pkstruct 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. pkstruct-0.1.0/.gitignore +0 -0
  2. pkstruct-0.1.0/CHANGELOG.md +23 -0
  3. pkstruct-0.1.0/LICENSE +21 -0
  4. pkstruct-0.1.0/MANIFEST.in +8 -0
  5. pkstruct-0.1.0/PKG-INFO +482 -0
  6. pkstruct-0.1.0/README.md +428 -0
  7. pkstruct-0.1.0/SECURITY.md +20 -0
  8. pkstruct-0.1.0/pkstruct_test_env/Scripts/py.test.exe +0 -0
  9. pkstruct-0.1.0/pkstruct_test_env/Scripts/pygmentize.exe +0 -0
  10. pkstruct-0.1.0/pkstruct_test_env/Scripts/pytest.exe +0 -0
  11. pkstruct-0.1.0/pkstruct_test_env/Scripts/python.exe +0 -0
  12. pkstruct-0.1.0/pkstruct_test_env/Scripts/pythonw.exe +0 -0
  13. pkstruct-0.1.0/pkstruct_test_env/pyvenv.cfg +3 -0
  14. pkstruct-0.1.0/pyproject.toml +73 -0
  15. pkstruct-0.1.0/requirements-dev.txt +9 -0
  16. pkstruct-0.1.0/src/pkstruct/__init__.py +167 -0
  17. pkstruct-0.1.0/src/pkstruct/graphs/__init__.py +127 -0
  18. pkstruct-0.1.0/src/pkstruct/graphs/connectivity.py +157 -0
  19. pkstruct-0.1.0/src/pkstruct/graphs/directed.py +95 -0
  20. pkstruct-0.1.0/src/pkstruct/graphs/exceptions.py +63 -0
  21. pkstruct-0.1.0/src/pkstruct/graphs/graph.py +262 -0
  22. pkstruct-0.1.0/src/pkstruct/graphs/mst.py +118 -0
  23. pkstruct-0.1.0/src/pkstruct/graphs/scc.py +138 -0
  24. pkstruct-0.1.0/src/pkstruct/graphs/shortest_path.py +250 -0
  25. pkstruct-0.1.0/src/pkstruct/graphs/tests/__init__.py +2 -0
  26. pkstruct-0.1.0/src/pkstruct/graphs/tests/test_graph.py +626 -0
  27. pkstruct-0.1.0/src/pkstruct/graphs/tests/test_graph_advanced.py +1402 -0
  28. pkstruct-0.1.0/src/pkstruct/graphs/topo_sort.py +108 -0
  29. pkstruct-0.1.0/src/pkstruct/graphs/traversal.py +175 -0
  30. pkstruct-0.1.0/src/pkstruct/graphs/visualization.py +90 -0
  31. pkstruct-0.1.0/src/pkstruct/graphs/weighted.py +37 -0
  32. pkstruct-0.1.0/src/pkstruct/linear/__init__.py +95 -0
  33. pkstruct-0.1.0/src/pkstruct/linear/deques/__init__.py +33 -0
  34. pkstruct-0.1.0/src/pkstruct/linear/deques/deque.py +194 -0
  35. pkstruct-0.1.0/src/pkstruct/linear/deques/linked_deque.py +198 -0
  36. pkstruct-0.1.0/src/pkstruct/linear/exceptions.py +26 -0
  37. pkstruct-0.1.0/src/pkstruct/linear/linked_lists/__init__.py +5 -0
  38. pkstruct-0.1.0/src/pkstruct/linear/linked_lists/_base.py +608 -0
  39. pkstruct-0.1.0/src/pkstruct/linear/linked_lists/circular_linked_list.py +230 -0
  40. pkstruct-0.1.0/src/pkstruct/linear/linked_lists/doubly_linked_list.py +151 -0
  41. pkstruct-0.1.0/src/pkstruct/linear/linked_lists/nodes.py +68 -0
  42. pkstruct-0.1.0/src/pkstruct/linear/linked_lists/singly_linked_list.py +136 -0
  43. pkstruct-0.1.0/src/pkstruct/linear/queues/__init__.py +44 -0
  44. pkstruct-0.1.0/src/pkstruct/linear/queues/circular_queue.py +258 -0
  45. pkstruct-0.1.0/src/pkstruct/linear/queues/linked_queue.py +186 -0
  46. pkstruct-0.1.0/src/pkstruct/linear/queues/priority_queue.py +202 -0
  47. pkstruct-0.1.0/src/pkstruct/linear/queues/queue.py +174 -0
  48. pkstruct-0.1.0/src/pkstruct/linear/stacks/__init__.py +38 -0
  49. pkstruct-0.1.0/src/pkstruct/linear/stacks/array_stack.py +165 -0
  50. pkstruct-0.1.0/src/pkstruct/linear/stacks/linked_stack.py +168 -0
  51. pkstruct-0.1.0/src/pkstruct/linear/stacks/stack.py +158 -0
  52. pkstruct-0.1.0/src/pkstruct/linear/tests/__init__.py +2 -0
  53. pkstruct-0.1.0/src/pkstruct/linear/tests/test_edge_cases.py +195 -0
  54. pkstruct-0.1.0/src/pkstruct/linear/tests/test_linked_list.py +673 -0
  55. pkstruct-0.1.0/src/pkstruct/linear/tests/test_visualization.py +92 -0
  56. pkstruct-0.1.0/src/pkstruct/linear/utils/__init__.py +18 -0
  57. pkstruct-0.1.0/src/pkstruct/linear/utils/benchmark.py +255 -0
  58. pkstruct-0.1.0/src/pkstruct/linear/utils/debug_tools.py +239 -0
  59. pkstruct-0.1.0/src/pkstruct/linear/utils/helpers.py +143 -0
  60. pkstruct-0.1.0/src/pkstruct/linear/utils/iterators.py +148 -0
  61. pkstruct-0.1.0/src/pkstruct/linear/visualization/__init__.py +0 -0
  62. pkstruct-0.1.0/src/pkstruct/linear/visualization/ascii_visualizer.py +114 -0
  63. pkstruct-0.1.0/src/pkstruct/linear/visualization/linked_list_visualizer.py +126 -0
  64. pkstruct-0.1.0/src/pkstruct/shared/__init__.py +67 -0
  65. pkstruct-0.1.0/src/pkstruct/shared/benchmarking/__init__.py +78 -0
  66. pkstruct-0.1.0/src/pkstruct/shared/debugging/__init__.py +69 -0
  67. pkstruct-0.1.0/src/pkstruct/shared/exceptions/__init__.py +59 -0
  68. pkstruct-0.1.0/src/pkstruct/shared/serializers/__init__.py +65 -0
  69. pkstruct-0.1.0/src/pkstruct/shared/threading/__init__.py +43 -0
  70. pkstruct-0.1.0/src/pkstruct/shared/validators/__init__.py +98 -0
  71. pkstruct-0.1.0/src/pkstruct/shared/visualization/__init__.py +21 -0
  72. pkstruct-0.1.0/src/pkstruct/trees/__init__.py +92 -0
  73. pkstruct-0.1.0/src/pkstruct/trees/avl.py +321 -0
  74. pkstruct-0.1.0/src/pkstruct/trees/balancing.py +253 -0
  75. pkstruct-0.1.0/src/pkstruct/trees/bplus.py +425 -0
  76. pkstruct-0.1.0/src/pkstruct/trees/bst.py +948 -0
  77. pkstruct-0.1.0/src/pkstruct/trees/btree.py +504 -0
  78. pkstruct-0.1.0/src/pkstruct/trees/exceptions.py +96 -0
  79. pkstruct-0.1.0/src/pkstruct/trees/fenwick_tree.py +312 -0
  80. pkstruct-0.1.0/src/pkstruct/trees/interval_tree.py +541 -0
  81. pkstruct-0.1.0/src/pkstruct/trees/node.py +356 -0
  82. pkstruct-0.1.0/src/pkstruct/trees/red_black.py +710 -0
  83. pkstruct-0.1.0/src/pkstruct/trees/segment_tree.py +398 -0
  84. pkstruct-0.1.0/src/pkstruct/trees/tests/__init__.py +2 -0
  85. pkstruct-0.1.0/src/pkstruct/trees/tests/test_avl.py +414 -0
  86. pkstruct-0.1.0/src/pkstruct/trees/tests/test_bplus.py +311 -0
  87. pkstruct-0.1.0/src/pkstruct/trees/tests/test_bst.py +553 -0
  88. pkstruct-0.1.0/src/pkstruct/trees/tests/test_btree.py +302 -0
  89. pkstruct-0.1.0/src/pkstruct/trees/tests/test_fenwick_tree.py +232 -0
  90. pkstruct-0.1.0/src/pkstruct/trees/tests/test_interval_tree.py +336 -0
  91. pkstruct-0.1.0/src/pkstruct/trees/tests/test_red_black.py +369 -0
  92. pkstruct-0.1.0/src/pkstruct/trees/tests/test_segment_tree.py +242 -0
  93. pkstruct-0.1.0/src/pkstruct/trees/traversal.py +456 -0
  94. pkstruct-0.1.0/src/pkstruct/trees/tree_helpers.py +366 -0
  95. pkstruct-0.1.0/src/pkstruct/trees/utils/__init__.py +15 -0
  96. pkstruct-0.1.0/src/pkstruct/trees/utils/complexity_helpers.py +231 -0
  97. pkstruct-0.1.0/src/pkstruct/trees/visualization/__init__.py +0 -0
  98. pkstruct-0.1.0/src/pkstruct/trees/visualization/ascii_renderer.py +220 -0
  99. pkstruct-0.1.0/src/pkstruct/trees/visualization/tree_printer.py +129 -0
  100. pkstruct-0.1.0/testing_final.py +1148 -0
