data-structure-typed 2.5.0 → 2.5.2

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 (246) hide show
  1. package/.vitepress/cache/deps_temp_51f5f1b0/chunk-7OIKW5WK.js +12984 -0
  2. package/.vitepress/cache/deps_temp_51f5f1b0/package.json +3 -0
  3. package/.vitepress/cache/deps_temp_51f5f1b0/vitepress___@vue_devtools-api.js +4505 -0
  4. package/.vitepress/cache/deps_temp_51f5f1b0/vitepress___@vueuse_core.js +9731 -0
  5. package/.vitepress/cache/deps_temp_51f5f1b0/vue.js +347 -0
  6. package/CHANGELOG.md +5 -1
  7. package/README.md +124 -29
  8. package/dist/cjs/binary-tree.cjs +26282 -0
  9. package/dist/cjs/graph.cjs +5422 -0
  10. package/dist/cjs/hash.cjs +1310 -0
  11. package/dist/cjs/heap.cjs +1602 -0
  12. package/dist/cjs/index.cjs +31257 -14673
  13. package/dist/cjs/linked-list.cjs +4576 -0
  14. package/dist/cjs/matrix.cjs +1080 -0
  15. package/dist/cjs/priority-queue.cjs +1376 -0
  16. package/dist/cjs/queue.cjs +4264 -0
  17. package/dist/cjs/stack.cjs +907 -0
  18. package/dist/cjs/trie.cjs +1223 -0
  19. package/dist/cjs-legacy/binary-tree.cjs +26319 -0
  20. package/dist/cjs-legacy/graph.cjs +5420 -0
  21. package/dist/cjs-legacy/hash.cjs +1310 -0
  22. package/dist/cjs-legacy/heap.cjs +1599 -0
  23. package/dist/cjs-legacy/index.cjs +31268 -14679
  24. package/dist/cjs-legacy/linked-list.cjs +4582 -0
  25. package/dist/cjs-legacy/matrix.cjs +1083 -0
  26. package/dist/cjs-legacy/priority-queue.cjs +1374 -0
  27. package/dist/cjs-legacy/queue.cjs +4262 -0
  28. package/dist/cjs-legacy/stack.cjs +907 -0
  29. package/dist/cjs-legacy/trie.cjs +1222 -0
  30. package/dist/esm/binary-tree.mjs +26267 -0
  31. package/dist/esm/graph.mjs +5409 -0
  32. package/dist/esm/hash.mjs +1307 -0
  33. package/dist/esm/heap.mjs +1596 -0
  34. package/dist/esm/index.mjs +31254 -14674
  35. package/dist/esm/linked-list.mjs +4569 -0
  36. package/dist/esm/matrix.mjs +1076 -0
  37. package/dist/esm/priority-queue.mjs +1372 -0
  38. package/dist/esm/queue.mjs +4260 -0
  39. package/dist/esm/stack.mjs +905 -0
  40. package/dist/esm/trie.mjs +1220 -0
  41. package/dist/esm-legacy/binary-tree.mjs +26304 -0
  42. package/dist/esm-legacy/graph.mjs +5407 -0
  43. package/dist/esm-legacy/hash.mjs +1307 -0
  44. package/dist/esm-legacy/heap.mjs +1593 -0
  45. package/dist/esm-legacy/index.mjs +31265 -14680
  46. package/dist/esm-legacy/linked-list.mjs +4575 -0
  47. package/dist/esm-legacy/matrix.mjs +1079 -0
  48. package/dist/esm-legacy/priority-queue.mjs +1370 -0
  49. package/dist/esm-legacy/queue.mjs +4258 -0
  50. package/dist/esm-legacy/stack.mjs +905 -0
  51. package/dist/esm-legacy/trie.mjs +1219 -0
  52. package/dist/types/common/error.d.ts +9 -0
  53. package/dist/types/common/index.d.ts +1 -1
  54. package/dist/types/data-structures/base/index.d.ts +1 -0
  55. package/dist/types/data-structures/base/iterable-entry-base.d.ts +8 -8
  56. package/dist/types/data-structures/base/linear-base.d.ts +3 -3
  57. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +288 -0
  58. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +336 -0
  59. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +618 -18
  60. package/dist/types/data-structures/binary-tree/bst.d.ts +676 -1
  61. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +456 -0
  62. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +144 -1
  63. package/dist/types/data-structures/binary-tree/tree-map.d.ts +3307 -399
  64. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +3285 -360
  65. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +2674 -325
  66. package/dist/types/data-structures/binary-tree/tree-set.d.ts +3072 -287
  67. package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -4
  68. package/dist/types/data-structures/graph/directed-graph.d.ts +240 -0
  69. package/dist/types/data-structures/graph/undirected-graph.d.ts +216 -0
  70. package/dist/types/data-structures/hash/hash-map.d.ts +274 -10
  71. package/dist/types/data-structures/heap/heap.d.ts +336 -0
  72. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +411 -3
  73. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +363 -3
  74. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +434 -2
  75. package/dist/types/data-structures/matrix/matrix.d.ts +192 -0
  76. package/dist/types/data-structures/queue/deque.d.ts +364 -4
  77. package/dist/types/data-structures/queue/queue.d.ts +288 -0
  78. package/dist/types/data-structures/stack/stack.d.ts +240 -0
  79. package/dist/types/data-structures/trie/trie.d.ts +292 -4
  80. package/dist/types/interfaces/graph.d.ts +1 -1
  81. package/dist/types/types/common.d.ts +2 -2
  82. package/dist/types/types/data-structures/binary-tree/bst.d.ts +1 -0
  83. package/dist/types/types/data-structures/binary-tree/tree-map.d.ts +5 -0
  84. package/dist/types/types/data-structures/binary-tree/tree-multi-set.d.ts +4 -0
  85. package/dist/types/types/data-structures/binary-tree/tree-set.d.ts +4 -0
  86. package/dist/types/types/data-structures/heap/heap.d.ts +1 -0
  87. package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +1 -0
  88. package/dist/types/types/utils/validate-type.d.ts +4 -4
  89. package/dist/umd/data-structure-typed.js +31196 -14608
  90. package/dist/umd/data-structure-typed.min.js +11 -5
  91. package/docs-site-docusaurus/README.md +41 -0
  92. package/docs-site-docusaurus/docs/api/README.md +52 -0
  93. package/docs-site-docusaurus/docs/api/classes/AVLTree.md +6644 -0
  94. package/docs-site-docusaurus/docs/api/classes/AVLTreeNode.md +282 -0
  95. package/docs-site-docusaurus/docs/api/classes/AbstractGraph.md +2266 -0
  96. package/docs-site-docusaurus/docs/api/classes/BST.md +6293 -0
  97. package/docs-site-docusaurus/docs/api/classes/BSTNode.md +333 -0
  98. package/docs-site-docusaurus/docs/api/classes/BinaryIndexedTree.md +455 -0
  99. package/docs-site-docusaurus/docs/api/classes/BinaryTree.md +4647 -0
  100. package/docs-site-docusaurus/docs/api/classes/BinaryTreeNode.md +331 -0
  101. package/docs-site-docusaurus/docs/api/classes/Deque.md +2767 -0
  102. package/docs-site-docusaurus/docs/api/classes/DirectedGraph.md +2999 -0
  103. package/docs-site-docusaurus/docs/api/classes/DoublyLinkedList.md +2685 -0
  104. package/docs-site-docusaurus/docs/api/classes/DoublyLinkedListNode.md +221 -0
  105. package/docs-site-docusaurus/docs/api/classes/FibonacciHeap.md +253 -0
  106. package/docs-site-docusaurus/docs/api/classes/FibonacciHeapNode.md +21 -0
  107. package/docs-site-docusaurus/docs/api/classes/HashMap.md +1333 -0
  108. package/docs-site-docusaurus/docs/api/classes/Heap.md +1881 -0
  109. package/docs-site-docusaurus/docs/api/classes/IterableElementBase.md +800 -0
  110. package/docs-site-docusaurus/docs/api/classes/IterableEntryBase.md +644 -0
  111. package/docs-site-docusaurus/docs/api/classes/LinearBase.md +1632 -0
  112. package/docs-site-docusaurus/docs/api/classes/LinearLinkedBase.md +1853 -0
  113. package/docs-site-docusaurus/docs/api/classes/LinkedHashMap.md +1108 -0
  114. package/docs-site-docusaurus/docs/api/classes/LinkedListNode.md +156 -0
  115. package/docs-site-docusaurus/docs/api/classes/LinkedListQueue.md +2824 -0
  116. package/docs-site-docusaurus/docs/api/classes/MapGraph.md +2929 -0
  117. package/docs-site-docusaurus/docs/api/classes/Matrix.md +1026 -0
  118. package/docs-site-docusaurus/docs/api/classes/MaxHeap.md +1866 -0
  119. package/docs-site-docusaurus/docs/api/classes/MaxPriorityQueue.md +1883 -0
  120. package/docs-site-docusaurus/docs/api/classes/MinHeap.md +1879 -0
  121. package/docs-site-docusaurus/docs/api/classes/MinPriorityQueue.md +1882 -0
  122. package/docs-site-docusaurus/docs/api/classes/Navigator.md +109 -0
  123. package/docs-site-docusaurus/docs/api/classes/PriorityQueue.md +1839 -0
  124. package/docs-site-docusaurus/docs/api/classes/Queue.md +2244 -0
  125. package/docs-site-docusaurus/docs/api/classes/RedBlackTree.md +6888 -0
  126. package/docs-site-docusaurus/docs/api/classes/SegmentTree.md +372 -0
  127. package/docs-site-docusaurus/docs/api/classes/SinglyLinkedList.md +2897 -0
  128. package/docs-site-docusaurus/docs/api/classes/SinglyLinkedListNode.md +169 -0
  129. package/docs-site-docusaurus/docs/api/classes/SkipList.md +1229 -0
  130. package/docs-site-docusaurus/docs/api/classes/Stack.md +1573 -0
  131. package/docs-site-docusaurus/docs/api/classes/TreeMap.md +1389 -0
  132. package/docs-site-docusaurus/docs/api/classes/TreeMultiMap.md +1591 -0
  133. package/docs-site-docusaurus/docs/api/classes/TreeSet.md +1246 -0
  134. package/docs-site-docusaurus/docs/api/classes/Trie.md +1708 -0
  135. package/docs-site-docusaurus/docs/api/classes/TrieNode.md +199 -0
  136. package/docs-site-docusaurus/docs/api/classes/UndirectedGraph.md +2979 -0
  137. package/docs-site-docusaurus/docs/guide/_category_.json +6 -0
  138. package/docs-site-docusaurus/docs/guide/architecture.md +615 -0
  139. package/docs-site-docusaurus/docs/guide/concepts.md +451 -0
  140. package/docs-site-docusaurus/docs/guide/faq.md +180 -0
  141. package/docs-site-docusaurus/docs/guide/guides.md +597 -0
  142. package/docs-site-docusaurus/docs/guide/installation.md +62 -0
  143. package/docs-site-docusaurus/docs/guide/integrations.md +825 -0
  144. package/docs-site-docusaurus/docs/guide/overview.md +645 -0
  145. package/docs-site-docusaurus/docs/guide/performance.md +835 -0
  146. package/docs-site-docusaurus/docs/guide/quick-start.md +104 -0
  147. package/docs-site-docusaurus/docs/guide/use-cases/_category_.json +6 -0
  148. package/docs-site-docusaurus/docs/guide/use-cases/array-sort-alternative.md +158 -0
  149. package/docs-site-docusaurus/docs/guide/use-cases/heap-vs-sorting.md +92 -0
  150. package/docs-site-docusaurus/docs/guide/use-cases/map-vs-treemap.md +151 -0
  151. package/docs-site-docusaurus/docs/guide/use-cases/priority-queue-typescript.md +113 -0
  152. package/docs-site-docusaurus/docs/guide/use-cases/treemap-javascript.md +151 -0
  153. package/docs-site-docusaurus/docusaurus.config.ts +159 -0
  154. package/docs-site-docusaurus/fix-mdx-generics.mjs +75 -0
  155. package/docs-site-docusaurus/package-lock.json +18667 -0
  156. package/docs-site-docusaurus/package.json +50 -0
  157. package/docs-site-docusaurus/prefix-class-to-methods.mjs +48 -0
  158. package/docs-site-docusaurus/sidebars.ts +23 -0
  159. package/docs-site-docusaurus/sort-protected.mjs +87 -0
  160. package/docs-site-docusaurus/src/css/custom.css +96 -0
  161. package/docs-site-docusaurus/src/pages/index.module.css +13 -0
  162. package/docs-site-docusaurus/src/pages/index.tsx +120 -0
  163. package/docs-site-docusaurus/src/pages/markdown-page.md +7 -0
  164. package/docs-site-docusaurus/src/theme/TOCItems/index.tsx +34 -0
  165. package/docs-site-docusaurus/static/.nojekyll +0 -0
  166. package/docs-site-docusaurus/static/img/docusaurus-social-card.jpg +0 -0
  167. package/docs-site-docusaurus/static/img/docusaurus.png +0 -0
  168. package/docs-site-docusaurus/static/img/favicon.ico +0 -0
  169. package/docs-site-docusaurus/static/img/favicon.png +0 -0
  170. package/docs-site-docusaurus/static/img/logo-180.png +0 -0
  171. package/docs-site-docusaurus/static/img/logo.jpg +0 -0
  172. package/docs-site-docusaurus/static/img/logo.png +0 -0
  173. package/docs-site-docusaurus/static/img/logo.svg +1 -0
  174. package/docs-site-docusaurus/static/img/og-image.png +0 -0
  175. package/docs-site-docusaurus/static/img/undraw_docusaurus_mountain.svg +171 -0
  176. package/docs-site-docusaurus/static/img/undraw_docusaurus_react.svg +170 -0
  177. package/docs-site-docusaurus/static/img/undraw_docusaurus_tree.svg +40 -0
  178. package/docs-site-docusaurus/static/llms.txt +37 -0
  179. package/docs-site-docusaurus/static/robots.txt +4 -0
  180. package/docs-site-docusaurus/typedoc.json +23 -0
  181. package/llms.txt +37 -0
  182. package/package.json +159 -55
  183. package/src/common/error.ts +19 -1
  184. package/src/common/index.ts +1 -1
  185. package/src/data-structures/base/index.ts +1 -0
  186. package/src/data-structures/base/iterable-element-base.ts +3 -2
  187. package/src/data-structures/base/iterable-entry-base.ts +8 -8
  188. package/src/data-structures/base/linear-base.ts +3 -3
  189. package/src/data-structures/binary-tree/avl-tree.ts +287 -0
  190. package/src/data-structures/binary-tree/binary-indexed-tree.ts +327 -5
  191. package/src/data-structures/binary-tree/binary-tree.ts +581 -6
  192. package/src/data-structures/binary-tree/bst.ts +922 -7
  193. package/src/data-structures/binary-tree/red-black-tree.ts +453 -0
  194. package/src/data-structures/binary-tree/segment-tree.ts +139 -2
  195. package/src/data-structures/binary-tree/tree-map.ts +3300 -495
  196. package/src/data-structures/binary-tree/tree-multi-map.ts +3384 -563
  197. package/src/data-structures/binary-tree/tree-multi-set.ts +2757 -493
  198. package/src/data-structures/binary-tree/tree-set.ts +3122 -440
  199. package/src/data-structures/graph/abstract-graph.ts +6 -6
  200. package/src/data-structures/graph/directed-graph.ts +230 -0
  201. package/src/data-structures/graph/undirected-graph.ts +207 -0
  202. package/src/data-structures/hash/hash-map.ts +270 -19
  203. package/src/data-structures/heap/heap.ts +326 -4
  204. package/src/data-structures/heap/max-heap.ts +2 -2
  205. package/src/data-structures/linked-list/doubly-linked-list.ts +394 -3
  206. package/src/data-structures/linked-list/singly-linked-list.ts +348 -3
  207. package/src/data-structures/linked-list/skip-linked-list.ts +421 -7
  208. package/src/data-structures/matrix/matrix.ts +194 -10
  209. package/src/data-structures/priority-queue/max-priority-queue.ts +2 -2
  210. package/src/data-structures/queue/deque.ts +350 -5
  211. package/src/data-structures/queue/queue.ts +276 -0
  212. package/src/data-structures/stack/stack.ts +230 -0
  213. package/src/data-structures/trie/trie.ts +283 -7
  214. package/src/interfaces/graph.ts +1 -1
  215. package/src/types/common.ts +2 -2
  216. package/src/types/data-structures/binary-tree/bst.ts +1 -0
  217. package/src/types/data-structures/binary-tree/tree-map.ts +6 -0
  218. package/src/types/data-structures/binary-tree/tree-multi-set.ts +5 -0
  219. package/src/types/data-structures/binary-tree/tree-set.ts +5 -0
  220. package/src/types/data-structures/heap/heap.ts +1 -0
  221. package/src/types/data-structures/priority-queue/priority-queue.ts +1 -0
  222. package/src/types/utils/validate-type.ts +4 -4
  223. package/vercel.json +6 -0
  224. package/dist/leetcode/avl-tree-counter.mjs +0 -2957
  225. package/dist/leetcode/avl-tree-multi-map.mjs +0 -2889
  226. package/dist/leetcode/avl-tree.mjs +0 -2720
  227. package/dist/leetcode/binary-tree.mjs +0 -1594
  228. package/dist/leetcode/bst.mjs +0 -2398
  229. package/dist/leetcode/deque.mjs +0 -683
  230. package/dist/leetcode/directed-graph.mjs +0 -1733
  231. package/dist/leetcode/doubly-linked-list.mjs +0 -709
  232. package/dist/leetcode/hash-map.mjs +0 -493
  233. package/dist/leetcode/heap.mjs +0 -542
  234. package/dist/leetcode/max-heap.mjs +0 -375
  235. package/dist/leetcode/max-priority-queue.mjs +0 -383
  236. package/dist/leetcode/min-heap.mjs +0 -363
  237. package/dist/leetcode/min-priority-queue.mjs +0 -371
  238. package/dist/leetcode/priority-queue.mjs +0 -363
  239. package/dist/leetcode/queue.mjs +0 -943
  240. package/dist/leetcode/red-black-tree.mjs +0 -2765
  241. package/dist/leetcode/singly-linked-list.mjs +0 -754
  242. package/dist/leetcode/stack.mjs +0 -217
  243. package/dist/leetcode/tree-counter.mjs +0 -3039
  244. package/dist/leetcode/tree-multi-map.mjs +0 -2913
  245. package/dist/leetcode/trie.mjs +0 -413
  246. package/dist/leetcode/undirected-graph.mjs +0 -1650