Binary file
@@ -0,0 +1,23 @@
1
+ # Changelog
2
+
3
+ All notable changes to pkstruct will be documented in this file.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2026-06-01
9
+
10
+ ### Added
11
+ - `pkstruct.linear` module with `SinglyLinkedList`, `DoublyLinkedList`, `CircularLinkedList`
12
+ - Full CRUD operations: `insert`, `delete`, `get`, `replace`, `extend`, `clear`
13
+ - Algorithmic operations: `sort`, `merge`, `partition`, `reverse`, `rotate`, `swap`
14
+ - Interview problems: `detect_cycle`, `intersection_node`, `palindrome`, `reorder`, `segregate_even_odd`
15
+ - Serialization: `from_list`, `from_json`, `to_list`, `copy`
16
+ - ASCII visualization with `visualize()` and `debug()` introspection
17
+ - Thread-safe operations via `RLock`
18
+ - Custom exception hierarchy via `pkstruct.linear.exceptions`
19
+ - Shared subsystem (`pkstruct.shared`) for validators, serializers, threading, benchmarking
20
+ - Full pytest suite with edge cases, randomization, and threading tests
21
+ - Benchmark suite comparing against `list` and `collections.deque`
22
+ - Type annotations, mypy strict compliance
23
+ - PyPI-ready packaging with `hatchling`
pkstruct-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Prannavakhanth
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,8 @@
1
+ include README.md
2
+ include LICENSE
3
+ include CHANGELOG.md
4
+ include SECURITY.md
5
+ recursive-include src/pkstruct *.py *.pyi
6
+ global-exclude __pycache__
7
+ global-exclude *.py[co]
8
+ global-exclude .DS_Store
@@ -0,0 +1,482 @@
1
+ Metadata-Version: 2.4
2
+ Name: pkstruct
3
+ Version: 0.1.0
4
+ Summary: Industrial-grade data structures and algorithms toolkit for Python
5
+ Project-URL: Homepage, https://github.com/pkstruct/pkstruct
6
+ Project-URL: Repository, https://github.com/pkstruct/pkstruct
7
+ Project-URL: Documentation, https://pkstruct.readthedocs.io
8
+ Project-URL: Bug Tracker, https://github.com/pkstruct/pkstruct/issues
9
+ Author: pkstruct Contributors
10
+ License: MIT License
11
+
12
+ Copyright (c) 2026 Prannavakhanth
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in all
22
+ copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+ License-File: LICENSE
32
+ Keywords: algorithms,collections,data-structures,dsa,linked-list
33
+ Classifier: Development Status :: 4 - Beta
34
+ Classifier: Intended Audience :: Developers
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Programming Language :: Python :: 3.10
38
+ Classifier: Programming Language :: Python :: 3.11
39
+ Classifier: Programming Language :: Python :: 3.12
40
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
41
+ Classifier: Typing :: Typed
42
+ Requires-Python: >=3.10
43
+ Provides-Extra: dev
44
+ Requires-Dist: black>=23.11; extra == 'dev'
45
+ Requires-Dist: build>=1.0; extra == 'dev'
46
+ Requires-Dist: mypy>=1.7; extra == 'dev'
47
+ Requires-Dist: pytest-benchmark>=4.0; extra == 'dev'
48
+ Requires-Dist: pytest-cov>=4.1; extra == 'dev'
49
+ Requires-Dist: pytest-xdist>=3.3; extra == 'dev'
50
+ Requires-Dist: pytest>=7.4; extra == 'dev'
51
+ Requires-Dist: ruff>=0.1.6; extra == 'dev'
52
+ Requires-Dist: twine>=4.0; extra == 'dev'
53
+ Description-Content-Type: text/markdown
54
+
55
+ # pkstruct
56
+
57
+ **Industrial-grade data structures and algorithms for Python ≥ 3.10**
58
+
59
+ [![PyPI](https://img.shields.io/pypi/v/pkstruct)](https://pypi.org/project/pkstruct/)
60
+ [![Python](https://img.shields.io/pypi/pyversions/pkstruct)](https://pypi.org/project/pkstruct/)
61
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
62
+
63
+ ---
64
+
65
+ ## Installation
66
+
67
+ ```bash
68
+ pip install pkstruct
69
+ ```
70
+
71
+ ## Quick Start
72
+
73
+ ```python
74
+ from pkstruct.linear import SinglyLinkedList, DoublyLinkedList, CircularLinkedList
75
+
76
+ # Singly Linked List
77
+ sll = SinglyLinkedList.from_list([1, 2, 3, 4, 5])
78
+ sll.insert(99, position=2) # [1, 2, 99, 3, 4, 5]
79
+ sll.sort() # [1, 2, 3, 4, 5, 99]
80
+ print(sll.visualize())
81
+ # [1] -> [2] -> [3] -> [4] -> [5] -> [99] -> NULL
82
+
83
+ # Doubly Linked List
84
+ dll = DoublyLinkedList.from_list([10, 20, 30])
85
+ dll.reverse()
86
+ print(dll.visualize())
87
+ # None <- 30 <-> 20 <-> 10 -> None
88
+
89
+ # Circular Linked List
90
+ cll = CircularLinkedList.from_list(["a", "b", "c"])
91
+ cll.rotate(shift=1)
92
+ print(cll.visualize())
93
+ # c -> a -> b -> (back to head)
94
+ ```
95
+
96
+ ```python
97
+ from pkstruct.trees import BinarySearchTree, AVLTree, RedBlackTree, SegmentTree
98
+
99
+ # Binary Search Tree
100
+ bst = BinarySearchTree()
101
+ bst.insert(10)
102
+ bst.insert(5)
103
+ bst.insert(15)
104
+ list(bst) # [5, 10, 15]
105
+ 10 in bst # True
106
+
107
+ # AVL Tree (self-balancing)
108
+ avl = AVLTree.from_list([1, 2, 3, 4, 5])
109
+ avl.height() # 2 (logarithmic, not linear)
110
+
111
+ # Segment Tree with lazy propagation
112
+ st = SegmentTree([1, 2, 3, 4, 5], func="sum")
113
+ st.query(1, 3) # 9 (2 + 3 + 4)
114
+ st.update(2, 10) # point update
115
+ st.range_update(1, 3, 5) # range add
116
+ st.query(1, 3) # 24
117
+ ```
118
+
119
+ ```python
120
+ from pkstruct.graphs import Graph, DirectedGraph, bfs, dfs, dijkstra, kruskal
121
+
122
+ # Create a weighted graph
123
+ g = Graph()
124
+ g.add_edge("A", "B", weight=4.0)
125
+ g.add_edge("B", "C", weight=2.0)
126
+ g.add_edge("A", "C", weight=1.0)
127
+
128
+ # Traversal
129
+ bfs(g, "A") # ['A', 'B', 'C']
130
+
131
+ # Shortest paths
132
+ dist, _ = dijkstra(g, "A")
133
+ dist["C"] # 1.0
134
+
135
+ # Minimum spanning tree
136
+ kruskal(g) # [('A', 'C', 1.0), ('B', 'C', 2.0)]
137
+ ```
138
+
139
+ ## Modules
140
+
141
+ ### `pkstruct.linear`
142
+
143
+ | Data Structure | Description |
144
+ |---|---|
145
+ | `SinglyLinkedList` | Forward-only linked list with merge sort, cycle detection, palindrome check |
146
+ | `DoublyLinkedList` | Bidirectional linked list with backward traversal |
147
+ | `CircularLinkedList` | Circular linked list maintaining circular invariant |
148
+ | `ArrayStack` | LIFO stack backed by a dynamic array |
149
+ | `LinkedStack` | LIFO stack backed by `SinglyLinkedList` |
150
+ | `LinkedQueue` | FIFO queue backed by `SinglyLinkedList` |
151
+ | `CircularQueue` | Fixed-capacity FIFO queue backed by a ring buffer |
152
+ | `PriorityQueue` | Min-heap priority queue |
153
+ | `LinkedDeque` | Double-ended queue backed by `DoublyLinkedList` |
154
+
155
+ ### `pkstruct.trees`
156
+
157
+ | Data Structure | Description |
158
+ |---|---|
159
+ | `BinarySearchTree` | Unbalanced BST with full interview-utility API |
160
+ | `AVLTree` | Self-balancing AVL tree (extends BST) |
161
+ | `RedBlackTree` | Self-balancing red-black tree |
162
+ | `BTree` | Balanced multi-way search tree |
163
+ | `BPlusTree` | B+ Tree with leaf-linked chain for efficient range queries |
164
+ | `SegmentTree` | Segment tree with lazy propagation (sum/min/max/gcd/xor) |
165
+ | `FenwickTree` | Binary indexed tree for prefix-sum operations |
166
+ | `IntervalTree` | Augmented interval tree for overlap queries |
167
+
168
+ ### `pkstruct.graphs`
169
+
170
+ | Class / Function | Description |
171
+ |---|---|
172
+ | `Graph` | Adjacency-list graph (directed/undirected, weighted) |
173
+ | `DirectedGraph` | Directed graph with in-degree, out-degree, reverse |
174
+ | `WeightedGraph` | Convenience class for weighted undirected graphs |
175
+ | `bfs` / `dfs` | Breadth-first and depth-first search |
176
+ | `bfs_paths` / `dfs_paths` | Find all paths between two vertices |
177
+ | `dijkstra` | Shortest paths (non-negative weights) |
178
+ | `bellman_ford` | Shortest paths (negative weights allowed) |
179
+ | `floyd_warshall` | All-pairs shortest paths |
180
+ | `reconstruct_path` | Path reconstruction from Dijkstra / Bellman-Ford |
181
+ | `reconstruct_path_fw` | Path reconstruction from Floyd-Warshall |
182
+ | `kruskal` / `prim` | Minimum spanning tree |
183
+ | `connected_components` | Find all connected components |
184
+ | `is_connected` / `is_bipartite` | Connectivity checks |
185
+ | `has_cycle` / `has_cycle_directed` | Cycle detection |
186
+ | `topological_sort_kahn` / `topological_sort_dfs` | Topological sort |
187
+ | `kosaraju` / `tarjan` | Strongly connected components |
188
+ | `visualize` / `adjacency_matrix` | ASCII visualization |
189
+
190
+ **Exceptions:** `GraphError`, `VertexNotFoundError`, `EdgeNotFoundError`,
191
+ `InvalidGraphOperationError`, `NegativeCycleError`, `NoPathError`
192
+
193
+ ## Features
194
+
195
+ ### Linked Lists
196
+
197
+ | Feature | SLL | DLL | CLL |
198
+ |---|---|---|---|
199
+ | Insert / Delete | ✅ | ✅ | ✅ |
200
+ | Sort (merge sort) | ✅ | ✅ | ✅ |
201
+ | Reverse (partial) | ✅ | ✅ | ✅ |
202
+ | Rotate (sub-range) | ✅ | ✅ | ✅ |
203
+ | Swap elements | ✅ | ✅ | ✅ |
204
+ | Cycle detection | ✅ | ✅ | — |
205
+ | Palindrome check | ✅ | ✅ | — |
206
+ | Even-odd segregation | ✅ | ✅ | — |
207
+ | JSON serialization | ✅ | ✅ | ✅ |
208
+ | ASCII visualization | ✅ | ✅ | ✅ |
209
+ | Thread-safe (RLock) | ✅ | ✅ | ✅ |
210
+ | `__slots__` nodes | ✅ | ✅ | ✅ |
211
+
212
+ ## API Overview
213
+
214
+ ### Linear — Linked Lists
215
+
216
+ ```python
217
+ # Construction
218
+ ll = SinglyLinkedList() # empty
219
+ ll = SinglyLinkedList.from_list([1, 2, 3])
220
+ ll = SinglyLinkedList.from_json('{"items": [1, 2, 3]}')
221
+
222
+ # Insertion
223
+ ll.insert(99) # append at tail
224
+ ll.insert(99, position=0) # insert at head
225
+ ll.insert(99, before=50) # insert before value
226
+ ll.insert(99, after=50) # insert after value
227
+
228
+ # Deletion
229
+ ll.delete(position=2) # delete by index
230
+ ll.delete(value=42) # delete by value (first match)
231
+ ll.delete(rng=(1, 3)) # delete sub-range [1..3]
232
+ ll.clear() # remove all
233
+
234
+ # Access
235
+ ll.get(0) # by index
236
+ ll[0] # via __getitem__
237
+ ll.index(42) # find first occurrence
238
+ ll.count(42) # count occurrences
239
+
240
+ # Mutation
241
+ ll[0] = 99 # via __setitem__
242
+ ll.swap(0, 2) # swap two positions
243
+ ll.reverse() # full reverse
244
+ ll.reverse(start=1, end=3) # sub-range reverse
245
+ ll.rotate(shift=2) # rotate whole list right
246
+ ll.rotate(shift=2, start=1, end=4) # rotate sub-range
247
+ ll.sort() # ascending
248
+ ll.sort(reverse=True) # descending
249
+ ll.merge(other_list) # merge in-place
250
+
251
+ # Interview helpers
252
+ ll.palindrome() # palindrome check
253
+ ll.detect_cycle() # Floyd's algorithm
254
+ ll.segregate_even_odd() # reorder
255
+ ll.partition(5) # pivot partition
256
+
257
+ # Serialization
258
+ json_str = ll.to_json()
259
+ ll = SinglyLinkedList.from_json(json_str)
260
+
261
+ # Visualization
262
+ print(ll.visualize()) # ASCII art
263
+ info = ll.debug() # diagnostic dict
264
+ ```
265
+
266
+ ### Linear — Stacks, Queues, Deques
267
+
268
+ ```python
269
+ from pkstruct.linear import ArrayStack, LinkedStack, LinkedQueue, CircularQueue, PriorityQueue, LinkedDeque
270
+
271
+ # Stack
272
+ s = LinkedStack([1, 2, 3])
273
+ s.push(4)
274
+ s.pop() # 4
275
+ s.peek() # 3
276
+ len(s) # 3
277
+
278
+ # Queue
279
+ q = LinkedQueue([1, 2, 3])
280
+ q.enqueue(4)
281
+ q.dequeue() # 1
282
+ q.peek() # 2
283
+
284
+ # Circular Queue (fixed capacity)
285
+ cq = CircularQueue(capacity=3)
286
+ cq.enqueue(1)
287
+ cq.enqueue(2)
288
+ cq.enqueue(3)
289
+ cq.is_full() # True
290
+ cq.dequeue() # 1
291
+
292
+ # Priority Queue (min-heap)
293
+ pq = PriorityQueue()
294
+ pq.push("task1", priority=3)
295
+ pq.push("task2", priority=1)
296
+ pq.pop() # "task2"
297
+
298
+ # Deque
299
+ d = LinkedDeque([1, 2, 3])
300
+ d.append(4)
301
+ d.appendleft(0)
302
+ d.pop() # 4
303
+ d.popleft() # 0
304
+ ```
305
+
306
+ ### Trees
307
+
308
+ ```python
309
+ # Binary Search Tree
310
+ bst = BinarySearchTree()
311
+ bst.insert(10, value="ten")
312
+ bst.insert(5, value="five")
313
+ bst[5] # "five"
314
+ bst.search(10) # ("ten", Node)
315
+ bst.delete(5)
316
+ len(bst) # 1
317
+
318
+ # Traversals
319
+ list(bst.inorder()) # [5, 10, 15]
320
+ list(bst.preorder()) # [10, 5, 15]
321
+ list(bst.postorder()) # [5, 15, 10]
322
+ list(bst.level_order()) # [10, 5, 15]
323
+ list(bst.zigzag()) # [10, 15, 5]
324
+
325
+ # Utilities
326
+ bst.find_lca(5, 15) # 10 (lowest common ancestor)
327
+ bst.kth_smallest(1) # 5
328
+ bst.kth_largest(1) # 15
329
+ bst.range_query(5, 15) # [5, 10, 15]
330
+ bst.path_sum(20) # True
331
+ bst.root_to_leaf_paths() # [[10, 5], [10, 15]]
332
+ bst.diameter() # 2
333
+ bst.is_balanced() # True
334
+ bst.invert()
335
+
336
+ # AVL Tree (self-balancing)
337
+ avl = AVLTree()
338
+ avl.insert(3)
339
+ avl.insert(2)
340
+ avl.insert(1) # triggers LL rotation
341
+ avl.is_avl_valid() # True
342
+ avl.height() # 1
343
+
344
+ # Red-Black Tree
345
+ rbt = RedBlackTree()
346
+ rbt.insert(10)
347
+ rbt.insert(20)
348
+ rbt.insert(30) # triggers recoloring / rotation
349
+ rbt.validate() # checks red-black invariants
350
+
351
+ # B-Tree & B+ Tree
352
+ bt = BTree(order=4)
353
+ bt.insert(10)
354
+ bt.insert(20)
355
+ bt.insert(5)
356
+ bt.search(10) # True
357
+
358
+ bpt = BPlusTree(order=4)
359
+ bpt.insert(10)
360
+ bpt.insert(20)
361
+ bpt.range_query(5, 15) # efficient via leaf chain
362
+
363
+ # Segment Tree
364
+ st = SegmentTree([1, 2, 3, 4, 5], func="sum")
365
+ st.query(0, 2) # 6
366
+ st.range_update(0, 2, 3) # range add
367
+ st.query(0, 2) # 15
368
+ st.rebuild([5, 6, 7, 8])
369
+
370
+ # Fenwick Tree
371
+ ft = FenwickTree(5)
372
+ ft.add(1, 10)
373
+ ft.add(2, 20)
374
+ ft.prefix_sum(2) # 30
375
+ ft.range_sum(1, 2) # 30
376
+
377
+ # Interval Tree
378
+ it = IntervalTree()
379
+ it.insert(5, 10, "A")
380
+ it.insert(15, 20, "B")
381
+ it.overlap(8, 12) # [(5, 10, "A")]
382
+ it.overlap_all(8, 12) # all overlapping intervals
383
+ ```
384
+
385
+ ### Graphs
386
+
387
+ ```python
388
+ from pkstruct.graphs import Graph, DirectedGraph, WeightedGraph
389
+ from pkstruct.graphs import bfs, dfs, dijkstra, bellman_ford, floyd_warshall
390
+ from pkstruct.graphs import reconstruct_path, kruskal, kosaraju
391
+
392
+ # Create a graph
393
+ g = Graph()
394
+ g.add_edge("A", "B", weight=4.0)
395
+ g.add_edge("B", "C", weight=2.0)
396
+ g.add_edge("A", "C", weight=1.0)
397
+
398
+ # Traversal
399
+ bfs(g, "A") # ['A', 'B', 'C']
400
+ dfs(g, "A") # ['A', 'B', 'C']
401
+
402
+ # Shortest path (Dijkstra)
403
+ dist, pred = dijkstra(g, "A")
404
+ dist["C"] # 1.0
405
+ reconstruct_path(pred, "A", "C") # ['A', 'C']
406
+
407
+ # Minimum spanning tree
408
+ mst = kruskal(g) # [('A', 'C', 1.0), ('B', 'C', 2.0)]
409
+
410
+ # Bellman-Ford (supports negative weights)
411
+ dist, pred = bellman_ford(g, "A")
412
+ dist["C"] # 1.0
413
+
414
+ # All-pairs shortest paths
415
+ dist_all, _ = floyd_warshall(g)
416
+ dist_all["A"]["C"] # 1.0
417
+
418
+ # Directed graph
419
+ dg = DirectedGraph()
420
+ dg.add_edge("A", "B")
421
+ dg.add_edge("B", "C")
422
+ dg.add_edge("A", "C")
423
+ topological_sort_kahn(dg) # ['A', 'B', 'C']
424
+
425
+ # Strongly connected components
426
+ dg.add_edge("C", "A")
427
+ kosaraju(dg) # [['A', 'B', 'C']] (one SCC)
428
+
429
+ # Weighted graph
430
+ wg = WeightedGraph()
431
+ wg.add_edge("X", "Y", 3.5)
432
+ wg.add_edge("Y", "Z", 1.5)
433
+ wg.get_weight("X", "Y") # 3.5
434
+
435
+ # Visualization
436
+ from pkstruct.graphs import visualize
437
+ print(visualize(g))
438
+ # Graph (directed=False, vertices=3, edges=3)
439
+ # 'A' -> 'B' [4.0] <-> 'C' [1.0]
440
+ # 'B' -> 'A' [4.0] <-> 'C' [2.0]
441
+ # 'C' -> 'A' [1.0] <-> 'B' [2.0]
442
+
443
+ # Exception handling
444
+ from pkstruct.graphs.exceptions import VertexNotFoundError, NegativeCycleError
445
+
446
+ try:
447
+ g.get_weight("X", "Y")
448
+ except VertexNotFoundError:
449
+ print("Vertex does not exist")
450
+ ```
451
+
452
+ ## String Protocol
453
+
454
+ ```python
455
+ sll = SinglyLinkedList.from_list([1, 2, 3])
456
+ list(sll) # [1, 2, 3]
457
+ len(sll) # 3
458
+ bool(sll) # True (False when empty)
459
+ repr(sll) # SinglyLinkedList([1, 2, 3])
460
+ str(sll) # SinglyLinkedList([1, 2, 3])
461
+ 42 in sll # True / False
462
+ sll == other # value equality
463
+ ```
464
+
465
+ ## Development
466
+
467
+ ```bash
468
+ pip install -e ".[dev]"
469
+ pytest src/pkstruct/linear/tests src/pkstruct/trees/tests src/pkstruct/graphs/tests -v
470
+ ```
471
+
472
+ ## Publishing
473
+
474
+ ```bash
475
+ python -m build
476
+ twine check dist/*
477
+ twine upload dist/*
478
+ ```
479
+
480
+ ## License
481
+
482
+ MIT © pkstruct Contributors