@@ -0,0 +1,4262 @@
1
+ 'use strict';
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
+
8
+ // src/common/error.ts
9
+ function raise(ErrorClass, message) {
10
+ throw new ErrorClass(message);
11
+ }
12
+ __name(raise, "raise");
13
+
14
+ // src/data-structures/base/iterable-element-base.ts
15
+ var _IterableElementBase = class _IterableElementBase {
16
+ /**
17
+ * Create a new iterable base.
18
+ *
19
+ * @param options Optional behavior overrides. When provided, a `toElementFn`
20
+ * is used to convert a raw element (`R`) into a public element (`E`).
21
+ *
22
+ * @remarks
23
+ * Time O(1), Space O(1).
24
+ */
25
+ constructor(options) {
26
+ /**
27
+ * The converter used to transform a raw element (`R`) into a public element (`E`).
28
+ *
29
+ * @remarks
30
+ * Time O(1), Space O(1).
31
+ */
32
+ __publicField(this, "_toElementFn");
33
+ if (options) {
34
+ const { toElementFn } = options;
35
+ if (typeof toElementFn === "function") this._toElementFn = toElementFn;
36
+ else if (toElementFn) raise(TypeError, "toElementFn must be a function type");
37
+ }
38
+ }
39
+ /**
40
+ * Exposes the current `toElementFn`, if configured.
41
+ *
42
+ * @returns The converter function or `undefined` when not set.
43
+ * @remarks
44
+ * Time O(1), Space O(1).
45
+ */
46
+ get toElementFn() {
47
+ return this._toElementFn;
48
+ }
49
+ /**
50
+ * Returns an iterator over the structure's elements.
51
+ *
52
+ * @param args Optional iterator arguments forwarded to the internal iterator.
53
+ * @returns An `IterableIterator<E>` that yields the elements in traversal order.
54
+ *
55
+ * @remarks
56
+ * Producing the iterator is O(1); consuming the entire iterator is Time O(n) with O(1) extra space.
57
+ */
58
+ *[Symbol.iterator](...args) {
59
+ yield* this._getIterator(...args);
60
+ }
61
+ /**
62
+ * Returns an iterator over the values (alias of the default iterator).
63
+ *
64
+ * @returns An `IterableIterator<E>` over all elements.
65
+ * @remarks
66
+ * Creating the iterator is O(1); full iteration is Time O(n), Space O(1).
67
+ */
68
+ *values() {
69
+ for (const item of this) yield item;
70
+ }
71
+ /**
72
+ * Tests whether all elements satisfy the predicate.
73
+ *
74
+ * @template TReturn
75
+ * @param predicate Function invoked for each element with signature `(value, index, self)`.
76
+ * @param thisArg Optional `this` binding for the predicate.
77
+ * @returns `true` if every element passes; otherwise `false`.
78
+ *
79
+ * @remarks
80
+ * Time O(n) in the worst case; may exit early when the first failure is found. Space O(1).
81
+ */
82
+ every(predicate, thisArg) {
83
+ let index = 0;
84
+ for (const item of this) {
85
+ if (thisArg === void 0) {
86
+ if (!predicate(item, index++, this)) return false;
87
+ } else {
88
+ const fn = predicate;
89
+ if (!fn.call(thisArg, item, index++, this)) return false;
90
+ }
91
+ }
92
+ return true;
93
+ }
94
+ /**
95
+ * Tests whether at least one element satisfies the predicate.
96
+ *
97
+ * @param predicate Function invoked for each element with signature `(value, index, self)`.
98
+ * @param thisArg Optional `this` binding for the predicate.
99
+ * @returns `true` if any element passes; otherwise `false`.
100
+ *
101
+ * @remarks
102
+ * Time O(n) in the worst case; may exit early on first success. Space O(1).
103
+ */
104
+ some(predicate, thisArg) {
105
+ let index = 0;
106
+ for (const item of this) {
107
+ if (thisArg === void 0) {
108
+ if (predicate(item, index++, this)) return true;
109
+ } else {
110
+ const fn = predicate;
111
+ if (fn.call(thisArg, item, index++, this)) return true;
112
+ }
113
+ }
114
+ return false;
115
+ }
116
+ /**
117
+ * Invokes a callback for each element in iteration order.
118
+ *
119
+ * @param callbackfn Function invoked per element with signature `(value, index, self)`.
120
+ * @param thisArg Optional `this` binding for the callback.
121
+ * @returns `void`.
122
+ *
123
+ * @remarks
124
+ * Time O(n), Space O(1).
125
+ */
126
+ forEach(callbackfn, thisArg) {
127
+ let index = 0;
128
+ for (const item of this) {
129
+ if (thisArg === void 0) {
130
+ callbackfn(item, index++, this);
131
+ } else {
132
+ const fn = callbackfn;
133
+ fn.call(thisArg, item, index++, this);
134
+ }
135
+ }
136
+ }
137
+ // Implementation signature
138
+ find(predicate, thisArg) {
139
+ let index = 0;
140
+ for (const item of this) {
141
+ if (thisArg === void 0) {
142
+ if (predicate(item, index++, this)) return item;
143
+ } else {
144
+ const fn = predicate;
145
+ if (fn.call(thisArg, item, index++, this)) return item;
146
+ }
147
+ }
148
+ return;
149
+ }
150
+ /**
151
+ * Checks whether a strictly-equal element exists in the structure.
152
+ *
153
+ * @param element The element to test with `===` equality.
154
+ * @returns `true` if an equal element is found; otherwise `false`.
155
+ *
156
+ * @remarks
157
+ * Time O(n) in the worst case. Space O(1).
158
+ */
159
+ has(element) {
160
+ for (const ele of this) if (ele === element) return true;
161
+ return false;
162
+ }
163
+ /**
164
+ * Reduces all elements to a single accumulated value.
165
+ *
166
+ * @overload
167
+ * @param callbackfn Reducer of signature `(acc, value, index, self) => nextAcc`. The first element is used as the initial accumulator.
168
+ * @returns The final accumulated value typed as `E`.
169
+ *
170
+ * @overload
171
+ * @param callbackfn Reducer of signature `(acc, value, index, self) => nextAcc`.
172
+ * @param initialValue The initial accumulator value of type `E`.
173
+ * @returns The final accumulated value typed as `E`.
174
+ *
175
+ * @overload
176
+ * @template U The accumulator type when it differs from `E`.
177
+ * @param callbackfn Reducer of signature `(acc: U, value, index, self) => U`.
178
+ * @param initialValue The initial accumulator value of type `U`.
179
+ * @returns The final accumulated value typed as `U`.
180
+ *
181
+ * @remarks
182
+ * Time O(n), Space O(1). Throws if called on an empty structure without `initialValue`.
183
+ */
184
+ reduce(callbackfn, initialValue) {
185
+ let index = 0;
186
+ const iter = this[Symbol.iterator]();
187
+ let acc;
188
+ if (arguments.length >= 2) {
189
+ acc = initialValue;
190
+ } else {
191
+ const first = iter.next();
192
+ if (first.done) raise(TypeError, "Reduce of empty structure with no initial value");
193
+ acc = first.value;
194
+ index = 1;
195
+ }
196
+ for (const value of iter) {
197
+ acc = callbackfn(acc, value, index++, this);
198
+ }
199
+ return acc;
200
+ }
201
+ /**
202
+ * Materializes the elements into a new array.
203
+ *
204
+ * @returns A shallow array copy of the iteration order.
205
+ * @remarks
206
+ * Time O(n), Space O(n).
207
+ */
208
+ toArray() {
209
+ return [...this];
210
+ }
211
+ /**
212
+ * Returns a representation of the structure suitable for quick visualization.
213
+ * Defaults to an array of elements; subclasses may override to provide richer visuals.
214
+ *
215
+ * @returns A visual representation (array by default).
216
+ * @remarks
217
+ * Time O(n), Space O(n).
218
+ */
219
+ toVisual() {
220
+ return [...this];
221
+ }
222
+ /**
223
+ * Prints `toVisual()` to the console. Intended for quick debugging.
224
+ *
225
+ * @returns `void`.
226
+ * @remarks
227
+ * Time O(n) due to materialization, Space O(n) for the intermediate representation.
228
+ */
229
+ print() {
230
+ console.log(this.toVisual());
231
+ }
232
+ };
233
+ __name(_IterableElementBase, "IterableElementBase");
234
+ var IterableElementBase = _IterableElementBase;
235
+
236
+ // src/data-structures/base/linear-base.ts
237
+ var _LinkedListNode = class _LinkedListNode {
238
+ /**
239
+ * Initialize a node.
240
+ * @param value - Element value.
241
+ * @remarks Time O(1), Space O(1)
242
+ */
243
+ constructor(value) {
244
+ __publicField(this, "_value");
245
+ __publicField(this, "_next");
246
+ this._value = value;
247
+ this._next = void 0;
248
+ }
249
+ /**
250
+ * Element payload getter.
251
+ * @returns Element value.
252
+ * @remarks Time O(1), Space O(1)
253
+ */
254
+ get value() {
255
+ return this._value;
256
+ }
257
+ /**
258
+ * Element payload setter.
259
+ * @param value - New value.
260
+ * @remarks Time O(1), Space O(1)
261
+ */
262
+ set value(value) {
263
+ this._value = value;
264
+ }
265
+ /**
266
+ * Next node getter.
267
+ * @returns Next node or `undefined`.
268
+ * @remarks Time O(1), Space O(1)
269
+ */
270
+ get next() {
271
+ return this._next;
272
+ }
273
+ /**
274
+ * Next node setter.
275
+ * @param value - Next node or `undefined`.
276
+ * @remarks Time O(1), Space O(1)
277
+ */
278
+ set next(value) {
279
+ this._next = value;
280
+ }
281
+ };
282
+ __name(_LinkedListNode, "LinkedListNode");
283
+ var LinkedListNode = _LinkedListNode;
284
+ var _LinearBase = class _LinearBase extends IterableElementBase {
285
+ /**
286
+ * Construct a linear container with runtime options.
287
+ * @param options - `{ maxLen?, ... }` bounds/behavior options.
288
+ * @remarks Time O(1), Space O(1)
289
+ */
290
+ constructor(options) {
291
+ super(options);
292
+ __publicField(this, "_maxLen", -1);
293
+ if (options) {
294
+ const { maxLen } = options;
295
+ if (typeof maxLen === "number" && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
296
+ }
297
+ }
298
+ /**
299
+ * Upper bound for length (if positive), or `-1` when unbounded.
300
+ * @returns Maximum allowed length.
301
+ * @remarks Time O(1), Space O(1)
302
+ */
303
+ get maxLen() {
304
+ return this._maxLen;
305
+ }
306
+ /**
307
+ * First index of a value from the left.
308
+ * @param searchElement - Value to match.
309
+ * @param fromIndex - Start position (supports negative index).
310
+ * @returns Index or `-1` if not found.
311
+ * @remarks Time O(n), Space O(1)
312
+ */
313
+ indexOf(searchElement, fromIndex = 0) {
314
+ if (this.length === 0) return -1;
315
+ if (fromIndex < 0) fromIndex = this.length + fromIndex;
316
+ if (fromIndex < 0) fromIndex = 0;
317
+ for (let i = fromIndex; i < this.length; i++) {
318
+ const element = this.at(i);
319
+ if (element === searchElement) return i;
320
+ }
321
+ return -1;
322
+ }
323
+ /**
324
+ * Last index of a value from the right.
325
+ * @param searchElement - Value to match.
326
+ * @param fromIndex - Start position (supports negative index).
327
+ * @returns Index or `-1` if not found.
328
+ * @remarks Time O(n), Space O(1)
329
+ */
330
+ lastIndexOf(searchElement, fromIndex = this.length - 1) {
331
+ if (this.length === 0) return -1;
332
+ if (fromIndex >= this.length) fromIndex = this.length - 1;
333
+ if (fromIndex < 0) fromIndex = this.length + fromIndex;
334
+ for (let i = fromIndex; i >= 0; i--) {
335
+ const element = this.at(i);
336
+ if (element === searchElement) return i;
337
+ }
338
+ return -1;
339
+ }
340
+ /**
341
+ * Find the first index matching a predicate.
342
+ * @param predicate - `(element, index, self) => boolean`.
343
+ * @param thisArg - Optional `this` for callback.
344
+ * @returns Index or `-1`.
345
+ * @remarks Time O(n), Space O(1)
346
+ */
347
+ findIndex(predicate, thisArg) {
348
+ for (let i = 0; i < this.length; i++) {
349
+ const item = this.at(i);
350
+ if (item !== void 0 && predicate.call(thisArg, item, i, this)) return i;
351
+ }
352
+ return -1;
353
+ }
354
+ /**
355
+ * Concatenate elements and/or containers.
356
+ * @param items - Elements or other containers.
357
+ * @returns New container with combined elements (`this` type).
358
+ * @remarks Time O(sum(length)), Space O(sum(length))
359
+ */
360
+ concat(...items) {
361
+ const newList = this.clone();
362
+ for (const item of items) {
363
+ if (item instanceof _LinearBase) {
364
+ newList.pushMany(item);
365
+ } else {
366
+ newList.push(item);
367
+ }
368
+ }
369
+ return newList;
370
+ }
371
+ /**
372
+ * In-place stable order via array sort semantics.
373
+ * @param compareFn - Comparator `(a, b) => number`.
374
+ * @returns This container.
375
+ * @remarks Time O(n log n), Space O(n) (materializes to array temporarily)
376
+ */
377
+ sort(compareFn) {
378
+ const arr = this.toArray();
379
+ arr.sort(compareFn);
380
+ this.clear();
381
+ for (const item of arr) this.push(item);
382
+ return this;
383
+ }
384
+ /**
385
+ * Remove and/or insert elements at a position (array-compatible).
386
+ * @param start - Start index (supports negative index).
387
+ * @param deleteCount - How many to remove.
388
+ * @param items - Elements to insert.
389
+ * @returns Removed elements as a new list (`this` type).
390
+ * @remarks Time O(n + m), Space O(min(n, m)) where `m = items.length`
391
+ */
392
+ splice(start, deleteCount = 0, ...items) {
393
+ const removedList = this._createInstance();
394
+ start = start < 0 ? this.length + start : start;
395
+ start = Math.max(0, Math.min(start, this.length));
396
+ deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
397
+ for (let i = 0; i < deleteCount; i++) {
398
+ const removed = this.deleteAt(start);
399
+ if (removed !== void 0) {
400
+ removedList.push(removed);
401
+ }
402
+ }
403
+ for (let i = 0; i < items.length; i++) {
404
+ this.addAt(start + i, items[i]);
405
+ }
406
+ return removedList;
407
+ }
408
+ /**
409
+ * Join all elements into a string.
410
+ * @param separator - Separator string.
411
+ * @returns Concatenated string.
412
+ * @remarks Time O(n), Space O(n)
413
+ */
414
+ join(separator = ",") {
415
+ return this.toArray().join(separator);
416
+ }
417
+ /**
418
+ * Snapshot elements into a reversed array.
419
+ * @returns New reversed array.
420
+ * @remarks Time O(n), Space O(n)
421
+ */
422
+ toReversedArray() {
423
+ const array = [];
424
+ for (let i = this.length - 1; i >= 0; i--) {
425
+ array.push(this.at(i));
426
+ }
427
+ return array;
428
+ }
429
+ reduceRight(callbackfn, initialValue) {
430
+ let accumulator = initialValue != null ? initialValue : 0;
431
+ for (let i = this.length - 1; i >= 0; i--) {
432
+ accumulator = callbackfn(accumulator, this.at(i), i, this);
433
+ }
434
+ return accumulator;
435
+ }
436
+ /**
437
+ * Create a shallow copy of a subrange.
438
+ * @param start - Inclusive start (supports negative index).
439
+ * @param end - Exclusive end (supports negative index).
440
+ * @returns New list with the range (`this` type).
441
+ * @remarks Time O(n), Space O(n)
442
+ */
443
+ slice(start = 0, end = this.length) {
444
+ start = start < 0 ? this.length + start : start;
445
+ end = end < 0 ? this.length + end : end;
446
+ const newList = this._createInstance();
447
+ for (let i = start; i < end; i++) {
448
+ newList.push(this.at(i));
449
+ }
450
+ return newList;
451
+ }
452
+ /**
453
+ * Fill a range with a value.
454
+ * @param value - Value to set.
455
+ * @param start - Inclusive start.
456
+ * @param end - Exclusive end.
457
+ * @returns This list.
458
+ * @remarks Time O(n), Space O(1)
459
+ */
460
+ fill(value, start = 0, end = this.length) {
461
+ start = start < 0 ? this.length + start : start;
462
+ end = end < 0 ? this.length + end : end;
463
+ if (start < 0) start = 0;
464
+ if (end > this.length) end = this.length;
465
+ if (start >= end) return this;
466
+ for (let i = start; i < end; i++) {
467
+ this.setAt(i, value);
468
+ }
469
+ return this;
470
+ }
471
+ };
472
+ __name(_LinearBase, "LinearBase");
473
+ var LinearBase = _LinearBase;
474
+ var _LinearLinkedBase = class _LinearLinkedBase extends LinearBase {
475
+ constructor(options) {
476
+ super(options);
477
+ if (options) {
478
+ const { maxLen } = options;
479
+ if (typeof maxLen === "number" && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
480
+ }
481
+ }
482
+ /**
483
+ * Linked-list optimized `indexOf` (forwards scan).
484
+ * @param searchElement - Value to match.
485
+ * @param fromIndex - Start position.
486
+ * @returns Index or `-1`.
487
+ * @remarks Time O(n), Space O(1)
488
+ */
489
+ indexOf(searchElement, fromIndex = 0) {
490
+ const iterator = this._getIterator();
491
+ let current = iterator.next();
492
+ let index = 0;
493
+ while (index < fromIndex) {
494
+ current = iterator.next();
495
+ index++;
496
+ }
497
+ while (!current.done) {
498
+ if (current.value === searchElement) return index;
499
+ current = iterator.next();
500
+ index++;
501
+ }
502
+ return -1;
503
+ }
504
+ /**
505
+ * Linked-list optimized `lastIndexOf` (reverse scan).
506
+ * @param searchElement - Value to match.
507
+ * @param fromIndex - Start position.
508
+ * @returns Index or `-1`.
509
+ * @remarks Time O(n), Space O(1)
510
+ */
511
+ lastIndexOf(searchElement, fromIndex = this.length - 1) {
512
+ const iterator = this._getReverseIterator();
513
+ let current = iterator.next();
514
+ let index = this.length - 1;
515
+ while (index > fromIndex) {
516
+ current = iterator.next();
517
+ index--;
518
+ }
519
+ while (!current.done) {
520
+ if (current.value === searchElement) return index;
521
+ current = iterator.next();
522
+ index--;
523
+ }
524
+ return -1;
525
+ }
526
+ /**
527
+ * Concatenate lists/elements preserving order.
528
+ * @param items - Elements or `LinearBase` instances.
529
+ * @returns New list with combined elements (`this` type).
530
+ * @remarks Time O(sum(length)), Space O(sum(length))
531
+ */
532
+ concat(...items) {
533
+ const newList = this.clone();
534
+ for (const item of items) {
535
+ if (item instanceof LinearBase) {
536
+ newList.pushMany(item);
537
+ } else {
538
+ newList.push(item);
539
+ }
540
+ }
541
+ return newList;
542
+ }
543
+ /**
544
+ * Slice via forward iteration (no random access required).
545
+ * @param start - Inclusive start (supports negative index).
546
+ * @param end - Exclusive end (supports negative index).
547
+ * @returns New list (`this` type).
548
+ * @remarks Time O(n), Space O(n)
549
+ */
550
+ slice(start = 0, end = this.length) {
551
+ start = start < 0 ? this.length + start : start;
552
+ end = end < 0 ? this.length + end : end;
553
+ const newList = this._createInstance();
554
+ const iterator = this._getIterator();
555
+ let current = iterator.next();
556
+ let c = 0;
557
+ while (c < start) {
558
+ current = iterator.next();
559
+ c++;
560
+ }
561
+ for (let i = start; i < end; i++) {
562
+ newList.push(current.value);
563
+ current = iterator.next();
564
+ }
565
+ return newList;
566
+ }
567
+ /**
568
+ * Splice by walking node iterators from the start index.
569
+ * @param start - Start index.
570
+ * @param deleteCount - How many elements to remove.
571
+ * @param items - Elements to insert after the splice point.
572
+ * @returns Removed elements as a new list (`this` type).
573
+ * @remarks Time O(n + m), Space O(min(n, m)) where `m = items.length`
574
+ */
575
+ splice(start, deleteCount = 0, ...items) {
576
+ const removedList = this._createInstance();
577
+ start = start < 0 ? this.length + start : start;
578
+ start = Math.max(0, Math.min(start, this.length));
579
+ deleteCount = Math.max(0, deleteCount);
580
+ let currentIndex = 0;
581
+ let currentNode = void 0;
582
+ let previousNode = void 0;
583
+ const iterator = this._getNodeIterator();
584
+ for (const node of iterator) {
585
+ if (currentIndex === start) {
586
+ currentNode = node;
587
+ break;
588
+ }
589
+ previousNode = node;
590
+ currentIndex++;
591
+ }
592
+ for (let i = 0; i < deleteCount && currentNode; i++) {
593
+ removedList.push(currentNode.value);
594
+ const nextNode = currentNode.next;
595
+ this.delete(currentNode);
596
+ currentNode = nextNode;
597
+ }
598
+ for (let i = 0; i < items.length; i++) {
599
+ if (previousNode) {
600
+ this.addAfter(previousNode, items[i]);
601
+ previousNode = previousNode.next;
602
+ } else {
603
+ this.addAt(0, items[i]);
604
+ previousNode = this._getNodeIterator().next().value;
605
+ }
606
+ }
607
+ return removedList;
608
+ }
609
+ reduceRight(callbackfn, initialValue) {
610
+ let accumulator = initialValue != null ? initialValue : 0;
611
+ let index = this.length - 1;
612
+ for (const item of this._getReverseIterator()) {
613
+ accumulator = callbackfn(accumulator, item, index--, this);
614
+ }
615
+ return accumulator;
616
+ }
617
+ };
618
+ __name(_LinearLinkedBase, "LinearLinkedBase");
619
+ var LinearLinkedBase = _LinearLinkedBase;
620
+
621
+ // src/data-structures/linked-list/singly-linked-list.ts
622
+ var _SinglyLinkedListNode = class _SinglyLinkedListNode extends LinkedListNode {
623
+ /**
624
+ * Create a list node.
625
+ * @remarks Time O(1), Space O(1)
626
+ * @param value - Element value to store.
627
+ * @returns New node instance.
628
+ */
629
+ constructor(value) {
630
+ super(value);
631
+ __publicField(this, "_next");
632
+ this._value = value;
633
+ this._next = void 0;
634
+ }
635
+ /**
636
+ * Get the next node.
637
+ * @remarks Time O(1), Space O(1)
638
+ * @returns Next node or undefined.
639
+ */
640
+ get next() {
641
+ return this._next;
642
+ }
643
+ /**
644
+ * Set the next node.
645
+ * @remarks Time O(1), Space O(1)
646
+ * @param value - Next node or undefined.
647
+ * @returns void
648
+ */
649
+ set next(value) {
650
+ this._next = value;
651
+ }
652
+ };
653
+ __name(_SinglyLinkedListNode, "SinglyLinkedListNode");
654
+ var SinglyLinkedListNode = _SinglyLinkedListNode;
655
+ var _SinglyLinkedList = class _SinglyLinkedList extends LinearLinkedBase {
656
+ /**
657
+ * Create a SinglyLinkedList and optionally bulk-insert elements.
658
+ * @remarks Time O(N), Space O(N)
659
+ * @param [elements] - Iterable of elements or nodes (or raw records if toElementFn is provided).
660
+ * @param [options] - Options such as maxLen and toElementFn.
661
+ * @returns New SinglyLinkedList instance.
662
+ */
663
+ constructor(elements = [], options) {
664
+ super(options);
665
+ __publicField(this, "_equals", /* @__PURE__ */ __name((a, b) => Object.is(a, b), "_equals"));
666
+ __publicField(this, "_head");
667
+ __publicField(this, "_tail");
668
+ __publicField(this, "_length", 0);
669
+ this.pushMany(elements);
670
+ }
671
+ /**
672
+ * Get the head node.
673
+ * @remarks Time O(1), Space O(1)
674
+ * @returns Head node or undefined.
675
+ */
676
+ get head() {
677
+ return this._head;
678
+ }
679
+ /**
680
+ * Get the tail node.
681
+ * @remarks Time O(1), Space O(1)
682
+ * @returns Tail node or undefined.
683
+ */
684
+ get tail() {
685
+ return this._tail;
686
+ }
687
+ /**
688
+ * Get the number of elements.
689
+ * @remarks Time O(1), Space O(1)
690
+ * @returns Current length.
691
+ */
692
+ get length() {
693
+ return this._length;
694
+ }
695
+ /**
696
+ * Get the first element value.
697
+ * @remarks Time O(1), Space O(1)
698
+ * @returns First element or undefined.
699
+ */
700
+ get first() {
701
+ var _a;
702
+ return (_a = this.head) == null ? void 0 : _a.value;
703
+ }
704
+ /**
705
+ * Get the last element value.
706
+ * @remarks Time O(1), Space O(1)
707
+ * @returns Last element or undefined.
708
+ */
709
+ get last() {
710
+ var _a;
711
+ return (_a = this.tail) == null ? void 0 : _a.value;
712
+ }
713
+ /**
714
+ * Create a new list from an iterable of elements.
715
+ * @remarks Time O(N), Space O(N)
716
+ * @template E
717
+ * @template R
718
+ * @template S
719
+ * @param this - The constructor (subclass) to instantiate.
720
+ * @param data - Iterable of elements to insert.
721
+ * @param [options] - Options forwarded to the constructor.
722
+ * @returns A new list populated with the iterable's elements.
723
+ */
724
+ static from(data, options) {
725
+ const list = new this([], options);
726
+ for (const x of data) list.push(x);
727
+ return list;
728
+ }
729
+ /**
730
+ * Append an element/node to the tail.
731
+ * @remarks Time O(1), Space O(1)
732
+ * @param elementOrNode - Element or node to append.
733
+ * @returns True when appended.
734
+
735
+
736
+
737
+
738
+
739
+
740
+
741
+
742
+
743
+
744
+
745
+
746
+
747
+
748
+
749
+
750
+
751
+
752
+
753
+
754
+
755
+
756
+
757
+
758
+
759
+
760
+
761
+
762
+
763
+
764
+
765
+
766
+
767
+
768
+
769
+ * @example
770
+ * // basic SinglyLinkedList creation and push operation
771
+ * // Create a simple SinglyLinkedList with initial values
772
+ * const list = new SinglyLinkedList([1, 2, 3, 4, 5]);
773
+ *
774
+ * // Verify the list maintains insertion order
775
+ * console.log([...list]); // [1, 2, 3, 4, 5];
776
+ *
777
+ * // Check length
778
+ * console.log(list.length); // 5;
779
+ *
780
+ * // Push a new element to the end
781
+ * list.push(6);
782
+ * console.log(list.length); // 6;
783
+ * console.log([...list]); // [1, 2, 3, 4, 5, 6];
784
+ */
785
+ push(elementOrNode) {
786
+ const newNode = this._ensureNode(elementOrNode);
787
+ if (!this.head) {
788
+ this._head = this._tail = newNode;
789
+ } else {
790
+ this.tail.next = newNode;
791
+ this._tail = newNode;
792
+ }
793
+ this._length++;
794
+ if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
795
+ return true;
796
+ }
797
+ /**
798
+ * Remove and return the tail element.
799
+ * @remarks Time O(N), Space O(1)
800
+ * @returns Removed element or undefined.
801
+
802
+
803
+
804
+
805
+
806
+
807
+
808
+
809
+
810
+
811
+
812
+
813
+
814
+
815
+
816
+
817
+
818
+
819
+
820
+
821
+
822
+
823
+
824
+
825
+
826
+
827
+
828
+
829
+
830
+
831
+
832
+
833
+
834
+
835
+
836
+ * @example
837
+ * // SinglyLinkedList pop and shift operations
838
+ * const list = new SinglyLinkedList<number>([10, 20, 30, 40, 50]);
839
+ *
840
+ * // Pop removes from the end
841
+ * const last = list.pop();
842
+ * console.log(last); // 50;
843
+ *
844
+ * // Shift removes from the beginning
845
+ * const first = list.shift();
846
+ * console.log(first); // 10;
847
+ *
848
+ * // Verify remaining elements
849
+ * console.log([...list]); // [20, 30, 40];
850
+ * console.log(list.length); // 3;
851
+ */
852
+ pop() {
853
+ var _a;
854
+ if (!this.head) return void 0;
855
+ if (this.head === this.tail) {
856
+ const value2 = this.head.value;
857
+ this._head = void 0;
858
+ this._tail = void 0;
859
+ this._length--;
860
+ return value2;
861
+ }
862
+ let current = this.head;
863
+ while (current.next && current.next !== this.tail) current = current.next;
864
+ const value = (_a = this.tail) == null ? void 0 : _a.value;
865
+ current.next = void 0;
866
+ this._tail = current;
867
+ this._length--;
868
+ return value;
869
+ }
870
+ /**
871
+ * Remove and return the head element.
872
+ * @remarks Time O(1), Space O(1)
873
+ * @returns Removed element or undefined.
874
+
875
+
876
+
877
+
878
+
879
+
880
+
881
+
882
+
883
+
884
+
885
+
886
+
887
+
888
+
889
+
890
+
891
+
892
+
893
+
894
+
895
+
896
+
897
+
898
+
899
+
900
+
901
+
902
+
903
+
904
+
905
+
906
+
907
+
908
+
909
+ * @example
910
+ * // Remove from the front
911
+ * const list = new SinglyLinkedList<number>([10, 20, 30]);
912
+ * console.log(list.shift()); // 10;
913
+ * console.log(list.length); // 2;
914
+ */
915
+ shift() {
916
+ if (!this.head) return void 0;
917
+ const removed = this.head;
918
+ this._head = this.head.next;
919
+ if (!this._head) this._tail = void 0;
920
+ this._length--;
921
+ return removed.value;
922
+ }
923
+ /**
924
+ * Prepend an element/node to the head.
925
+ * @remarks Time O(1), Space O(1)
926
+ * @param elementOrNode - Element or node to prepend.
927
+ * @returns True when prepended.
928
+
929
+
930
+
931
+
932
+
933
+
934
+
935
+
936
+
937
+
938
+
939
+
940
+
941
+
942
+
943
+
944
+
945
+
946
+
947
+
948
+
949
+
950
+
951
+
952
+
953
+
954
+
955
+
956
+
957
+
958
+
959
+
960
+
961
+
962
+
963
+ * @example
964
+ * // SinglyLinkedList unshift and forward traversal
965
+ * const list = new SinglyLinkedList<number>([20, 30, 40]);
966
+ *
967
+ * // Unshift adds to the beginning
968
+ * list.unshift(10);
969
+ * console.log([...list]); // [10, 20, 30, 40];
970
+ *
971
+ * // Access elements (forward traversal only for singly linked)
972
+ * const second = list.at(1);
973
+ * console.log(second); // 20;
974
+ *
975
+ * // SinglyLinkedList allows forward iteration only
976
+ * const elements: number[] = [];
977
+ * for (const item of list) {
978
+ * elements.push(item);
979
+ * }
980
+ * console.log(elements); // [10, 20, 30, 40];
981
+ *
982
+ * console.log(list.length); // 4;
983
+ */
984
+ unshift(elementOrNode) {
985
+ const newNode = this._ensureNode(elementOrNode);
986
+ if (!this.head) {
987
+ this._head = this._tail = newNode;
988
+ } else {
989
+ newNode.next = this.head;
990
+ this._head = newNode;
991
+ }
992
+ this._length++;
993
+ return true;
994
+ }
995
+ /**
996
+ * Append a sequence of elements/nodes.
997
+ * @remarks Time O(N), Space O(1)
998
+ * @param elements - Iterable of elements or nodes (or raw records if toElementFn is provided).
999
+ * @returns Array of per-element success flags.
1000
+ */
1001
+ pushMany(elements) {
1002
+ const ans = [];
1003
+ for (const el of elements) {
1004
+ if (this.toElementFn) ans.push(this.push(this.toElementFn(el)));
1005
+ else ans.push(this.push(el));
1006
+ }
1007
+ return ans;
1008
+ }
1009
+ /**
1010
+ * Prepend a sequence of elements/nodes.
1011
+ * @remarks Time O(N), Space O(1)
1012
+ * @param elements - Iterable of elements or nodes (or raw records if toElementFn is provided).
1013
+ * @returns Array of per-element success flags.
1014
+ */
1015
+ unshiftMany(elements) {
1016
+ const ans = [];
1017
+ for (const el of elements) {
1018
+ if (this.toElementFn) ans.push(this.unshift(this.toElementFn(el)));
1019
+ else ans.push(this.unshift(el));
1020
+ }
1021
+ return ans;
1022
+ }
1023
+ /**
1024
+ * Find the first value matching a predicate (by node).
1025
+ * @remarks Time O(N), Space O(1)
1026
+ * @param elementNodeOrPredicate - Element, node, or node predicate to match.
1027
+ * @returns Matched value or undefined.
1028
+ */
1029
+ search(elementNodeOrPredicate) {
1030
+ const predicate = this._ensurePredicate(elementNodeOrPredicate);
1031
+ let current = this.head;
1032
+ while (current) {
1033
+ if (predicate(current)) return current.value;
1034
+ current = current.next;
1035
+ }
1036
+ return void 0;
1037
+ }
1038
+ /**
1039
+ * Get the element at a given index.
1040
+ * @remarks Time O(N), Space O(1)
1041
+ * @param index - Zero-based index.
1042
+ * @returns Element or undefined.
1043
+
1044
+
1045
+
1046
+
1047
+
1048
+
1049
+
1050
+
1051
+
1052
+
1053
+
1054
+
1055
+
1056
+
1057
+
1058
+
1059
+
1060
+
1061
+
1062
+
1063
+
1064
+
1065
+
1066
+
1067
+
1068
+
1069
+
1070
+
1071
+
1072
+
1073
+
1074
+
1075
+
1076
+
1077
+
1078
+ * @example
1079
+ * // Access element by index
1080
+ * const list = new SinglyLinkedList<string>(['a', 'b', 'c', 'd']);
1081
+ * console.log(list.at(0)); // 'a';
1082
+ * console.log(list.at(2)); // 'c';
1083
+ * console.log(list.at(3)); // 'd';
1084
+ */
1085
+ at(index) {
1086
+ if (index < 0 || index >= this._length) return void 0;
1087
+ let current = this.head;
1088
+ for (let i = 0; i < index && current; i++) current = current.next;
1089
+ return current == null ? void 0 : current.value;
1090
+ }
1091
+ /**
1092
+ * Type guard: check whether the input is a SinglyLinkedListNode.
1093
+ * @remarks Time O(1), Space O(1)
1094
+ * @param elementNodeOrPredicate - Element, node, or predicate.
1095
+ * @returns True if the value is a SinglyLinkedListNode.
1096
+ */
1097
+ isNode(elementNodeOrPredicate) {
1098
+ return elementNodeOrPredicate instanceof SinglyLinkedListNode;
1099
+ }
1100
+ /**
1101
+ * Get the node reference at a given index.
1102
+ * @remarks Time O(N), Space O(1)
1103
+ * @param index - Zero-based index.
1104
+ * @returns Node or undefined.
1105
+
1106
+
1107
+
1108
+
1109
+
1110
+
1111
+
1112
+
1113
+
1114
+
1115
+
1116
+
1117
+
1118
+
1119
+
1120
+
1121
+
1122
+
1123
+
1124
+
1125
+
1126
+
1127
+
1128
+
1129
+
1130
+
1131
+
1132
+
1133
+
1134
+
1135
+
1136
+
1137
+ * @example
1138
+ * // Get node at index
1139
+ * const list = new SinglyLinkedList<string>(['a', 'b', 'c']);
1140
+ * console.log(list.getNodeAt(1)?.value); // 'b';
1141
+ */
1142
+ getNodeAt(index) {
1143
+ if (index < 0 || index >= this._length) return void 0;
1144
+ let current = this.head;
1145
+ for (let i = 0; i < index && current; i++) current = current.next;
1146
+ return current;
1147
+ }
1148
+ /**
1149
+ * Delete the element at an index.
1150
+ * @remarks Time O(N), Space O(1)
1151
+ * @param index - Zero-based index.
1152
+ * @returns Removed element or undefined.
1153
+
1154
+
1155
+
1156
+
1157
+
1158
+
1159
+
1160
+
1161
+
1162
+
1163
+
1164
+
1165
+
1166
+
1167
+
1168
+
1169
+
1170
+
1171
+
1172
+
1173
+
1174
+
1175
+
1176
+
1177
+
1178
+
1179
+
1180
+
1181
+
1182
+
1183
+
1184
+
1185
+ * @example
1186
+ * // Remove by index
1187
+ * const list = new SinglyLinkedList<string>(['a', 'b', 'c']);
1188
+ * list.deleteAt(1);
1189
+ * console.log(list.toArray()); // ['a', 'c'];
1190
+ */
1191
+ deleteAt(index) {
1192
+ if (index < 0 || index >= this._length) return void 0;
1193
+ if (index === 0) return this.shift();
1194
+ const targetNode = this.getNodeAt(index);
1195
+ const prevNode = this._getPrevNode(targetNode);
1196
+ const value = targetNode.value;
1197
+ prevNode.next = targetNode.next;
1198
+ if (targetNode === this.tail) this._tail = prevNode;
1199
+ this._length--;
1200
+ return value;
1201
+ }
1202
+ /**
1203
+ * Delete the first match by value/node.
1204
+ * @remarks Time O(N), Space O(1)
1205
+ * @param [elementOrNode] - Element or node to remove; if omitted/undefined, nothing happens.
1206
+ * @returns True if removed.
1207
+
1208
+
1209
+
1210
+
1211
+
1212
+
1213
+
1214
+
1215
+
1216
+
1217
+
1218
+
1219
+
1220
+
1221
+
1222
+
1223
+
1224
+
1225
+
1226
+
1227
+
1228
+
1229
+
1230
+
1231
+
1232
+
1233
+
1234
+
1235
+
1236
+
1237
+
1238
+
1239
+ * @example
1240
+ * // Remove first occurrence
1241
+ * const list = new SinglyLinkedList<number>([1, 2, 3, 2]);
1242
+ * list.delete(2);
1243
+ * console.log(list.toArray()); // [1, 3, 2];
1244
+ */
1245
+ delete(elementOrNode) {
1246
+ if (elementOrNode === void 0 || !this.head) return false;
1247
+ const node = this.isNode(elementOrNode) ? elementOrNode : this.getNode(elementOrNode);
1248
+ if (!node) return false;
1249
+ const prevNode = this._getPrevNode(node);
1250
+ if (!prevNode) {
1251
+ this._head = node.next;
1252
+ if (node === this.tail) this._tail = void 0;
1253
+ } else {
1254
+ prevNode.next = node.next;
1255
+ if (node === this.tail) this._tail = prevNode;
1256
+ }
1257
+ this._length--;
1258
+ return true;
1259
+ }
1260
+ /**
1261
+ * Insert a new element/node at an index, shifting following nodes.
1262
+ * @remarks Time O(N), Space O(1)
1263
+ * @param index - Zero-based index.
1264
+ * @param newElementOrNode - Element or node to insert.
1265
+ * @returns True if inserted.
1266
+
1267
+
1268
+
1269
+
1270
+
1271
+
1272
+
1273
+
1274
+
1275
+
1276
+
1277
+
1278
+
1279
+
1280
+
1281
+
1282
+
1283
+
1284
+
1285
+
1286
+
1287
+
1288
+
1289
+
1290
+
1291
+
1292
+
1293
+
1294
+
1295
+
1296
+
1297
+
1298
+ * @example
1299
+ * // Insert at index
1300
+ * const list = new SinglyLinkedList<number>([1, 3]);
1301
+ * list.addAt(1, 2);
1302
+ * console.log(list.toArray()); // [1, 2, 3];
1303
+ */
1304
+ addAt(index, newElementOrNode) {
1305
+ if (index < 0 || index > this._length) return false;
1306
+ if (index === 0) return this.unshift(newElementOrNode);
1307
+ if (index === this._length) return this.push(newElementOrNode);
1308
+ const newNode = this._ensureNode(newElementOrNode);
1309
+ const prevNode = this.getNodeAt(index - 1);
1310
+ newNode.next = prevNode.next;
1311
+ prevNode.next = newNode;
1312
+ this._length++;
1313
+ return true;
1314
+ }
1315
+ /**
1316
+ * Set the element value at an index.
1317
+ * @remarks Time O(N), Space O(1)
1318
+ * @param index - Zero-based index.
1319
+ * @param value - New value.
1320
+ * @returns True if updated.
1321
+ */
1322
+ setAt(index, value) {
1323
+ const node = this.getNodeAt(index);
1324
+ if (!node) return false;
1325
+ node.value = value;
1326
+ return true;
1327
+ }
1328
+ /**
1329
+ * Check whether the list is empty.
1330
+ * @remarks Time O(1), Space O(1)
1331
+ * @returns True if length is 0.
1332
+
1333
+
1334
+
1335
+
1336
+
1337
+
1338
+
1339
+
1340
+
1341
+
1342
+
1343
+
1344
+
1345
+
1346
+
1347
+
1348
+
1349
+
1350
+
1351
+
1352
+
1353
+
1354
+
1355
+
1356
+
1357
+
1358
+
1359
+
1360
+
1361
+
1362
+
1363
+
1364
+
1365
+ * @example
1366
+ * // Check empty
1367
+ * console.log(new SinglyLinkedList().isEmpty()); // true;
1368
+ */
1369
+ isEmpty() {
1370
+ return this._length === 0;
1371
+ }
1372
+ /**
1373
+ * Remove all nodes and reset length.
1374
+ * @remarks Time O(N), Space O(1)
1375
+ * @returns void
1376
+
1377
+
1378
+
1379
+
1380
+
1381
+
1382
+
1383
+
1384
+
1385
+
1386
+
1387
+
1388
+
1389
+
1390
+
1391
+
1392
+
1393
+
1394
+
1395
+
1396
+
1397
+
1398
+
1399
+
1400
+
1401
+
1402
+
1403
+
1404
+
1405
+
1406
+
1407
+
1408
+
1409
+ * @example
1410
+ * // Remove all
1411
+ * const list = new SinglyLinkedList<number>([1, 2, 3]);
1412
+ * list.clear();
1413
+ * console.log(list.isEmpty()); // true;
1414
+ */
1415
+ clear() {
1416
+ this._head = void 0;
1417
+ this._tail = void 0;
1418
+ this._length = 0;
1419
+ }
1420
+ /**
1421
+ * Reverse the list in place.
1422
+ * @remarks Time O(N), Space O(1)
1423
+ * @returns This list.
1424
+
1425
+
1426
+
1427
+
1428
+
1429
+
1430
+
1431
+
1432
+
1433
+
1434
+
1435
+
1436
+
1437
+
1438
+
1439
+
1440
+
1441
+
1442
+
1443
+
1444
+
1445
+
1446
+
1447
+
1448
+
1449
+
1450
+
1451
+
1452
+
1453
+
1454
+
1455
+
1456
+
1457
+
1458
+
1459
+ * @example
1460
+ * // Reverse the list in-place
1461
+ * const list = new SinglyLinkedList<number>([1, 2, 3, 4]);
1462
+ * list.reverse();
1463
+ * console.log([...list]); // [4, 3, 2, 1];
1464
+ */
1465
+ reverse() {
1466
+ if (!this.head || this.head === this.tail) return this;
1467
+ let prev;
1468
+ let current = this.head;
1469
+ let next;
1470
+ while (current) {
1471
+ next = current.next;
1472
+ current.next = prev;
1473
+ prev = current;
1474
+ current = next;
1475
+ }
1476
+ [this._head, this._tail] = [this.tail, this.head];
1477
+ return this;
1478
+ }
1479
+ /**
1480
+ * Find a node by value, reference, or predicate.
1481
+ * @remarks Time O(N), Space O(1)
1482
+ * @param [elementNodeOrPredicate] - Element, node, or node predicate to match.
1483
+ * @returns Matching node or undefined.
1484
+ */
1485
+ getNode(elementNodeOrPredicate) {
1486
+ if (elementNodeOrPredicate === void 0) return;
1487
+ if (this.isNode(elementNodeOrPredicate)) return elementNodeOrPredicate;
1488
+ const predicate = this._ensurePredicate(elementNodeOrPredicate);
1489
+ let current = this.head;
1490
+ while (current) {
1491
+ if (predicate(current)) return current;
1492
+ current = current.next;
1493
+ }
1494
+ return void 0;
1495
+ }
1496
+ /**
1497
+ * Insert a new element/node before an existing one.
1498
+ * @remarks Time O(N), Space O(1)
1499
+ * @param existingElementOrNode - Existing element or node.
1500
+ * @param newElementOrNode - Element or node to insert.
1501
+ * @returns True if inserted.
1502
+ */
1503
+ addBefore(existingElementOrNode, newElementOrNode) {
1504
+ const existingNode = this.getNode(existingElementOrNode);
1505
+ if (!existingNode) return false;
1506
+ const prevNode = this._getPrevNode(existingNode);
1507
+ const newNode = this._ensureNode(newElementOrNode);
1508
+ if (!prevNode) {
1509
+ newNode.next = this._head;
1510
+ this._head = newNode;
1511
+ if (!this._tail) this._tail = newNode;
1512
+ this._length++;
1513
+ } else {
1514
+ prevNode.next = newNode;
1515
+ newNode.next = existingNode;
1516
+ this._length++;
1517
+ }
1518
+ return true;
1519
+ }
1520
+ /**
1521
+ * Insert a new element/node after an existing one.
1522
+ * @remarks Time O(N), Space O(1)
1523
+ * @param existingElementOrNode - Existing element or node.
1524
+ * @param newElementOrNode - Element or node to insert.
1525
+ * @returns True if inserted.
1526
+ */
1527
+ addAfter(existingElementOrNode, newElementOrNode) {
1528
+ const existingNode = this.getNode(existingElementOrNode);
1529
+ if (!existingNode) return false;
1530
+ const newNode = this._ensureNode(newElementOrNode);
1531
+ newNode.next = existingNode.next;
1532
+ existingNode.next = newNode;
1533
+ if (existingNode === this.tail) this._tail = newNode;
1534
+ this._length++;
1535
+ return true;
1536
+ }
1537
+ /**
1538
+ * Remove and/or insert elements at a position (array-like behavior).
1539
+ * @remarks Time O(N + M), Space O(M)
1540
+ * @param start - Start index (clamped to [0, length]).
1541
+ * @param [deleteCount] - Number of elements to remove (default 0).
1542
+ * @param [items] - Elements to insert after `start`.
1543
+ * @returns A new list containing the removed elements (typed as `this`).
1544
+ */
1545
+ splice(start, deleteCount = 0, ...items) {
1546
+ start = Math.max(0, Math.min(start, this.length));
1547
+ deleteCount = Math.max(0, deleteCount);
1548
+ const removedList = this._createInstance();
1549
+ const prevNode = start === 0 ? void 0 : this.getNodeAt(start - 1);
1550
+ let cur = prevNode ? prevNode.next : this.head;
1551
+ let removedCount = 0;
1552
+ while (removedCount < deleteCount && cur) {
1553
+ removedList.push(cur.value);
1554
+ cur = cur.next;
1555
+ removedCount++;
1556
+ }
1557
+ const afterNode = cur;
1558
+ if (prevNode) {
1559
+ prevNode.next = afterNode;
1560
+ } else {
1561
+ this._head = afterNode;
1562
+ }
1563
+ if (!afterNode) this._tail = prevNode;
1564
+ if (items.length > 0) {
1565
+ let firstInserted;
1566
+ let lastInserted;
1567
+ for (const it of items) {
1568
+ const node = this._ensureNode(it);
1569
+ if (!firstInserted) firstInserted = node;
1570
+ if (lastInserted) lastInserted.next = node;
1571
+ lastInserted = node;
1572
+ }
1573
+ if (prevNode) prevNode.next = firstInserted;
1574
+ else this._head = firstInserted;
1575
+ lastInserted.next = afterNode;
1576
+ if (!afterNode) this._tail = lastInserted;
1577
+ }
1578
+ this._length += items.length - removedCount;
1579
+ if (this._length === 0) {
1580
+ this._head = void 0;
1581
+ this._tail = void 0;
1582
+ }
1583
+ return removedList;
1584
+ }
1585
+ /**
1586
+ * Count how many nodes match a value/node/predicate.
1587
+ * @remarks Time O(N), Space O(1)
1588
+ * @param elementOrNode - Element, node, or node predicate to match.
1589
+ * @returns Number of matches in the list.
1590
+ */
1591
+ countOccurrences(elementOrNode) {
1592
+ const predicate = elementOrPredicate(elementOrNode, this._equals);
1593
+ let count = 0;
1594
+ let current = this.head;
1595
+ while (current) {
1596
+ if (predicate(current)) count++;
1597
+ current = current.next;
1598
+ }
1599
+ return count;
1600
+ }
1601
+ /**
1602
+ * Set the equality comparator used to compare values.
1603
+ * @remarks Time O(1), Space O(1)
1604
+ * @param equals - Equality predicate (a, b) → boolean.
1605
+ * @returns This list.
1606
+ */
1607
+ setEquality(equals) {
1608
+ this._equals = equals;
1609
+ return this;
1610
+ }
1611
+ /**
1612
+ * Delete the first node whose value matches a predicate.
1613
+ * @remarks Time O(N), Space O(1)
1614
+ * @param predicate - Predicate (value, index, list) → boolean to decide deletion.
1615
+ * @returns True if a node was removed.
1616
+ */
1617
+ deleteWhere(predicate) {
1618
+ let prev;
1619
+ let current = this.head;
1620
+ let i = 0;
1621
+ while (current) {
1622
+ if (predicate(current.value, i++, this)) {
1623
+ if (!prev) {
1624
+ this._head = current.next;
1625
+ if (current === this._tail) this._tail = void 0;
1626
+ } else {
1627
+ prev.next = current.next;
1628
+ if (current === this._tail) this._tail = prev;
1629
+ }
1630
+ this._length--;
1631
+ return true;
1632
+ }
1633
+ prev = current;
1634
+ current = current.next;
1635
+ }
1636
+ return false;
1637
+ }
1638
+ /**
1639
+ * Deep clone this list (values are copied by reference).
1640
+ * @remarks Time O(N), Space O(N)
1641
+ * @returns A new list with the same element sequence.
1642
+
1643
+
1644
+
1645
+
1646
+
1647
+
1648
+
1649
+
1650
+
1651
+
1652
+
1653
+
1654
+
1655
+
1656
+
1657
+
1658
+
1659
+
1660
+
1661
+
1662
+
1663
+
1664
+
1665
+
1666
+
1667
+
1668
+
1669
+
1670
+
1671
+
1672
+
1673
+
1674
+
1675
+ * @example
1676
+ * // Deep copy
1677
+ * const list = new SinglyLinkedList<number>([1, 2, 3]);
1678
+ * const copy = list.clone();
1679
+ * copy.pop();
1680
+ * console.log(list.length); // 3;
1681
+ * console.log(copy.length); // 2;
1682
+ */
1683
+ clone() {
1684
+ const out = this._createInstance();
1685
+ for (const v of this) out.push(v);
1686
+ return out;
1687
+ }
1688
+ /**
1689
+ * Filter values into a new list of the same class.
1690
+ * @remarks Time O(N), Space O(N)
1691
+ * @param callback - Predicate (value, index, list) → boolean to keep value.
1692
+ * @param [thisArg] - Value for `this` inside the callback.
1693
+ * @returns A new list with kept values.
1694
+
1695
+
1696
+
1697
+
1698
+
1699
+
1700
+
1701
+
1702
+
1703
+
1704
+
1705
+
1706
+
1707
+
1708
+
1709
+
1710
+
1711
+
1712
+
1713
+
1714
+
1715
+
1716
+
1717
+
1718
+
1719
+
1720
+
1721
+
1722
+
1723
+
1724
+
1725
+
1726
+
1727
+
1728
+
1729
+ * @example
1730
+ * // SinglyLinkedList filter and map operations
1731
+ * const list = new SinglyLinkedList<number>([1, 2, 3, 4, 5]);
1732
+ *
1733
+ * // Filter even numbers
1734
+ * const filtered = list.filter(value => value % 2 === 0);
1735
+ * console.log(filtered.length); // 2;
1736
+ *
1737
+ * // Map to double values
1738
+ * const doubled = list.map(value => value * 2);
1739
+ * console.log(doubled.length); // 5;
1740
+ *
1741
+ * // Use reduce to sum
1742
+ * const sum = list.reduce((acc, value) => acc + value, 0);
1743
+ * console.log(sum); // 15;
1744
+ */
1745
+ filter(callback, thisArg) {
1746
+ const out = this._createInstance();
1747
+ let index = 0;
1748
+ for (const value of this) if (callback.call(thisArg, value, index++, this)) out.push(value);
1749
+ return out;
1750
+ }
1751
+ /**
1752
+ * Map values into a new list of the same class.
1753
+ * @remarks Time O(N), Space O(N)
1754
+ * @param callback - Mapping function (value, index, list) → newValue.
1755
+ * @param [thisArg] - Value for `this` inside the callback.
1756
+ * @returns A new list with mapped values.
1757
+ */
1758
+ mapSame(callback, thisArg) {
1759
+ const out = this._createInstance();
1760
+ let index = 0;
1761
+ for (const value of this) {
1762
+ const mv = thisArg === void 0 ? callback(value, index++, this) : callback.call(thisArg, value, index++, this);
1763
+ out.push(mv);
1764
+ }
1765
+ return out;
1766
+ }
1767
+ /**
1768
+ * Map values into a new list (possibly different element type).
1769
+ * @remarks Time O(N), Space O(N)
1770
+ * @template EM
1771
+ * @template RM
1772
+ * @param callback - Mapping function (value, index, list) → newElement.
1773
+ * @param [options] - Options for the output list (e.g., maxLen, toElementFn).
1774
+ * @param [thisArg] - Value for `this` inside the callback.
1775
+ * @returns A new SinglyLinkedList with mapped values.
1776
+
1777
+
1778
+
1779
+
1780
+
1781
+
1782
+
1783
+
1784
+
1785
+
1786
+
1787
+
1788
+
1789
+
1790
+
1791
+
1792
+
1793
+
1794
+
1795
+
1796
+
1797
+
1798
+
1799
+
1800
+
1801
+
1802
+
1803
+
1804
+
1805
+
1806
+
1807
+
1808
+
1809
+
1810
+
1811
+ * @example
1812
+ * // Transform elements
1813
+ * const list = new SinglyLinkedList<number>([1, 2, 3]);
1814
+ * const doubled = list.map(n => n * 2);
1815
+ * console.log([...doubled]); // [2, 4, 6];
1816
+ */
1817
+ map(callback, options, thisArg) {
1818
+ const out = this._createLike([], { ...options != null ? options : {}, maxLen: this._maxLen });
1819
+ let index = 0;
1820
+ for (const value of this) out.push(callback.call(thisArg, value, index++, this));
1821
+ return out;
1822
+ }
1823
+ /**
1824
+ * (Protected) Create a node from a value.
1825
+ * @remarks Time O(1), Space O(1)
1826
+ * @param value - Value to wrap in a node.
1827
+ * @returns A new SinglyLinkedListNode instance.
1828
+ */
1829
+ createNode(value) {
1830
+ return new SinglyLinkedListNode(value);
1831
+ }
1832
+ /**
1833
+ * (Protected) Check if input is a node predicate function.
1834
+ * @remarks Time O(1), Space O(1)
1835
+ * @param elementNodeOrPredicate - Element, node, or node predicate.
1836
+ * @returns True if input is a predicate function.
1837
+ */
1838
+ _isPredicate(elementNodeOrPredicate) {
1839
+ return typeof elementNodeOrPredicate === "function";
1840
+ }
1841
+ /**
1842
+ * (Protected) Normalize input into a node instance.
1843
+ * @remarks Time O(1), Space O(1)
1844
+ * @param elementOrNode - Element or node.
1845
+ * @returns A SinglyLinkedListNode for the provided input.
1846
+ */
1847
+ _ensureNode(elementOrNode) {
1848
+ if (this.isNode(elementOrNode)) return elementOrNode;
1849
+ return this.createNode(elementOrNode);
1850
+ }
1851
+ /**
1852
+ * (Protected) Normalize input into a node predicate.
1853
+ * @remarks Time O(1), Space O(1)
1854
+ * @param elementNodeOrPredicate - Element, node, or predicate.
1855
+ * @returns A predicate taking a node and returning true/false.
1856
+ */
1857
+ _ensurePredicate(elementNodeOrPredicate) {
1858
+ if (this.isNode(elementNodeOrPredicate)) return (node) => node === elementNodeOrPredicate;
1859
+ if (this._isPredicate(elementNodeOrPredicate)) return elementNodeOrPredicate;
1860
+ const value = elementNodeOrPredicate;
1861
+ return (node) => this._equals(node.value, value);
1862
+ }
1863
+ /**
1864
+ * (Protected) Get the previous node of a given node.
1865
+ * @remarks Time O(N), Space O(1)
1866
+ * @param node - A node in the list.
1867
+ * @returns Previous node or undefined.
1868
+ */
1869
+ _getPrevNode(node) {
1870
+ if (!this.head || this.head === node) return void 0;
1871
+ let current = this.head;
1872
+ while (current.next && current.next !== node) current = current.next;
1873
+ return current.next === node ? current : void 0;
1874
+ }
1875
+ /**
1876
+ * (Protected) Iterate values from head to tail.
1877
+ * @remarks Time O(N), Space O(1)
1878
+ * @returns Iterator of values (E).
1879
+ */
1880
+ *_getIterator() {
1881
+ let current = this.head;
1882
+ while (current) {
1883
+ yield current.value;
1884
+ current = current.next;
1885
+ }
1886
+ }
1887
+ /**
1888
+ * (Protected) Iterate values from tail to head.
1889
+ * @remarks Time O(N), Space O(N)
1890
+ * @returns Iterator of values (E).
1891
+ */
1892
+ *_getReverseIterator() {
1893
+ const reversedArr = [...this].reverse();
1894
+ for (const item of reversedArr) yield item;
1895
+ }
1896
+ /**
1897
+ * (Protected) Iterate nodes from head to tail.
1898
+ * @remarks Time O(N), Space O(1)
1899
+ * @returns Iterator of nodes.
1900
+ */
1901
+ *_getNodeIterator() {
1902
+ let current = this.head;
1903
+ while (current) {
1904
+ yield current;
1905
+ current = current.next;
1906
+ }
1907
+ }
1908
+ /**
1909
+ * (Protected) Create an empty instance of the same concrete class.
1910
+ * @remarks Time O(1), Space O(1)
1911
+ * @param [options] - Options forwarded to the constructor.
1912
+ * @returns An empty like-kind list instance.
1913
+ */
1914
+ _createInstance(options) {
1915
+ const Ctor = this.constructor;
1916
+ return new Ctor([], options);
1917
+ }
1918
+ /**
1919
+ * (Protected) Create a like-kind instance and seed it from an iterable.
1920
+ * @remarks Time O(N), Space O(N)
1921
+ * @template EM
1922
+ * @template RM
1923
+ * @param [elements] - Iterable used to seed the new list.
1924
+ * @param [options] - Options forwarded to the constructor.
1925
+ * @returns A like-kind SinglyLinkedList instance.
1926
+ */
1927
+ _createLike(elements = [], options) {
1928
+ const Ctor = this.constructor;
1929
+ return new Ctor(elements, options);
1930
+ }
1931
+ /**
1932
+ * (Protected) Spawn an empty like-kind list instance.
1933
+ * @remarks Time O(1), Space O(1)
1934
+ * @template EM
1935
+ * @template RM
1936
+ * @param [options] - Options forwarded to the constructor.
1937
+ * @returns An empty like-kind SinglyLinkedList instance.
1938
+ */
1939
+ _spawnLike(options) {
1940
+ return this._createLike([], options);
1941
+ }
1942
+ };
1943
+ __name(_SinglyLinkedList, "SinglyLinkedList");
1944
+ var SinglyLinkedList = _SinglyLinkedList;
1945
+ function elementOrPredicate(input, equals) {
1946
+ if (input instanceof SinglyLinkedListNode) return (node) => node === input;
1947
+ if (typeof input === "function") return input;
1948
+ const value = input;
1949
+ return (node) => equals(node.value, value);
1950
+ }
1951
+ __name(elementOrPredicate, "elementOrPredicate");
1952
+
1953
+ // src/data-structures/queue/queue.ts
1954
+ var _Queue = class _Queue extends LinearBase {
1955
+ /**
1956
+ * Create a Queue and optionally bulk-insert elements.
1957
+ * @remarks Time O(N), Space O(N)
1958
+ * @param [elements] - Iterable of elements (or raw records if toElementFn is set).
1959
+ * @param [options] - Options such as toElementFn, maxLen, and autoCompactRatio.
1960
+ * @returns New Queue instance.
1961
+ */
1962
+ constructor(elements = [], options) {
1963
+ super(options);
1964
+ __publicField(this, "_elements", []);
1965
+ __publicField(this, "_offset", 0);
1966
+ __publicField(this, "_autoCompactRatio", 0.5);
1967
+ if (options) {
1968
+ const { autoCompactRatio = 0.5 } = options;
1969
+ this._autoCompactRatio = autoCompactRatio;
1970
+ }
1971
+ this.pushMany(elements);
1972
+ }
1973
+ /**
1974
+ * Get the underlying array buffer.
1975
+ * @remarks Time O(1), Space O(1)
1976
+ * @returns Backing array of elements.
1977
+ */
1978
+ get elements() {
1979
+ return this._elements;
1980
+ }
1981
+ /**
1982
+ * Get the current start offset into the array.
1983
+ * @remarks Time O(1), Space O(1)
1984
+ * @returns Zero-based offset.
1985
+ */
1986
+ get offset() {
1987
+ return this._offset;
1988
+ }
1989
+ /**
1990
+ * Get the compaction threshold (offset/size).
1991
+ * @remarks Time O(1), Space O(1)
1992
+ * @returns Auto-compaction ratio in (0,1].
1993
+ */
1994
+ get autoCompactRatio() {
1995
+ return this._autoCompactRatio;
1996
+ }
1997
+ /**
1998
+ * Set the compaction threshold.
1999
+ * @remarks Time O(1), Space O(1)
2000
+ * @param value - New ratio; compacts when offset/size exceeds this value.
2001
+ * @returns void
2002
+ */
2003
+ set autoCompactRatio(value) {
2004
+ this._autoCompactRatio = value;
2005
+ }
2006
+ /**
2007
+ * Get the number of elements currently in the queue.
2008
+ * @remarks Time O(1), Space O(1)
2009
+ * @returns Current length.
2010
+
2011
+
2012
+
2013
+
2014
+
2015
+
2016
+
2017
+
2018
+
2019
+
2020
+
2021
+
2022
+
2023
+
2024
+
2025
+
2026
+
2027
+
2028
+
2029
+
2030
+
2031
+
2032
+
2033
+
2034
+
2035
+
2036
+
2037
+
2038
+
2039
+
2040
+
2041
+
2042
+
2043
+
2044
+
2045
+ * @example
2046
+ * // Track queue length
2047
+ * const q = new Queue<number>();
2048
+ * console.log(q.length); // 0;
2049
+ * q.push(1);
2050
+ * q.push(2);
2051
+ * console.log(q.length); // 2;
2052
+ */
2053
+ get length() {
2054
+ return this.elements.length - this._offset;
2055
+ }
2056
+ /**
2057
+ * Get the first element (front) without removing it.
2058
+ * @remarks Time O(1), Space O(1)
2059
+ * @returns Front element or undefined.
2060
+
2061
+
2062
+
2063
+
2064
+
2065
+
2066
+
2067
+
2068
+
2069
+
2070
+
2071
+
2072
+
2073
+
2074
+
2075
+
2076
+
2077
+
2078
+
2079
+
2080
+
2081
+
2082
+
2083
+
2084
+
2085
+
2086
+
2087
+
2088
+
2089
+
2090
+
2091
+
2092
+
2093
+
2094
+
2095
+ * @example
2096
+ * // View the front element
2097
+ * const q = new Queue<string>(['first', 'second', 'third']);
2098
+ * console.log(q.first); // 'first';
2099
+ * console.log(q.length); // 3;
2100
+ */
2101
+ get first() {
2102
+ return this.length > 0 ? this.elements[this._offset] : void 0;
2103
+ }
2104
+ /**
2105
+ * Get the last element (back) without removing it.
2106
+ * @remarks Time O(1), Space O(1)
2107
+ * @returns Back element or undefined.
2108
+ */
2109
+ get last() {
2110
+ return this.length > 0 ? this.elements[this.elements.length - 1] : void 0;
2111
+ }
2112
+ /**
2113
+ * Create a queue from an array of elements.
2114
+ * @remarks Time O(N), Space O(N)
2115
+ * @template E
2116
+ * @param elements - Array of elements to enqueue in order.
2117
+ * @returns A new queue populated from the array.
2118
+ */
2119
+ static fromArray(elements) {
2120
+ return new _Queue(elements);
2121
+ }
2122
+ /**
2123
+ * Check whether the queue is empty.
2124
+ * @remarks Time O(1), Space O(1)
2125
+ * @returns True if length is 0.
2126
+
2127
+
2128
+
2129
+
2130
+
2131
+
2132
+
2133
+
2134
+
2135
+
2136
+
2137
+
2138
+
2139
+
2140
+
2141
+
2142
+
2143
+
2144
+
2145
+
2146
+
2147
+
2148
+
2149
+
2150
+
2151
+
2152
+
2153
+
2154
+
2155
+
2156
+
2157
+
2158
+
2159
+
2160
+
2161
+ * @example
2162
+ * // Queue for...of iteration and isEmpty check
2163
+ * const queue = new Queue<string>(['A', 'B', 'C', 'D']);
2164
+ *
2165
+ * const elements: string[] = [];
2166
+ * for (const item of queue) {
2167
+ * elements.push(item);
2168
+ * }
2169
+ *
2170
+ * // Verify all elements are iterated in order
2171
+ * console.log(elements); // ['A', 'B', 'C', 'D'];
2172
+ *
2173
+ * // Process all elements
2174
+ * while (queue.length > 0) {
2175
+ * queue.shift();
2176
+ * }
2177
+ *
2178
+ * console.log(queue.length); // 0;
2179
+ */
2180
+ isEmpty() {
2181
+ return this.length === 0;
2182
+ }
2183
+ /**
2184
+ * Enqueue one element at the back.
2185
+ * @remarks Time O(1), Space O(1)
2186
+ * @param element - Element to enqueue.
2187
+ * @returns True on success.
2188
+
2189
+
2190
+
2191
+
2192
+
2193
+
2194
+
2195
+
2196
+
2197
+
2198
+
2199
+
2200
+
2201
+
2202
+
2203
+
2204
+
2205
+
2206
+
2207
+
2208
+
2209
+
2210
+
2211
+
2212
+
2213
+
2214
+
2215
+
2216
+
2217
+
2218
+
2219
+
2220
+
2221
+
2222
+
2223
+ * @example
2224
+ * // basic Queue creation and push operation
2225
+ * // Create a simple Queue with initial values
2226
+ * const queue = new Queue([1, 2, 3, 4, 5]);
2227
+ *
2228
+ * // Verify the queue maintains insertion order
2229
+ * console.log([...queue]); // [1, 2, 3, 4, 5];
2230
+ *
2231
+ * // Check length
2232
+ * console.log(queue.length); // 5;
2233
+ */
2234
+ push(element) {
2235
+ this.elements.push(element);
2236
+ if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
2237
+ return true;
2238
+ }
2239
+ /**
2240
+ * Enqueue many elements from an iterable.
2241
+ * @remarks Time O(N), Space O(1)
2242
+ * @param elements - Iterable of elements (or raw records if toElementFn is set).
2243
+ * @returns Array of per-element success flags.
2244
+ */
2245
+ pushMany(elements) {
2246
+ const ans = [];
2247
+ for (const el of elements) {
2248
+ if (this.toElementFn) ans.push(this.push(this.toElementFn(el)));
2249
+ else ans.push(this.push(el));
2250
+ }
2251
+ return ans;
2252
+ }
2253
+ /**
2254
+ * Dequeue one element from the front (amortized via offset).
2255
+ * @remarks Time O(1) amortized, Space O(1)
2256
+ * @returns Removed element or undefined.
2257
+
2258
+
2259
+
2260
+
2261
+
2262
+
2263
+
2264
+
2265
+
2266
+
2267
+
2268
+
2269
+
2270
+
2271
+
2272
+
2273
+
2274
+
2275
+
2276
+
2277
+
2278
+
2279
+
2280
+
2281
+
2282
+
2283
+
2284
+
2285
+
2286
+
2287
+
2288
+
2289
+
2290
+
2291
+
2292
+ * @example
2293
+ * // Queue shift and peek operations
2294
+ * const queue = new Queue<number>([10, 20, 30, 40]);
2295
+ *
2296
+ * // Peek at the front element without removing it
2297
+ * console.log(queue.first); // 10;
2298
+ *
2299
+ * // Remove and get the first element (FIFO)
2300
+ * const first = queue.shift();
2301
+ * console.log(first); // 10;
2302
+ *
2303
+ * // Verify remaining elements and length decreased
2304
+ * console.log([...queue]); // [20, 30, 40];
2305
+ * console.log(queue.length); // 3;
2306
+ */
2307
+ shift() {
2308
+ if (this.length === 0) return void 0;
2309
+ const first = this.first;
2310
+ this._offset += 1;
2311
+ if (this.elements.length > 0 && this.offset / this.elements.length > this.autoCompactRatio) this.compact();
2312
+ return first;
2313
+ }
2314
+ /**
2315
+ * Delete the first occurrence of a specific element.
2316
+ * @remarks Time O(N), Space O(1)
2317
+ * @param element - Element to remove (strict equality via Object.is).
2318
+ * @returns True if an element was removed.
2319
+
2320
+
2321
+
2322
+
2323
+
2324
+
2325
+
2326
+
2327
+
2328
+
2329
+
2330
+
2331
+
2332
+
2333
+
2334
+
2335
+
2336
+
2337
+
2338
+
2339
+
2340
+
2341
+
2342
+
2343
+
2344
+
2345
+
2346
+
2347
+
2348
+
2349
+
2350
+
2351
+ * @example
2352
+ * // Remove specific element
2353
+ * const q = new Queue<number>([1, 2, 3, 2]);
2354
+ * q.delete(2);
2355
+ * console.log(q.length); // 3;
2356
+ */
2357
+ delete(element) {
2358
+ for (let i = this._offset; i < this.elements.length; i++) {
2359
+ if (Object.is(this.elements[i], element)) {
2360
+ this.elements.splice(i, 1);
2361
+ return true;
2362
+ }
2363
+ }
2364
+ return false;
2365
+ }
2366
+ /**
2367
+ * Get the element at a given logical index.
2368
+ * @remarks Time O(1), Space O(1)
2369
+ * @param index - Zero-based index from the front.
2370
+ * @returns Element or undefined.
2371
+
2372
+
2373
+
2374
+
2375
+
2376
+
2377
+
2378
+
2379
+
2380
+
2381
+
2382
+
2383
+
2384
+
2385
+
2386
+
2387
+
2388
+
2389
+
2390
+
2391
+
2392
+
2393
+
2394
+
2395
+
2396
+
2397
+
2398
+
2399
+
2400
+
2401
+
2402
+
2403
+ * @example
2404
+ * // Access element by index
2405
+ * const q = new Queue<string>(['a', 'b', 'c']);
2406
+ * console.log(q.at(0)); // 'a';
2407
+ * console.log(q.at(2)); // 'c';
2408
+ */
2409
+ at(index) {
2410
+ if (index < 0 || index >= this.length) return void 0;
2411
+ return this._elements[this._offset + index];
2412
+ }
2413
+ /**
2414
+ * Delete the element at a given index.
2415
+ * @remarks Time O(N), Space O(1)
2416
+ * @param index - Zero-based index from the front.
2417
+ * @returns Removed element or undefined.
2418
+ */
2419
+ deleteAt(index) {
2420
+ if (index < 0 || index >= this.length) return void 0;
2421
+ const gi = this._offset + index;
2422
+ const [deleted] = this.elements.splice(gi, 1);
2423
+ return deleted;
2424
+ }
2425
+ /**
2426
+ * Insert a new element at a given index.
2427
+ * @remarks Time O(N), Space O(1)
2428
+ * @param index - Zero-based index from the front.
2429
+ * @param newElement - Element to insert.
2430
+ * @returns True if inserted.
2431
+ */
2432
+ addAt(index, newElement) {
2433
+ if (index < 0 || index > this.length) return false;
2434
+ this._elements.splice(this._offset + index, 0, newElement);
2435
+ return true;
2436
+ }
2437
+ /**
2438
+ * Replace the element at a given index.
2439
+ * @remarks Time O(1), Space O(1)
2440
+ * @param index - Zero-based index from the front.
2441
+ * @param newElement - New element to set.
2442
+ * @returns True if updated.
2443
+ */
2444
+ setAt(index, newElement) {
2445
+ if (index < 0 || index >= this.length) return false;
2446
+ this._elements[this._offset + index] = newElement;
2447
+ return true;
2448
+ }
2449
+ /**
2450
+ * Reverse the queue in-place by compacting then reversing.
2451
+ * @remarks Time O(N), Space O(N)
2452
+ * @returns This queue.
2453
+ */
2454
+ reverse() {
2455
+ this._elements = this.elements.slice(this._offset).reverse();
2456
+ this._offset = 0;
2457
+ return this;
2458
+ }
2459
+ /**
2460
+ * Remove all elements and reset offset.
2461
+ * @remarks Time O(1), Space O(1)
2462
+ * @returns void
2463
+
2464
+
2465
+
2466
+
2467
+
2468
+
2469
+
2470
+
2471
+
2472
+
2473
+
2474
+
2475
+
2476
+
2477
+
2478
+
2479
+
2480
+
2481
+
2482
+
2483
+
2484
+
2485
+
2486
+
2487
+
2488
+
2489
+
2490
+
2491
+
2492
+
2493
+
2494
+
2495
+
2496
+ * @example
2497
+ * // Remove all elements
2498
+ * const q = new Queue<number>([1, 2, 3]);
2499
+ * q.clear();
2500
+ * console.log(q.length); // 0;
2501
+ */
2502
+ clear() {
2503
+ this._elements = [];
2504
+ this._offset = 0;
2505
+ }
2506
+ /**
2507
+ * Compact storage by discarding consumed head elements.
2508
+ * @remarks Time O(N), Space O(N)
2509
+ * @returns True when compaction performed.
2510
+
2511
+
2512
+
2513
+
2514
+
2515
+
2516
+
2517
+
2518
+
2519
+
2520
+
2521
+
2522
+
2523
+
2524
+
2525
+
2526
+
2527
+
2528
+
2529
+
2530
+
2531
+
2532
+
2533
+
2534
+
2535
+
2536
+
2537
+
2538
+
2539
+
2540
+
2541
+
2542
+ * @example
2543
+ * // Reclaim unused memory
2544
+ * const q = new Queue<number>([1, 2, 3, 4, 5]);
2545
+ * q.shift();
2546
+ * q.shift();
2547
+ * q.compact();
2548
+ * console.log(q.length); // 3;
2549
+ */
2550
+ compact() {
2551
+ this._elements = this.elements.slice(this._offset);
2552
+ this._offset = 0;
2553
+ return true;
2554
+ }
2555
+ /**
2556
+ * Remove and/or insert elements at a position (array-like).
2557
+ * @remarks Time O(N + M), Space O(M)
2558
+ * @param start - Start index (clamped to [0, length]).
2559
+ * @param [deleteCount] - Number of elements to remove (default 0).
2560
+ * @param [items] - Elements to insert after `start`.
2561
+ * @returns A new queue containing the removed elements (typed as `this`).
2562
+ */
2563
+ splice(start, deleteCount = 0, ...items) {
2564
+ start = Math.max(0, Math.min(start, this.length));
2565
+ deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
2566
+ const gi = this._offset + start;
2567
+ const removedArray = this._elements.splice(gi, deleteCount, ...items);
2568
+ if (this.elements.length > 0 && this.offset / this.elements.length > this.autoCompactRatio) this.compact();
2569
+ const removed = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
2570
+ removed._setAutoCompactRatio(this._autoCompactRatio);
2571
+ removed.pushMany(removedArray);
2572
+ return removed;
2573
+ }
2574
+ /**
2575
+ * Deep clone this queue and its parameters.
2576
+ * @remarks Time O(N), Space O(N)
2577
+ * @returns A new queue with the same content and options.
2578
+
2579
+
2580
+
2581
+
2582
+
2583
+
2584
+
2585
+
2586
+
2587
+
2588
+
2589
+
2590
+
2591
+
2592
+
2593
+
2594
+
2595
+
2596
+
2597
+
2598
+
2599
+
2600
+
2601
+
2602
+
2603
+
2604
+
2605
+
2606
+
2607
+
2608
+
2609
+
2610
+
2611
+ * @example
2612
+ * // Create independent copy
2613
+ * const q = new Queue<number>([1, 2, 3]);
2614
+ * const copy = q.clone();
2615
+ * copy.shift();
2616
+ * console.log(q.length); // 3;
2617
+ * console.log(copy.length); // 2;
2618
+ */
2619
+ clone() {
2620
+ const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
2621
+ out._setAutoCompactRatio(this._autoCompactRatio);
2622
+ for (let i = this._offset; i < this.elements.length; i++) out.push(this.elements[i]);
2623
+ return out;
2624
+ }
2625
+ /**
2626
+ * Filter elements into a new queue of the same class.
2627
+ * @remarks Time O(N), Space O(N)
2628
+ * @param predicate - Predicate (element, index, queue) → boolean to keep element.
2629
+ * @param [thisArg] - Value for `this` inside the predicate.
2630
+ * @returns A new queue with kept elements.
2631
+
2632
+
2633
+
2634
+
2635
+
2636
+
2637
+
2638
+
2639
+
2640
+
2641
+
2642
+
2643
+
2644
+
2645
+
2646
+
2647
+
2648
+
2649
+
2650
+
2651
+
2652
+
2653
+
2654
+
2655
+
2656
+
2657
+
2658
+
2659
+
2660
+
2661
+
2662
+
2663
+
2664
+ * @example
2665
+ * // Filter elements
2666
+ * const q = new Queue<number>([1, 2, 3, 4, 5]);
2667
+ * const evens = q.filter(x => x % 2 === 0);
2668
+ * console.log(evens.length); // 2;
2669
+ */
2670
+ filter(predicate, thisArg) {
2671
+ const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
2672
+ out._setAutoCompactRatio(this._autoCompactRatio);
2673
+ let index = 0;
2674
+ for (const v of this) {
2675
+ if (predicate.call(thisArg, v, index, this)) out.push(v);
2676
+ index++;
2677
+ }
2678
+ return out;
2679
+ }
2680
+ /**
2681
+ * Map each element to a new element in a possibly different-typed queue.
2682
+ * @remarks Time O(N), Space O(N)
2683
+ * @template EM
2684
+ * @template RM
2685
+ * @param callback - Mapping function (element, index, queue) → newElement.
2686
+ * @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
2687
+ * @param [thisArg] - Value for `this` inside the callback.
2688
+ * @returns A new Queue with mapped elements.
2689
+
2690
+
2691
+
2692
+
2693
+
2694
+
2695
+
2696
+
2697
+
2698
+
2699
+
2700
+
2701
+
2702
+
2703
+
2704
+
2705
+
2706
+
2707
+
2708
+
2709
+
2710
+
2711
+
2712
+
2713
+
2714
+
2715
+
2716
+
2717
+
2718
+
2719
+
2720
+
2721
+ * @example
2722
+ * // Transform elements
2723
+ * const q = new Queue<number>([1, 2, 3]);
2724
+ * const doubled = q.map(x => x * 2);
2725
+ * console.log(doubled.toArray()); // [2, 4, 6];
2726
+ */
2727
+ map(callback, options, thisArg) {
2728
+ var _a, _b;
2729
+ const out = new this.constructor([], {
2730
+ toElementFn: options == null ? void 0 : options.toElementFn,
2731
+ maxLen: (_a = options == null ? void 0 : options.maxLen) != null ? _a : this._maxLen,
2732
+ autoCompactRatio: (_b = options == null ? void 0 : options.autoCompactRatio) != null ? _b : this._autoCompactRatio
2733
+ });
2734
+ let index = 0;
2735
+ for (const v of this)
2736
+ out.push(thisArg === void 0 ? callback(v, index++, this) : callback.call(thisArg, v, index++, this));
2737
+ return out;
2738
+ }
2739
+ /**
2740
+ * Map each element to a new value of the same type.
2741
+ * @remarks Time O(N), Space O(N)
2742
+ * @param callback - Mapping function (element, index, queue) → element.
2743
+ * @param [thisArg] - Value for `this` inside the callback.
2744
+ * @returns A new queue with mapped elements (same element type).
2745
+ */
2746
+ mapSame(callback, thisArg) {
2747
+ var _a;
2748
+ const Ctor = this.constructor;
2749
+ const out = new Ctor([], {
2750
+ toElementFn: this.toElementFn,
2751
+ maxLen: this._maxLen,
2752
+ autoCompactRatio: this._autoCompactRatio
2753
+ });
2754
+ (_a = out._setAutoCompactRatio) == null ? void 0 : _a.call(out, this._autoCompactRatio);
2755
+ let index = 0;
2756
+ for (const v of this) {
2757
+ const mv = thisArg === void 0 ? callback(v, index++, this) : callback.call(thisArg, v, index++, this);
2758
+ out.push(mv);
2759
+ }
2760
+ return out;
2761
+ }
2762
+ /**
2763
+ * (Protected) Set the internal auto-compaction ratio.
2764
+ * @remarks Time O(1), Space O(1)
2765
+ * @param value - New ratio to assign.
2766
+ * @returns void
2767
+ */
2768
+ _setAutoCompactRatio(value) {
2769
+ this._autoCompactRatio = value;
2770
+ }
2771
+ /**
2772
+ * (Protected) Iterate elements from front to back.
2773
+ * @remarks Time O(N), Space O(1)
2774
+ * @returns Iterator of E.
2775
+ */
2776
+ *_getIterator() {
2777
+ for (let i = this._offset; i < this.elements.length; i++) yield this.elements[i];
2778
+ }
2779
+ /**
2780
+ * (Protected) Iterate elements from back to front.
2781
+ * @remarks Time O(N), Space O(1)
2782
+ * @returns Iterator of E.
2783
+ */
2784
+ *_getReverseIterator() {
2785
+ for (let i = this.length - 1; i >= 0; i--) {
2786
+ const cur = this.at(i);
2787
+ if (cur !== void 0) yield cur;
2788
+ }
2789
+ }
2790
+ /**
2791
+ * (Protected) Create an empty instance of the same concrete class.
2792
+ * @remarks Time O(1), Space O(1)
2793
+ * @param [options] - Options forwarded to the constructor.
2794
+ * @returns An empty like-kind queue instance.
2795
+ */
2796
+ _createInstance(options) {
2797
+ const Ctor = this.constructor;
2798
+ return new Ctor([], options);
2799
+ }
2800
+ /**
2801
+ * (Protected) Create a like-kind queue and seed it from an iterable.
2802
+ * @remarks Time O(N), Space O(N)
2803
+ * @template EM
2804
+ * @template RM
2805
+ * @param [elements] - Iterable used to seed the new queue.
2806
+ * @param [options] - Options forwarded to the constructor.
2807
+ * @returns A like-kind Queue instance.
2808
+ */
2809
+ _createLike(elements = [], options) {
2810
+ const Ctor = this.constructor;
2811
+ return new Ctor(elements, options);
2812
+ }
2813
+ };
2814
+ __name(_Queue, "Queue");
2815
+ var Queue = _Queue;
2816
+ var _LinkedListQueue = class _LinkedListQueue extends SinglyLinkedList {
2817
+ /**
2818
+ * Deep clone this linked-list-based queue.
2819
+ * @remarks Time O(N), Space O(N)
2820
+ * @returns A new queue with the same sequence of elements.
2821
+ */
2822
+ clone() {
2823
+ const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
2824
+ for (const v of this) out.push(v);
2825
+ return out;
2826
+ }
2827
+ };
2828
+ __name(_LinkedListQueue, "LinkedListQueue");
2829
+ var LinkedListQueue = _LinkedListQueue;
2830
+
2831
+ // src/utils/utils.ts
2832
+ var rangeCheck = /* @__PURE__ */ __name((index, min, max, message) => {
2833
+ if (index < min || index > max) {
2834
+ throw new RangeError(message != null ? message : `Index ${index} is out of range [${min}, ${max}].`);
2835
+ }
2836
+ }, "rangeCheck");
2837
+ var calcMinUnitsRequired = /* @__PURE__ */ __name((totalQuantity, unitSize) => Math.floor((totalQuantity + unitSize - 1) / unitSize), "calcMinUnitsRequired");
2838
+
2839
+ // src/data-structures/queue/deque.ts
2840
+ var _Deque = class _Deque extends LinearBase {
2841
+ constructor(elements = [], options) {
2842
+ super(options);
2843
+ __publicField(this, "_equals", /* @__PURE__ */ __name((a, b) => Object.is(a, b), "_equals"));
2844
+ __publicField(this, "_bucketSize", 1 << 12);
2845
+ __publicField(this, "_autoCompactRatio", 0.5);
2846
+ /**
2847
+ * Counter for shift/pop operations since last compaction check.
2848
+ * Only checks ratio every `_bucketSize` operations to minimize overhead.
2849
+ */
2850
+ __publicField(this, "_compactCounter", 0);
2851
+ __publicField(this, "_bucketFirst", 0);
2852
+ __publicField(this, "_firstInBucket", 0);
2853
+ __publicField(this, "_bucketLast", 0);
2854
+ __publicField(this, "_lastInBucket", 0);
2855
+ __publicField(this, "_bucketCount", 0);
2856
+ __publicField(this, "_buckets", []);
2857
+ __publicField(this, "_length", 0);
2858
+ if (options) {
2859
+ const { bucketSize, autoCompactRatio } = options;
2860
+ if (typeof bucketSize === "number") this._bucketSize = bucketSize;
2861
+ if (typeof autoCompactRatio === "number") this._autoCompactRatio = autoCompactRatio;
2862
+ }
2863
+ let _size;
2864
+ if ("length" in elements) {
2865
+ _size = typeof elements.length === "function" ? elements.length() : elements.length;
2866
+ } else {
2867
+ _size = typeof elements.size === "function" ? elements.size() : elements.size;
2868
+ }
2869
+ this._bucketCount = calcMinUnitsRequired(_size, this._bucketSize) || 1;
2870
+ for (let i = 0; i < this._bucketCount; ++i) {
2871
+ this._buckets.push(new Array(this._bucketSize));
2872
+ }
2873
+ const needBucketNum = calcMinUnitsRequired(_size, this._bucketSize);
2874
+ this._bucketFirst = this._bucketLast = (this._bucketCount >> 1) - (needBucketNum >> 1);
2875
+ this._firstInBucket = this._lastInBucket = this._bucketSize - _size % this._bucketSize >> 1;
2876
+ this.pushMany(elements);
2877
+ }
2878
+ /**
2879
+ * Get the current bucket size.
2880
+ * @remarks Time O(1), Space O(1)
2881
+ * @returns Bucket capacity per bucket.
2882
+ */
2883
+ get bucketSize() {
2884
+ return this._bucketSize;
2885
+ }
2886
+ /**
2887
+ * Get the auto-compaction ratio.
2888
+ * When `elements / (bucketCount * bucketSize)` drops below this ratio after
2889
+ * enough shift/pop operations, the deque auto-compacts.
2890
+ * @remarks Time O(1), Space O(1)
2891
+ * @returns Current ratio threshold. 0 means auto-compact is disabled.
2892
+ */
2893
+ get autoCompactRatio() {
2894
+ return this._autoCompactRatio;
2895
+ }
2896
+ /**
2897
+ * Set the auto-compaction ratio.
2898
+ * @remarks Time O(1), Space O(1)
2899
+ * @param value - Ratio in [0,1]. 0 disables auto-compact.
2900
+ */
2901
+ set autoCompactRatio(value) {
2902
+ this._autoCompactRatio = value;
2903
+ }
2904
+ /**
2905
+ * Get the index of the first bucket in use.
2906
+ * @remarks Time O(1), Space O(1)
2907
+ * @returns Zero-based bucket index.
2908
+ */
2909
+ get bucketFirst() {
2910
+ return this._bucketFirst;
2911
+ }
2912
+ /**
2913
+ * Get the index inside the first bucket.
2914
+ * @remarks Time O(1), Space O(1)
2915
+ * @returns Zero-based index within the first bucket.
2916
+ */
2917
+ get firstInBucket() {
2918
+ return this._firstInBucket;
2919
+ }
2920
+ /**
2921
+ * Get the index of the last bucket in use.
2922
+ * @remarks Time O(1), Space O(1)
2923
+ * @returns Zero-based bucket index.
2924
+ */
2925
+ get bucketLast() {
2926
+ return this._bucketLast;
2927
+ }
2928
+ /**
2929
+ * Get the index inside the last bucket.
2930
+ * @remarks Time O(1), Space O(1)
2931
+ * @returns Zero-based index within the last bucket.
2932
+ */
2933
+ get lastInBucket() {
2934
+ return this._lastInBucket;
2935
+ }
2936
+ /**
2937
+ * Get the number of buckets allocated.
2938
+ * @remarks Time O(1), Space O(1)
2939
+ * @returns Bucket count.
2940
+ */
2941
+ get bucketCount() {
2942
+ return this._bucketCount;
2943
+ }
2944
+ /**
2945
+ * Get the internal buckets array.
2946
+ * @remarks Time O(1), Space O(1)
2947
+ * @returns Array of buckets storing values.
2948
+ */
2949
+ get buckets() {
2950
+ return this._buckets;
2951
+ }
2952
+ /**
2953
+ * Get the number of elements in the deque.
2954
+ * @remarks Time O(1), Space O(1)
2955
+ * @returns Current length.
2956
+ */
2957
+ get length() {
2958
+ return this._length;
2959
+ }
2960
+ /**
2961
+ * Get the first element without removing it.
2962
+ * @remarks Time O(1), Space O(1)
2963
+ * @returns First element or undefined.
2964
+
2965
+
2966
+
2967
+
2968
+
2969
+
2970
+
2971
+
2972
+
2973
+
2974
+
2975
+
2976
+
2977
+
2978
+
2979
+
2980
+
2981
+
2982
+
2983
+
2984
+
2985
+
2986
+
2987
+
2988
+
2989
+
2990
+
2991
+
2992
+
2993
+
2994
+
2995
+
2996
+
2997
+
2998
+
2999
+ * @example
3000
+ * // Deque peek at both ends
3001
+ * const deque = new Deque<number>([10, 20, 30, 40, 50]);
3002
+ *
3003
+ * // Get first element without removing
3004
+ * const first = deque.at(0);
3005
+ * console.log(first); // 10;
3006
+ *
3007
+ * // Get last element without removing
3008
+ * const last = deque.at(deque.length - 1);
3009
+ * console.log(last); // 50;
3010
+ *
3011
+ * // Length unchanged
3012
+ * console.log(deque.length); // 5;
3013
+ */
3014
+ get first() {
3015
+ if (this._length === 0) return;
3016
+ return this._buckets[this._bucketFirst][this._firstInBucket];
3017
+ }
3018
+ /**
3019
+ * Get the last element without removing it.
3020
+ * @remarks Time O(1), Space O(1)
3021
+ * @returns Last element or undefined.
3022
+
3023
+
3024
+
3025
+
3026
+
3027
+
3028
+
3029
+
3030
+
3031
+
3032
+
3033
+
3034
+
3035
+
3036
+
3037
+
3038
+
3039
+
3040
+
3041
+
3042
+
3043
+
3044
+
3045
+
3046
+
3047
+
3048
+
3049
+
3050
+
3051
+
3052
+
3053
+
3054
+
3055
+
3056
+
3057
+ * @example
3058
+ * // Peek at the back element
3059
+ * const dq = new Deque<string>(['a', 'b', 'c']);
3060
+ * console.log(dq.last); // 'c';
3061
+ * console.log(dq.first); // 'a';
3062
+ */
3063
+ get last() {
3064
+ if (this._length === 0) return;
3065
+ return this._buckets[this._bucketLast][this._lastInBucket];
3066
+ }
3067
+ /**
3068
+ * Create a Deque from an array of elements.
3069
+ * @remarks Time O(N), Space O(N)
3070
+ * @template E
3071
+ * @template R
3072
+ * @param this - Constructor (subclass) to instantiate.
3073
+ * @param data - Array of elements to insert in order.
3074
+ * @param [options] - Options forwarded to the constructor.
3075
+ * @returns A new Deque populated from the array.
3076
+ */
3077
+ static fromArray(data, options) {
3078
+ return new this(data, options);
3079
+ }
3080
+ /**
3081
+ * Append one element at the back.
3082
+ * @remarks Time O(1) amortized, Space O(1)
3083
+ * @param element - Element to append.
3084
+ * @returns True when appended.
3085
+
3086
+
3087
+
3088
+
3089
+
3090
+
3091
+
3092
+
3093
+
3094
+
3095
+
3096
+
3097
+
3098
+
3099
+
3100
+
3101
+
3102
+
3103
+
3104
+
3105
+
3106
+
3107
+
3108
+
3109
+
3110
+
3111
+
3112
+
3113
+
3114
+
3115
+
3116
+
3117
+
3118
+
3119
+
3120
+ * @example
3121
+ * // basic Deque creation and push/pop operations
3122
+ * // Create a simple Deque with initial values
3123
+ * const deque = new Deque([1, 2, 3, 4, 5]);
3124
+ *
3125
+ * // Verify the deque maintains insertion order
3126
+ * console.log([...deque]); // [1, 2, 3, 4, 5];
3127
+ *
3128
+ * // Check length
3129
+ * console.log(deque.length); // 5;
3130
+ *
3131
+ * // Push to the end
3132
+ * deque.push(6);
3133
+ * console.log(deque.length); // 6;
3134
+ *
3135
+ * // Pop from the end
3136
+ * const last = deque.pop();
3137
+ * console.log(last); // 6;
3138
+ */
3139
+ push(element) {
3140
+ if (this._length) {
3141
+ if (this._lastInBucket < this._bucketSize - 1) {
3142
+ this._lastInBucket += 1;
3143
+ } else if (this._bucketLast < this._bucketCount - 1) {
3144
+ this._bucketLast += 1;
3145
+ this._lastInBucket = 0;
3146
+ } else {
3147
+ this._bucketLast = 0;
3148
+ this._lastInBucket = 0;
3149
+ }
3150
+ if (this._bucketLast === this._bucketFirst && this._lastInBucket === this._firstInBucket) this._reallocate();
3151
+ }
3152
+ this._length += 1;
3153
+ this._buckets[this._bucketLast][this._lastInBucket] = element;
3154
+ if (this._maxLen > 0 && this._length > this._maxLen) this.shift();
3155
+ return true;
3156
+ }
3157
+ /**
3158
+ * Remove and return the last element.
3159
+ * @remarks Time O(1), Space O(1)
3160
+ * @returns Removed element or undefined.
3161
+
3162
+
3163
+
3164
+
3165
+
3166
+
3167
+
3168
+
3169
+
3170
+
3171
+
3172
+
3173
+
3174
+
3175
+
3176
+
3177
+
3178
+
3179
+
3180
+
3181
+
3182
+
3183
+
3184
+
3185
+
3186
+
3187
+
3188
+
3189
+
3190
+
3191
+
3192
+
3193
+
3194
+
3195
+
3196
+ * @example
3197
+ * // Remove from the back
3198
+ * const dq = new Deque<number>([1, 2, 3]);
3199
+ * console.log(dq.pop()); // 3;
3200
+ * console.log(dq.length); // 2;
3201
+ */
3202
+ pop() {
3203
+ if (this._length === 0) return;
3204
+ const element = this._buckets[this._bucketLast][this._lastInBucket];
3205
+ if (this._length !== 1) {
3206
+ if (this._lastInBucket > 0) {
3207
+ this._lastInBucket -= 1;
3208
+ } else if (this._bucketLast > 0) {
3209
+ this._bucketLast -= 1;
3210
+ this._lastInBucket = this._bucketSize - 1;
3211
+ } else {
3212
+ this._bucketLast = this._bucketCount - 1;
3213
+ this._lastInBucket = this._bucketSize - 1;
3214
+ }
3215
+ }
3216
+ this._length -= 1;
3217
+ this._autoCompact();
3218
+ return element;
3219
+ }
3220
+ /**
3221
+ * Remove and return the first element.
3222
+ * @remarks Time O(1) amortized, Space O(1)
3223
+ * @returns Removed element or undefined.
3224
+
3225
+
3226
+
3227
+
3228
+
3229
+
3230
+
3231
+
3232
+
3233
+
3234
+
3235
+
3236
+
3237
+
3238
+
3239
+
3240
+
3241
+
3242
+
3243
+
3244
+
3245
+
3246
+
3247
+
3248
+
3249
+
3250
+
3251
+
3252
+
3253
+
3254
+
3255
+
3256
+
3257
+
3258
+
3259
+ * @example
3260
+ * // Remove from the front
3261
+ * const dq = new Deque<number>([1, 2, 3]);
3262
+ * console.log(dq.shift()); // 1;
3263
+ * console.log(dq.length); // 2;
3264
+ */
3265
+ shift() {
3266
+ if (this._length === 0) return;
3267
+ const element = this._buckets[this._bucketFirst][this._firstInBucket];
3268
+ if (this._length !== 1) {
3269
+ if (this._firstInBucket < this._bucketSize - 1) {
3270
+ this._firstInBucket += 1;
3271
+ } else if (this._bucketFirst < this._bucketCount - 1) {
3272
+ this._bucketFirst += 1;
3273
+ this._firstInBucket = 0;
3274
+ } else {
3275
+ this._bucketFirst = 0;
3276
+ this._firstInBucket = 0;
3277
+ }
3278
+ }
3279
+ this._length -= 1;
3280
+ this._autoCompact();
3281
+ return element;
3282
+ }
3283
+ /**
3284
+ * Prepend one element at the front.
3285
+ * @remarks Time O(1) amortized, Space O(1)
3286
+ * @param element - Element to prepend.
3287
+ * @returns True when prepended.
3288
+
3289
+
3290
+
3291
+
3292
+
3293
+
3294
+
3295
+
3296
+
3297
+
3298
+
3299
+
3300
+
3301
+
3302
+
3303
+
3304
+
3305
+
3306
+
3307
+
3308
+
3309
+
3310
+
3311
+
3312
+
3313
+
3314
+
3315
+
3316
+
3317
+
3318
+
3319
+
3320
+
3321
+
3322
+
3323
+ * @example
3324
+ * // Deque shift and unshift operations
3325
+ * const deque = new Deque<number>([20, 30, 40]);
3326
+ *
3327
+ * // Unshift adds to the front
3328
+ * deque.unshift(10);
3329
+ * console.log([...deque]); // [10, 20, 30, 40];
3330
+ *
3331
+ * // Shift removes from the front (O(1) complexity!)
3332
+ * const first = deque.shift();
3333
+ * console.log(first); // 10;
3334
+ *
3335
+ * // Verify remaining elements
3336
+ * console.log([...deque]); // [20, 30, 40];
3337
+ * console.log(deque.length); // 3;
3338
+ */
3339
+ unshift(element) {
3340
+ if (this._length) {
3341
+ if (this._firstInBucket > 0) {
3342
+ this._firstInBucket -= 1;
3343
+ } else if (this._bucketFirst > 0) {
3344
+ this._bucketFirst -= 1;
3345
+ this._firstInBucket = this._bucketSize - 1;
3346
+ } else {
3347
+ this._bucketFirst = this._bucketCount - 1;
3348
+ this._firstInBucket = this._bucketSize - 1;
3349
+ }
3350
+ if (this._bucketFirst === this._bucketLast && this._firstInBucket === this._lastInBucket) this._reallocate();
3351
+ }
3352
+ this._length += 1;
3353
+ this._buckets[this._bucketFirst][this._firstInBucket] = element;
3354
+ if (this._maxLen > 0 && this._length > this._maxLen) this.pop();
3355
+ return true;
3356
+ }
3357
+ /**
3358
+ * Append a sequence of elements.
3359
+ * @remarks Time O(N), Space O(1)
3360
+ * @param elements - Iterable (or iterable-like) of elements/records.
3361
+ * @returns Array of per-element success flags.
3362
+ */
3363
+ pushMany(elements) {
3364
+ const ans = [];
3365
+ for (const el of elements) {
3366
+ if (this.toElementFn) {
3367
+ ans.push(this.push(this.toElementFn(el)));
3368
+ } else {
3369
+ ans.push(this.push(el));
3370
+ }
3371
+ }
3372
+ return ans;
3373
+ }
3374
+ /**
3375
+ * Prepend a sequence of elements.
3376
+ * @remarks Time O(N), Space O(1)
3377
+ * @param [elements] - Iterable (or iterable-like) of elements/records.
3378
+ * @returns Array of per-element success flags.
3379
+ */
3380
+ unshiftMany(elements = []) {
3381
+ const ans = [];
3382
+ for (const el of elements) {
3383
+ if (this.toElementFn) {
3384
+ ans.push(this.unshift(this.toElementFn(el)));
3385
+ } else {
3386
+ ans.push(this.unshift(el));
3387
+ }
3388
+ }
3389
+ return ans;
3390
+ }
3391
+ /**
3392
+ * Check whether the deque is empty.
3393
+ * @remarks Time O(1), Space O(1)
3394
+ * @returns True if length is 0.
3395
+
3396
+
3397
+
3398
+
3399
+
3400
+
3401
+
3402
+
3403
+
3404
+
3405
+
3406
+
3407
+
3408
+
3409
+
3410
+
3411
+
3412
+
3413
+
3414
+
3415
+
3416
+
3417
+
3418
+
3419
+
3420
+
3421
+
3422
+
3423
+
3424
+
3425
+
3426
+
3427
+
3428
+ * @example
3429
+ * // Check if empty
3430
+ * const dq = new Deque();
3431
+ * console.log(dq.isEmpty()); // true;
3432
+ */
3433
+ isEmpty() {
3434
+ return this._length === 0;
3435
+ }
3436
+ /**
3437
+ * Remove all elements and reset structure.
3438
+ * @remarks Time O(1), Space O(1)
3439
+ * @returns void
3440
+
3441
+
3442
+
3443
+
3444
+
3445
+
3446
+
3447
+
3448
+
3449
+
3450
+
3451
+
3452
+
3453
+
3454
+
3455
+
3456
+
3457
+
3458
+
3459
+
3460
+
3461
+
3462
+
3463
+
3464
+
3465
+
3466
+
3467
+
3468
+
3469
+
3470
+
3471
+
3472
+
3473
+ * @example
3474
+ * // Remove all elements
3475
+ * const dq = new Deque<number>([1, 2, 3]);
3476
+ * dq.clear();
3477
+ * console.log(dq.length); // 0;
3478
+ */
3479
+ clear() {
3480
+ this._buckets = [new Array(this._bucketSize)];
3481
+ this._bucketCount = 1;
3482
+ this._bucketFirst = this._bucketLast = this._length = 0;
3483
+ this._firstInBucket = this._lastInBucket = this._bucketSize >> 1;
3484
+ }
3485
+ /**
3486
+ * Get the element at a given position.
3487
+ * @remarks Time O(1), Space O(1)
3488
+ * @param pos - Zero-based position from the front.
3489
+ * @returns Element or undefined.
3490
+
3491
+
3492
+
3493
+
3494
+
3495
+
3496
+
3497
+
3498
+
3499
+
3500
+
3501
+
3502
+
3503
+
3504
+
3505
+
3506
+
3507
+
3508
+
3509
+
3510
+
3511
+
3512
+
3513
+
3514
+
3515
+
3516
+
3517
+
3518
+
3519
+
3520
+
3521
+
3522
+ * @example
3523
+ * // Access by index
3524
+ * const dq = new Deque<string>(['a', 'b', 'c']);
3525
+ * console.log(dq.at(0)); // 'a';
3526
+ * console.log(dq.at(2)); // 'c';
3527
+ */
3528
+ at(pos) {
3529
+ if (pos < 0 || pos >= this._length) return void 0;
3530
+ const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);
3531
+ return this._buckets[bucketIndex][indexInBucket];
3532
+ }
3533
+ /**
3534
+ * Replace the element at a given position.
3535
+ * @remarks Time O(1), Space O(1)
3536
+ * @param pos - Zero-based position from the front.
3537
+ * @param element - New element value.
3538
+ * @returns True if updated.
3539
+ */
3540
+ setAt(pos, element) {
3541
+ rangeCheck(pos, 0, this._length - 1);
3542
+ const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);
3543
+ this._buckets[bucketIndex][indexInBucket] = element;
3544
+ return true;
3545
+ }
3546
+ /**
3547
+ * Insert repeated copies of an element at a position.
3548
+ * @remarks Time O(N), Space O(1)
3549
+ * @param pos - Zero-based position from the front.
3550
+ * @param element - Element to insert.
3551
+ * @param [num] - Number of times to insert (default 1).
3552
+ * @returns True if inserted.
3553
+ */
3554
+ addAt(pos, element, num = 1) {
3555
+ const length = this._length;
3556
+ rangeCheck(pos, 0, length);
3557
+ if (pos === 0) {
3558
+ while (num--) this.unshift(element);
3559
+ } else if (pos === this._length) {
3560
+ while (num--) this.push(element);
3561
+ } else {
3562
+ const arr = [];
3563
+ for (let i = pos; i < this._length; ++i) {
3564
+ const v = this.at(i);
3565
+ if (v !== void 0) arr.push(v);
3566
+ }
3567
+ this.cut(pos - 1, true);
3568
+ for (let i = 0; i < num; ++i) this.push(element);
3569
+ for (let i = 0; i < arr.length; ++i) this.push(arr[i]);
3570
+ }
3571
+ return true;
3572
+ }
3573
+ /**
3574
+ * Cut the deque to keep items up to index; optionally mutate in-place.
3575
+ * @remarks Time O(N), Space O(1)
3576
+ * @param pos - Last index to keep.
3577
+ * @param [isCutSelf] - When true, mutate this deque; otherwise return a new deque.
3578
+ * @returns This deque if in-place; otherwise a new deque of the prefix.
3579
+ */
3580
+ cut(pos, isCutSelf = false) {
3581
+ if (isCutSelf) {
3582
+ if (pos < 0) {
3583
+ this.clear();
3584
+ return this;
3585
+ }
3586
+ const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);
3587
+ this._bucketLast = bucketIndex;
3588
+ this._lastInBucket = indexInBucket;
3589
+ this._length = pos + 1;
3590
+ return this;
3591
+ } else {
3592
+ const newDeque = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
3593
+ newDeque._setBucketSize(this._bucketSize);
3594
+ for (let i = 0; i <= pos; i++) {
3595
+ const v = this.at(i);
3596
+ if (v !== void 0) newDeque.push(v);
3597
+ }
3598
+ return newDeque;
3599
+ }
3600
+ }
3601
+ /**
3602
+ * Remove and/or insert elements at a position (array-like behavior).
3603
+ * @remarks Time O(N + M), Space O(M)
3604
+ * @param start - Start index (clamped to [0, length]).
3605
+ * @param [deleteCount] - Number of elements to remove (default: length - start).
3606
+ * @param [items] - Elements to insert after `start`.
3607
+ * @returns A new deque containing the removed elements (typed as `this`).
3608
+ */
3609
+ splice(start, deleteCount = this._length - start, ...items) {
3610
+ rangeCheck(start, 0, this._length);
3611
+ if (deleteCount < 0) deleteCount = 0;
3612
+ if (start + deleteCount > this._length) deleteCount = this._length - start;
3613
+ const removed = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
3614
+ removed._setBucketSize(this._bucketSize);
3615
+ for (let i = 0; i < deleteCount; i++) {
3616
+ const v = this.at(start + i);
3617
+ if (v !== void 0) removed.push(v);
3618
+ }
3619
+ const tail = [];
3620
+ for (let i = start + deleteCount; i < this._length; i++) {
3621
+ const v = this.at(i);
3622
+ if (v !== void 0) tail.push(v);
3623
+ }
3624
+ this.cut(start - 1, true);
3625
+ for (const it of items) this.push(it);
3626
+ for (const v of tail) this.push(v);
3627
+ return removed;
3628
+ }
3629
+ /**
3630
+ * Cut the deque to keep items from index onward; optionally mutate in-place.
3631
+ * @remarks Time O(N), Space O(1)
3632
+ * @param pos - First index to keep.
3633
+ * @param [isCutSelf] - When true, mutate this deque; otherwise return a new deque.
3634
+ * @returns This deque if in-place; otherwise a new deque of the suffix.
3635
+ */
3636
+ cutRest(pos, isCutSelf = false) {
3637
+ if (isCutSelf) {
3638
+ if (pos < 0) {
3639
+ return this;
3640
+ }
3641
+ const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);
3642
+ this._bucketFirst = bucketIndex;
3643
+ this._firstInBucket = indexInBucket;
3644
+ this._length = this._length - pos;
3645
+ return this;
3646
+ } else {
3647
+ const newDeque = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
3648
+ newDeque._setBucketSize(this._bucketSize);
3649
+ if (pos < 0) pos = 0;
3650
+ for (let i = pos; i < this._length; i++) {
3651
+ const v = this.at(i);
3652
+ if (v !== void 0) newDeque.push(v);
3653
+ }
3654
+ return newDeque;
3655
+ }
3656
+ }
3657
+ /**
3658
+ * Delete the element at a given position.
3659
+ * @remarks Time O(N), Space O(1)
3660
+ * @param pos - Zero-based position from the front.
3661
+ * @returns Removed element or undefined.
3662
+ */
3663
+ deleteAt(pos) {
3664
+ rangeCheck(pos, 0, this._length - 1);
3665
+ let deleted;
3666
+ if (pos === 0) {
3667
+ return this.shift();
3668
+ } else if (pos === this._length - 1) {
3669
+ deleted = this.last;
3670
+ this.pop();
3671
+ return deleted;
3672
+ } else {
3673
+ const length = this._length - 1;
3674
+ const { bucketIndex: targetBucket, indexInBucket: targetPointer } = this._getBucketAndPosition(pos);
3675
+ deleted = this._buckets[targetBucket][targetPointer];
3676
+ for (let i = pos; i < length; i++) {
3677
+ const { bucketIndex: curBucket, indexInBucket: curPointer } = this._getBucketAndPosition(i);
3678
+ const { bucketIndex: nextBucket, indexInBucket: nextPointer } = this._getBucketAndPosition(i + 1);
3679
+ this._buckets[curBucket][curPointer] = this._buckets[nextBucket][nextPointer];
3680
+ }
3681
+ this.pop();
3682
+ return deleted;
3683
+ }
3684
+ }
3685
+ /**
3686
+ * Delete the first occurrence of a value.
3687
+ * @remarks Time O(N), Space O(1)
3688
+ * @param element - Element to remove (using the configured equality).
3689
+ * @returns True if an element was removed.
3690
+
3691
+
3692
+
3693
+
3694
+
3695
+
3696
+
3697
+
3698
+
3699
+
3700
+
3701
+
3702
+
3703
+
3704
+
3705
+
3706
+
3707
+
3708
+
3709
+
3710
+
3711
+
3712
+
3713
+
3714
+
3715
+
3716
+
3717
+
3718
+
3719
+
3720
+
3721
+
3722
+ * @example
3723
+ * // Remove element
3724
+ * const dq = new Deque<number>([1, 2, 3]);
3725
+ * dq.delete(2);
3726
+ * console.log(dq.length); // 2;
3727
+ */
3728
+ delete(element) {
3729
+ const size = this._length;
3730
+ if (size === 0) return false;
3731
+ let i = 0;
3732
+ let index = 0;
3733
+ while (i < size) {
3734
+ const oldElement = this.at(i);
3735
+ if (!this._equals(oldElement, element)) {
3736
+ this.setAt(index, oldElement);
3737
+ index += 1;
3738
+ }
3739
+ i += 1;
3740
+ }
3741
+ this.cut(index - 1, true);
3742
+ return true;
3743
+ }
3744
+ /**
3745
+ * Delete the first element matching a predicate.
3746
+ * @remarks Time O(N), Space O(1)
3747
+ * @param predicate - Function (value, index, deque) → boolean.
3748
+ * @returns True if a match was removed.
3749
+ */
3750
+ deleteWhere(predicate) {
3751
+ for (let i = 0; i < this._length; i++) {
3752
+ const v = this.at(i);
3753
+ if (predicate(v, i, this)) {
3754
+ this.deleteAt(i);
3755
+ return true;
3756
+ }
3757
+ }
3758
+ return false;
3759
+ }
3760
+ /**
3761
+ * Set the equality comparator used by delete operations.
3762
+ * @remarks Time O(1), Space O(1)
3763
+ * @param equals - Equality predicate (a, b) → boolean.
3764
+ * @returns This deque.
3765
+ */
3766
+ setEquality(equals) {
3767
+ this._equals = equals;
3768
+ return this;
3769
+ }
3770
+ /**
3771
+ * Reverse the deque by reversing buckets and pointers.
3772
+ * @remarks Time O(N), Space O(N)
3773
+ * @returns This deque.
3774
+
3775
+
3776
+
3777
+
3778
+
3779
+
3780
+
3781
+
3782
+
3783
+
3784
+
3785
+
3786
+
3787
+
3788
+
3789
+
3790
+
3791
+
3792
+
3793
+
3794
+
3795
+
3796
+
3797
+
3798
+
3799
+
3800
+
3801
+
3802
+
3803
+
3804
+
3805
+
3806
+
3807
+
3808
+
3809
+ * @example
3810
+ * // Deque for...of iteration and reverse
3811
+ * const deque = new Deque<string>(['A', 'B', 'C', 'D']);
3812
+ *
3813
+ * // Iterate forward
3814
+ * const forward: string[] = [];
3815
+ * for (const item of deque) {
3816
+ * forward.push(item);
3817
+ * }
3818
+ * console.log(forward); // ['A', 'B', 'C', 'D'];
3819
+ *
3820
+ * // Reverse the deque
3821
+ * deque.reverse();
3822
+ * const backward: string[] = [];
3823
+ * for (const item of deque) {
3824
+ * backward.push(item);
3825
+ * }
3826
+ * console.log(backward); // ['D', 'C', 'B', 'A'];
3827
+ */
3828
+ reverse() {
3829
+ this._buckets.reverse().forEach(function(bucket) {
3830
+ bucket.reverse();
3831
+ });
3832
+ const { _bucketFirst, _bucketLast, _firstInBucket, _lastInBucket } = this;
3833
+ this._bucketFirst = this._bucketCount - _bucketLast - 1;
3834
+ this._bucketLast = this._bucketCount - _bucketFirst - 1;
3835
+ this._firstInBucket = this._bucketSize - _lastInBucket - 1;
3836
+ this._lastInBucket = this._bucketSize - _firstInBucket - 1;
3837
+ return this;
3838
+ }
3839
+ /**
3840
+ * Deduplicate consecutive equal elements in-place.
3841
+ * @remarks Time O(N), Space O(1)
3842
+ * @returns This deque.
3843
+ */
3844
+ unique() {
3845
+ if (this._length <= 1) {
3846
+ return this;
3847
+ }
3848
+ let index = 1;
3849
+ let prev = this.at(0);
3850
+ for (let i = 1; i < this._length; ++i) {
3851
+ const cur = this.at(i);
3852
+ if (!this._equals(cur, prev)) {
3853
+ prev = cur;
3854
+ this.setAt(index++, cur);
3855
+ }
3856
+ }
3857
+ this.cut(index - 1, true);
3858
+ return this;
3859
+ }
3860
+ /**
3861
+ * Trim unused buckets to fit exactly the active range.
3862
+ * @remarks Time O(N), Space O(1)
3863
+ * @returns void
3864
+ */
3865
+ /**
3866
+ * (Protected) Trigger auto-compaction if space utilization drops below threshold.
3867
+ * Only checks every `_bucketSize` operations to minimize hot-path overhead.
3868
+ * Uses element-based ratio: `elements / (bucketCount * bucketSize)`.
3869
+ */
3870
+ _autoCompact() {
3871
+ if (this._autoCompactRatio <= 0 || this._bucketCount <= 1) return;
3872
+ this._compactCounter++;
3873
+ if (this._compactCounter < this._bucketSize) return;
3874
+ this._compactCounter = 0;
3875
+ const utilization = this._length / (this._bucketCount * this._bucketSize);
3876
+ if (utilization < this._autoCompactRatio) {
3877
+ this.shrinkToFit();
3878
+ }
3879
+ }
3880
+ /**
3881
+ * Compact the deque by removing unused buckets.
3882
+ * @remarks Time O(N), Space O(1)
3883
+ * @returns True if compaction was performed (bucket count reduced).
3884
+ */
3885
+ /**
3886
+ * Compact the deque by removing unused buckets.
3887
+ * @remarks Time O(N), Space O(1)
3888
+ * @returns True if compaction was performed (bucket count reduced).
3889
+
3890
+
3891
+
3892
+
3893
+
3894
+
3895
+
3896
+
3897
+
3898
+
3899
+
3900
+
3901
+
3902
+
3903
+
3904
+
3905
+
3906
+
3907
+
3908
+
3909
+
3910
+
3911
+
3912
+
3913
+
3914
+
3915
+
3916
+
3917
+
3918
+
3919
+
3920
+
3921
+ * @example
3922
+ * // Reclaim memory
3923
+ * const dq = new Deque<number>([1, 2, 3, 4, 5]);
3924
+ * dq.shift();
3925
+ * dq.shift();
3926
+ * dq.compact();
3927
+ * console.log(dq.length); // 3;
3928
+ */
3929
+ compact() {
3930
+ const before = this._bucketCount;
3931
+ this.shrinkToFit();
3932
+ return this._bucketCount < before;
3933
+ }
3934
+ shrinkToFit() {
3935
+ if (this._length === 0) return;
3936
+ const newBuckets = [];
3937
+ if (this._bucketFirst <= this._bucketLast) {
3938
+ for (let i = this._bucketFirst; i <= this._bucketLast; ++i) {
3939
+ newBuckets.push(this._buckets[i]);
3940
+ }
3941
+ } else {
3942
+ for (let i = this._bucketFirst; i < this._bucketCount; ++i) {
3943
+ newBuckets.push(this._buckets[i]);
3944
+ }
3945
+ for (let i = 0; i <= this._bucketLast; ++i) {
3946
+ newBuckets.push(this._buckets[i]);
3947
+ }
3948
+ }
3949
+ this._bucketFirst = 0;
3950
+ this._bucketLast = newBuckets.length - 1;
3951
+ this._buckets = newBuckets;
3952
+ this._bucketCount = newBuckets.length;
3953
+ this._compactCounter = 0;
3954
+ }
3955
+ /**
3956
+ * Deep clone this deque, preserving options.
3957
+ * @remarks Time O(N), Space O(N)
3958
+ * @returns A new deque with the same content and options.
3959
+
3960
+
3961
+
3962
+
3963
+
3964
+
3965
+
3966
+
3967
+
3968
+
3969
+
3970
+
3971
+
3972
+
3973
+
3974
+
3975
+
3976
+
3977
+
3978
+
3979
+
3980
+
3981
+
3982
+
3983
+
3984
+
3985
+
3986
+
3987
+
3988
+
3989
+
3990
+
3991
+
3992
+ * @example
3993
+ * // Create independent copy
3994
+ * const dq = new Deque<number>([1, 2, 3]);
3995
+ * const copy = dq.clone();
3996
+ * copy.pop();
3997
+ * console.log(dq.length); // 3;
3998
+ * console.log(copy.length); // 2;
3999
+ */
4000
+ clone() {
4001
+ return this._createLike(this, {
4002
+ bucketSize: this.bucketSize,
4003
+ toElementFn: this.toElementFn,
4004
+ maxLen: this._maxLen
4005
+ });
4006
+ }
4007
+ /**
4008
+ * Filter elements into a new deque of the same class.
4009
+ * @remarks Time O(N), Space O(N)
4010
+ * @param predicate - Predicate (value, index, deque) → boolean to keep element.
4011
+ * @param [thisArg] - Value for `this` inside the predicate.
4012
+ * @returns A new deque with kept elements.
4013
+
4014
+
4015
+
4016
+
4017
+
4018
+
4019
+
4020
+
4021
+
4022
+
4023
+
4024
+
4025
+
4026
+
4027
+
4028
+
4029
+
4030
+
4031
+
4032
+
4033
+
4034
+
4035
+
4036
+
4037
+
4038
+
4039
+
4040
+
4041
+
4042
+
4043
+
4044
+
4045
+
4046
+ * @example
4047
+ * // Filter elements
4048
+ * const dq = new Deque<number>([1, 2, 3, 4]);
4049
+ * const result = dq.filter(x => x > 2);
4050
+ * console.log(result.length); // 2;
4051
+ */
4052
+ filter(predicate, thisArg) {
4053
+ const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
4054
+ out._setBucketSize(this._bucketSize);
4055
+ let index = 0;
4056
+ for (const el of this) {
4057
+ if (predicate.call(thisArg, el, index, this)) out.push(el);
4058
+ index++;
4059
+ }
4060
+ return out;
4061
+ }
4062
+ /**
4063
+ * Map elements into a new deque of the same element type.
4064
+ * @remarks Time O(N), Space O(N)
4065
+ * @param callback - Mapping function (value, index, deque) → newValue.
4066
+ * @param [thisArg] - Value for `this` inside the callback.
4067
+ * @returns A new deque with mapped values.
4068
+ */
4069
+ mapSame(callback, thisArg) {
4070
+ const out = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
4071
+ out._setBucketSize(this._bucketSize);
4072
+ let index = 0;
4073
+ for (const v of this) {
4074
+ const mv = thisArg === void 0 ? callback(v, index++, this) : callback.call(thisArg, v, index++, this);
4075
+ out.push(mv);
4076
+ }
4077
+ return out;
4078
+ }
4079
+ /**
4080
+ * Map elements into a new deque (possibly different element type).
4081
+ * @remarks Time O(N), Space O(N)
4082
+ * @template EM
4083
+ * @template RM
4084
+ * @param callback - Mapping function (value, index, deque) → newElement.
4085
+ * @param [options] - Options for the output deque (e.g., bucketSize, toElementFn, maxLen).
4086
+ * @param [thisArg] - Value for `this` inside the callback.
4087
+ * @returns A new Deque with mapped elements.
4088
+
4089
+
4090
+
4091
+
4092
+
4093
+
4094
+
4095
+
4096
+
4097
+
4098
+
4099
+
4100
+
4101
+
4102
+
4103
+
4104
+
4105
+
4106
+
4107
+
4108
+
4109
+
4110
+
4111
+
4112
+
4113
+
4114
+
4115
+
4116
+
4117
+
4118
+
4119
+
4120
+ * @example
4121
+ * // Transform elements
4122
+ * const dq = new Deque<number>([1, 2, 3]);
4123
+ * const result = dq.map(x => x * 10);
4124
+ * console.log(result.toArray()); // [10, 20, 30];
4125
+ */
4126
+ map(callback, options, thisArg) {
4127
+ const out = this._createLike([], {
4128
+ ...options != null ? options : {},
4129
+ bucketSize: this._bucketSize,
4130
+ maxLen: this._maxLen
4131
+ });
4132
+ let index = 0;
4133
+ for (const el of this) {
4134
+ const mv = thisArg === void 0 ? callback(el, index, this) : callback.call(thisArg, el, index, this);
4135
+ out.push(mv);
4136
+ index++;
4137
+ }
4138
+ return out;
4139
+ }
4140
+ /**
4141
+ * (Protected) Set the internal bucket size.
4142
+ * @remarks Time O(1), Space O(1)
4143
+ * @param size - Bucket capacity to assign.
4144
+ * @returns void
4145
+ */
4146
+ _setBucketSize(size) {
4147
+ this._bucketSize = size;
4148
+ if (this._length === 0) {
4149
+ this._buckets = [new Array(this._bucketSize)];
4150
+ this._bucketCount = 1;
4151
+ this._bucketFirst = this._bucketLast = 0;
4152
+ this._firstInBucket = this._lastInBucket = this._bucketSize >> 1;
4153
+ }
4154
+ }
4155
+ /**
4156
+ * (Protected) Iterate elements from front to back.
4157
+ * @remarks Time O(N), Space O(1)
4158
+ * @returns Iterator of elements.
4159
+ */
4160
+ *_getIterator() {
4161
+ for (let i = 0; i < this._length; ++i) {
4162
+ const v = this.at(i);
4163
+ if (v !== void 0) yield v;
4164
+ }
4165
+ }
4166
+ /**
4167
+ * (Protected) Reallocate buckets to make room near the ends.
4168
+ * @remarks Time O(N), Space O(N)
4169
+ * @param [needBucketNum] - How many extra buckets to add; defaults to half of current.
4170
+ * @returns void
4171
+ */
4172
+ _reallocate(needBucketNum) {
4173
+ const newBuckets = [];
4174
+ const addBucketNum = needBucketNum || this._bucketCount >> 1 || 1;
4175
+ for (let i = 0; i < addBucketNum; ++i) {
4176
+ newBuckets[i] = new Array(this._bucketSize);
4177
+ }
4178
+ for (let i = this._bucketFirst; i < this._bucketCount; ++i) {
4179
+ newBuckets[newBuckets.length] = this._buckets[i];
4180
+ }
4181
+ for (let i = 0; i < this._bucketLast; ++i) {
4182
+ newBuckets[newBuckets.length] = this._buckets[i];
4183
+ }
4184
+ newBuckets[newBuckets.length] = [...this._buckets[this._bucketLast]];
4185
+ this._bucketFirst = addBucketNum;
4186
+ this._bucketLast = newBuckets.length - 1;
4187
+ for (let i = 0; i < addBucketNum; ++i) {
4188
+ newBuckets[newBuckets.length] = new Array(this._bucketSize);
4189
+ }
4190
+ this._buckets = newBuckets;
4191
+ this._bucketCount = newBuckets.length;
4192
+ }
4193
+ /**
4194
+ * (Protected) Translate a logical position to bucket/offset.
4195
+ * @remarks Time O(1), Space O(1)
4196
+ * @param pos - Zero-based position.
4197
+ * @returns An object containing bucketIndex and indexInBucket.
4198
+ */
4199
+ _getBucketAndPosition(pos) {
4200
+ let bucketIndex;
4201
+ let indexInBucket;
4202
+ const overallIndex = this._firstInBucket + pos;
4203
+ bucketIndex = this._bucketFirst + Math.floor(overallIndex / this._bucketSize);
4204
+ if (bucketIndex >= this._bucketCount) {
4205
+ bucketIndex -= this._bucketCount;
4206
+ }
4207
+ indexInBucket = (overallIndex + 1) % this._bucketSize - 1;
4208
+ if (indexInBucket < 0) {
4209
+ indexInBucket = this._bucketSize - 1;
4210
+ }
4211
+ return { bucketIndex, indexInBucket };
4212
+ }
4213
+ /**
4214
+ * (Protected) Create an empty instance of the same concrete class.
4215
+ * @remarks Time O(1), Space O(1)
4216
+ * @param [options] - Options forwarded to the constructor.
4217
+ * @returns An empty like-kind deque instance.
4218
+ */
4219
+ _createInstance(options) {
4220
+ const Ctor = this.constructor;
4221
+ return new Ctor([], options);
4222
+ }
4223
+ /**
4224
+ * (Protected) Create a like-kind deque seeded by elements.
4225
+ * @remarks Time O(N), Space O(N)
4226
+ * @template T
4227
+ * @template RR
4228
+ * @param [elements] - Iterable used to seed the new deque.
4229
+ * @param [options] - Options forwarded to the constructor.
4230
+ * @returns A like-kind Deque instance.
4231
+ */
4232
+ _createLike(elements = [], options) {
4233
+ const Ctor = this.constructor;
4234
+ return new Ctor(elements, options);
4235
+ }
4236
+ /**
4237
+ * (Protected) Iterate elements from back to front.
4238
+ * @remarks Time O(N), Space O(1)
4239
+ * @returns Iterator of elements.
4240
+ */
4241
+ *_getReverseIterator() {
4242
+ for (let i = this._length - 1; i > -1; i--) {
4243
+ const v = this.at(i);
4244
+ if (v !== void 0) yield v;
4245
+ }
4246
+ }
4247
+ };
4248
+ __name(_Deque, "Deque");
4249
+ var Deque = _Deque;
4250
+ /**
4251
+ * data-structure-typed
4252
+ *
4253
+ * @author Pablo Zeng
4254
+ * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
4255
+ * @license MIT License
4256
+ */
4257
+
4258
+ exports.Deque = Deque;
4259
+ exports.LinkedListQueue = LinkedListQueue;
4260
+ exports.Queue = Queue;
4261
+ //# sourceMappingURL=queue.cjs.map
4262
+ //# sourceMappingURL=queue.cjs.map