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
@@ -26,7 +26,7 @@ import { BinaryTree } from './binary-tree';
26
26
  import { IBinaryTree } from '../../interfaces';
27
27
  import { Queue } from '../queue';
28
28
  import { isComparable } from '../../utils';
29
- import { ERR, Range } from '../../common';
29
+ import { ERR, Range, raise } from '../../common';
30
30
 
31
31
  /**
32
32
  * Represents a Node in a Binary Search Tree.
@@ -345,6 +345,9 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
345
345
  } else {
346
346
  this._comparator = this._createDefaultComparator();
347
347
  }
348
+ if (options.enableOrderStatistic) {
349
+ this._enableOrderStatistic = true;
350
+ }
348
351
  } else {
349
352
  this._comparator = this._createDefaultComparator();
350
353
  }
@@ -354,6 +357,8 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
354
357
 
355
358
  protected override _root?: BSTNode<K, V> = undefined;
356
359
 
360
+ protected _enableOrderStatistic: boolean = false;
361
+
357
362
  /**
358
363
  * Gets the root node of the tree.
359
364
  * @remarks Time O(1)
@@ -428,7 +433,7 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
428
433
  * @param key - The key to validate.
429
434
  * @returns True if the key is valid, false otherwise.
430
435
  */
431
- override isValidKey(key: any): key is K {
436
+ override isValidKey(key: unknown): key is K {
432
437
  return isComparable(key);
433
438
  }
434
439
 
@@ -454,6 +459,52 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
454
459
 
455
460
 
456
461
 
462
+
463
+
464
+
465
+
466
+
467
+
468
+
469
+
470
+
471
+
472
+
473
+
474
+
475
+
476
+
477
+
478
+
479
+
480
+
481
+
482
+
483
+
484
+
485
+
486
+
487
+
488
+
489
+
490
+
491
+
492
+
493
+
494
+
495
+
496
+
497
+
498
+
499
+
500
+
501
+
502
+
503
+
504
+
505
+
506
+
507
+
457
508
 
458
509
 
459
510
 
@@ -514,6 +565,52 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
514
565
 
515
566
 
516
567
 
568
+
569
+
570
+
571
+
572
+
573
+
574
+
575
+
576
+
577
+
578
+
579
+
580
+
581
+
582
+
583
+
584
+
585
+
586
+
587
+
588
+
589
+
590
+
591
+
592
+
593
+
594
+
595
+
596
+
597
+
598
+
599
+
600
+
601
+
602
+
603
+
604
+
605
+
606
+
607
+
608
+
609
+
610
+
611
+
612
+
613
+
517
614
  * @example
518
615
  * // Breadth-first traversal
519
616
  * const bst = new BST<number>([5, 3, 7]);
@@ -566,6 +663,52 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
566
663
 
567
664
 
568
665
 
666
+
667
+
668
+
669
+
670
+
671
+
672
+
673
+
674
+
675
+
676
+
677
+
678
+
679
+
680
+
681
+
682
+
683
+
684
+
685
+
686
+
687
+
688
+
689
+
690
+
691
+
692
+
693
+
694
+
695
+
696
+
697
+
698
+
699
+
700
+
701
+
702
+
703
+
704
+
705
+
706
+
707
+
708
+
709
+
710
+
711
+
569
712
  * @example
570
713
  * // Level-order grouping
571
714
  * const bst = new BST<number>([5, 3, 7, 1, 4]);
@@ -629,6 +772,52 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
629
772
 
630
773
 
631
774
 
775
+
776
+
777
+
778
+
779
+
780
+
781
+
782
+
783
+
784
+
785
+
786
+
787
+
788
+
789
+
790
+
791
+
792
+
793
+
794
+
795
+
796
+
797
+
798
+
799
+
800
+
801
+
802
+
803
+
804
+
805
+
806
+
807
+
808
+
809
+
810
+
811
+
812
+
813
+
814
+
815
+
816
+
817
+
818
+
819
+
820
+
632
821
 
633
822
  * @example
634
823
  * // Get node object by key
@@ -713,6 +902,52 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
713
902
 
714
903
 
715
904
 
905
+
906
+
907
+
908
+
909
+
910
+
911
+
912
+
913
+
914
+
915
+
916
+
917
+
918
+
919
+
920
+
921
+
922
+
923
+
924
+
925
+
926
+
927
+
928
+
929
+
930
+
931
+
932
+
933
+
934
+
935
+
936
+
937
+
938
+
939
+
940
+
941
+
942
+
943
+
944
+
945
+
946
+
947
+
948
+
949
+
950
+
716
951
  * @example
717
952
  * // Search nodes by predicate
718
953
  * const bst = new BST<number, string>([[1, 'a'], [2, 'b'], [3, 'c'], [4, 'd']]);
@@ -885,6 +1120,29 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
885
1120
 
886
1121
 
887
1122
 
1123
+
1124
+
1125
+
1126
+
1127
+
1128
+
1129
+
1130
+
1131
+
1132
+
1133
+
1134
+
1135
+
1136
+
1137
+
1138
+
1139
+
1140
+
1141
+
1142
+
1143
+
1144
+
1145
+
888
1146
  * @example
889
1147
  * // Find all keys in a range
890
1148
  * const bst = new BST<number>([10, 20, 30, 40, 50]);
@@ -920,6 +1178,232 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
920
1178
  return this.search(searchRange, false, callback, startNode, iterationType);
921
1179
  }
922
1180
 
1181
+ // ─── Order-Statistic Methods ───────────────────────────
1182
+
1183
+ /**
1184
+ * Returns the element at the k-th position in tree order (0-indexed).
1185
+ * @remarks Time O(log n), Space O(1) iterative / O(log n) recursive. Requires `enableOrderStatistic: true`.
1186
+ * Tree order is defined by the comparator — ascending by default, but respects custom comparators (e.g. descending).
1187
+ *
1188
+ * @param k - The 0-based position in tree order (0 = first element).
1189
+ * @returns The key at position k, or `undefined` if out of bounds.
1190
+ * @example
1191
+ * // Order-statistic on BST
1192
+ * const tree = new BST<number>([30, 10, 50, 20, 40], { enableOrderStatistic: true });
1193
+ * console.log(tree.getByRank(0)); // 10;
1194
+ * console.log(tree.getByRank(4)); // 50;
1195
+ * console.log(tree.getRank(30)); // 2;
1196
+ */
1197
+ getByRank(k: number): K | undefined;
1198
+
1199
+ /**
1200
+ * Returns the element at the k-th position in tree order and applies a callback.
1201
+ * @remarks Time O(log n), Space O(1) iterative / O(log n) recursive. Requires `enableOrderStatistic: true`.
1202
+ *
1203
+ * @param k - The 0-based position in tree order (0 = first element).
1204
+ * @param callback - Callback to apply to the found node.
1205
+ * @param iterationType - Iteration strategy ('ITERATIVE' or 'RECURSIVE').
1206
+ * @returns The callback result, or `undefined` if out of bounds.
1207
+ */
1208
+ getByRank<C extends NodeCallback<BSTNode<K, V>>>(
1209
+ k: number,
1210
+ callback: C,
1211
+ iterationType?: IterationType
1212
+ ): ReturnType<C> | undefined;
1213
+
1214
+ getByRank<C extends NodeCallback<BSTNode<K, V>>>(
1215
+ k: number,
1216
+ callback: C = this._DEFAULT_NODE_CALLBACK as C,
1217
+ iterationType: IterationType = this.iterationType
1218
+ ): K | undefined | ReturnType<C> | undefined {
1219
+ if (!this._enableOrderStatistic) {
1220
+ raise(Error, ERR.orderStatisticNotEnabled('getByRank'));
1221
+ }
1222
+ if (k < 0 || k >= this._size) return undefined;
1223
+
1224
+ let actualCallback: C | undefined = undefined;
1225
+ let actualIterationType: IterationType = this.iterationType;
1226
+
1227
+ if (typeof callback === 'string') {
1228
+ actualIterationType = callback;
1229
+ } else if (callback) {
1230
+ actualCallback = callback;
1231
+ if (iterationType) {
1232
+ actualIterationType = iterationType;
1233
+ }
1234
+ }
1235
+
1236
+ const node = actualIterationType === 'RECURSIVE'
1237
+ ? this._getByRankRecursive(this._root, k)
1238
+ : this._getByRankIterative(this._root, k);
1239
+
1240
+ if (!node) return undefined;
1241
+ return actualCallback ? actualCallback(node) : node.key;
1242
+ }
1243
+
1244
+ /**
1245
+ * Returns the 0-based rank of a key (number of elements that precede it in tree order).
1246
+ * @remarks Time O(log n), Space O(1) iterative / O(log n) recursive. Requires `enableOrderStatistic: true`.
1247
+ * Tree order is defined by the comparator. When the key is not found, returns the insertion position.
1248
+ *
1249
+ * @param keyNodeEntryOrPredicate - The key, node, entry `[K, V]`, or predicate to find.
1250
+ * @returns The rank (0-indexed), or -1 if the tree is empty or input is invalid.
1251
+ */
1252
+ getRank(
1253
+ keyNodeEntryOrPredicate:
1254
+ | K
1255
+ | BSTNode<K, V>
1256
+ | [K | null | undefined, V | undefined]
1257
+ | null
1258
+ | undefined
1259
+ | NodePredicate<BSTNode<K, V>>
1260
+ ): number;
1261
+
1262
+ /**
1263
+ * Returns the 0-based rank (number of preceding elements in tree order) with explicit iteration type.
1264
+ * @remarks Time O(log n), Space O(1) iterative / O(log n) recursive. Requires `enableOrderStatistic: true`.
1265
+ *
1266
+ * @param keyNodeEntryOrPredicate - The key, node, entry, or predicate to find.
1267
+ * @param iterationType - Iteration strategy ('ITERATIVE' or 'RECURSIVE').
1268
+ * @returns The rank (0-indexed), or -1 if the tree is empty or input is invalid.
1269
+ */
1270
+ getRank(
1271
+ keyNodeEntryOrPredicate:
1272
+ | K
1273
+ | BSTNode<K, V>
1274
+ | [K | null | undefined, V | undefined]
1275
+ | null
1276
+ | undefined
1277
+ | NodePredicate<BSTNode<K, V>>,
1278
+ iterationType: IterationType
1279
+ ): number;
1280
+
1281
+ getRank(
1282
+ keyNodeEntryOrPredicate:
1283
+ | K
1284
+ | BSTNode<K, V>
1285
+ | [K | null | undefined, V | undefined]
1286
+ | null
1287
+ | undefined
1288
+ | NodePredicate<BSTNode<K, V>>,
1289
+ iterationType: IterationType = this.iterationType
1290
+ ): number {
1291
+ if (!this._enableOrderStatistic) {
1292
+ raise(Error, ERR.orderStatisticNotEnabled('getRank'));
1293
+ }
1294
+ if (!this._root || this._size === 0) return -1;
1295
+
1296
+ let actualIterationType: IterationType = this.iterationType;
1297
+ if (iterationType) actualIterationType = iterationType;
1298
+
1299
+ // Resolve key from input
1300
+ let key: K | undefined;
1301
+ if (typeof keyNodeEntryOrPredicate === 'function') {
1302
+ // Predicate: find first matching node
1303
+ const results = this.search(keyNodeEntryOrPredicate as NodePredicate<BSTNode<K, V>>, true);
1304
+ if (results.length === 0 || results[0] === undefined) return -1;
1305
+ key = results[0];
1306
+ } else if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === undefined) {
1307
+ return -1;
1308
+ } else if (this.isNode(keyNodeEntryOrPredicate)) {
1309
+ key = keyNodeEntryOrPredicate.key;
1310
+ } else if (Array.isArray(keyNodeEntryOrPredicate)) {
1311
+ key = keyNodeEntryOrPredicate[0] ?? undefined;
1312
+ if (key === undefined || key === null) return -1;
1313
+ } else {
1314
+ key = keyNodeEntryOrPredicate as K;
1315
+ }
1316
+
1317
+ if (key === undefined) return -1;
1318
+
1319
+ return actualIterationType === 'RECURSIVE'
1320
+ ? this._getRankRecursive(this._root, key)
1321
+ : this._getRankIterative(this._root, key);
1322
+ }
1323
+
1324
+ /**
1325
+ * Returns elements by position range in tree order (0-indexed, inclusive on both ends).
1326
+ * @remarks Time O(log n + k), Space O(k), where k = end - start + 1. Requires `enableOrderStatistic: true`.
1327
+ *
1328
+ * @param start - Start position (inclusive, 0-indexed). Clamped to 0 if negative.
1329
+ * @param end - End position (inclusive, 0-indexed). Clamped to size-1 if too large.
1330
+ * @returns Array of keys in tree order within the specified range.
1331
+ */
1332
+ rangeByRank(start: number, end: number): (K | undefined)[];
1333
+
1334
+ /**
1335
+ * Returns elements by position range in tree order with callback and optional iteration type.
1336
+ * @remarks Time O(log n + k), Space O(k), where k = end - start + 1. Requires `enableOrderStatistic: true`.
1337
+ *
1338
+ * @param start - Start rank (inclusive, 0-indexed).
1339
+ * @param end - End rank (inclusive, 0-indexed).
1340
+ * @param callback - Callback to apply to each node in the range.
1341
+ * @param iterationType - Iteration strategy ('ITERATIVE' or 'RECURSIVE').
1342
+ * @returns Array of callback results for nodes in the rank range.
1343
+ */
1344
+ rangeByRank<C extends NodeCallback<BSTNode<K, V>>>(
1345
+ start: number,
1346
+ end: number,
1347
+ callback: C,
1348
+ iterationType?: IterationType
1349
+ ): ReturnType<C>[];
1350
+
1351
+ rangeByRank<C extends NodeCallback<BSTNode<K, V>>>(
1352
+ start: number,
1353
+ end: number,
1354
+ callback: C = this._DEFAULT_NODE_CALLBACK as C,
1355
+ iterationType: IterationType = this.iterationType
1356
+ ): (K | undefined)[] | ReturnType<C>[] {
1357
+ if (!this._enableOrderStatistic) {
1358
+ raise(Error, ERR.orderStatisticNotEnabled('rangeByRank'));
1359
+ }
1360
+ if (this._size === 0) return [];
1361
+
1362
+ // Clamp
1363
+ const lo = Math.max(0, start);
1364
+ const hi = Math.min(this._size - 1, end);
1365
+ if (lo > hi) return [];
1366
+
1367
+ let actualCallback: C | undefined = undefined;
1368
+ let actualIterationType: IterationType = this.iterationType;
1369
+
1370
+ if (typeof callback === 'string') {
1371
+ actualIterationType = callback;
1372
+ } else if (callback) {
1373
+ actualCallback = callback;
1374
+ if (iterationType) {
1375
+ actualIterationType = iterationType;
1376
+ }
1377
+ }
1378
+
1379
+ const results: (K | undefined | ReturnType<C>)[] = [];
1380
+ const count = hi - lo + 1;
1381
+
1382
+ // Find the lo-th node, then in-order traverse count nodes
1383
+ const startNode = actualIterationType === 'RECURSIVE'
1384
+ ? this._getByRankRecursive(this._root, lo)
1385
+ : this._getByRankIterative(this._root, lo);
1386
+
1387
+ if (!startNode) return [];
1388
+
1389
+ // In-order traversal from startNode collecting count elements
1390
+ let collected = 0;
1391
+ const cb = actualCallback ?? this._DEFAULT_NODE_CALLBACK as C;
1392
+
1393
+ // Use higher() to iterate — it's already O(log n) amortized per step
1394
+ let current: BSTNode<K, V> | undefined = startNode;
1395
+ while (current && collected < count) {
1396
+ results.push(cb(current));
1397
+ collected++;
1398
+ if (collected < count) {
1399
+ // Find next in-order node
1400
+ current = this._next(current);
1401
+ }
1402
+ }
1403
+
1404
+ return results as (K | undefined)[] | ReturnType<C>[];
1405
+ }
1406
+
923
1407
  /**
924
1408
  * Adds a new node to the BST based on key comparison.
925
1409
  * @remarks Time O(log N), where H is tree height. O(N) worst-case (unbalanced tree), O(log N) average. Space O(1).
@@ -947,6 +1431,75 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
947
1431
 
948
1432
 
949
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
+
1460
+
1461
+
1462
+
1463
+
1464
+
1465
+
1466
+
1467
+
1468
+
1469
+
1470
+
1471
+
1472
+
1473
+
1474
+
1475
+
1476
+
1477
+
1478
+
1479
+
1480
+
1481
+
1482
+
1483
+
1484
+
1485
+
1486
+
1487
+
1488
+
1489
+
1490
+
1491
+
1492
+
1493
+
1494
+
1495
+
1496
+
1497
+
1498
+
1499
+
1500
+
1501
+
1502
+
950
1503
 
951
1504
 
952
1505
 
@@ -973,6 +1526,7 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
973
1526
  this._setRoot(newNode);
974
1527
  if (this._isMapMode && this.isRealNode(newNode)) this._store.set(newNode.key, newNode);
975
1528
  this._size++;
1529
+ this._updateCount(newNode);
976
1530
  return true;
977
1531
  }
978
1532
 
@@ -989,6 +1543,7 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
989
1543
  current.left = newNode;
990
1544
  if (this._isMapMode && this.isRealNode(newNode)) this._store.set(newNode.key, newNode);
991
1545
  this._size++;
1546
+ this._updateCountAlongPath(newNode);
992
1547
  return true;
993
1548
  }
994
1549
  if (current.left !== null) current = current.left;
@@ -998,6 +1553,7 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
998
1553
  current.right = newNode;
999
1554
  if (this._isMapMode && this.isRealNode(newNode)) this._store.set(newNode.key, newNode);
1000
1555
  this._size++;
1556
+ this._updateCountAlongPath(newNode);
1001
1557
  return true;
1002
1558
  }
1003
1559
  if (current.right !== null) current = current.right;
@@ -1031,6 +1587,52 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
1031
1587
 
1032
1588
 
1033
1589
 
1590
+
1591
+
1592
+
1593
+
1594
+
1595
+
1596
+
1597
+
1598
+
1599
+
1600
+
1601
+
1602
+
1603
+
1604
+
1605
+
1606
+
1607
+
1608
+
1609
+
1610
+
1611
+
1612
+
1613
+
1614
+
1615
+
1616
+
1617
+
1618
+
1619
+
1620
+
1621
+
1622
+
1623
+
1624
+
1625
+
1626
+
1627
+
1628
+
1629
+
1630
+
1631
+
1632
+
1633
+
1634
+
1635
+
1034
1636
  * @example
1035
1637
  * // Set multiple key-value pairs
1036
1638
  * const bst = new BST<number, string>();
@@ -1147,6 +1749,29 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
1147
1749
 
1148
1750
 
1149
1751
 
1752
+
1753
+
1754
+
1755
+
1756
+
1757
+
1758
+
1759
+
1760
+
1761
+
1762
+
1763
+
1764
+
1765
+
1766
+
1767
+
1768
+
1769
+
1770
+
1771
+
1772
+
1773
+
1774
+
1150
1775
  * @example
1151
1776
  * // Find the least key ≥ target
1152
1777
  * const bst = new BST<number>([10, 20, 30, 40, 50]);
@@ -1230,6 +1855,29 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
1230
1855
 
1231
1856
 
1232
1857
 
1858
+
1859
+
1860
+
1861
+
1862
+
1863
+
1864
+
1865
+
1866
+
1867
+
1868
+
1869
+
1870
+
1871
+
1872
+
1873
+
1874
+
1875
+
1876
+
1877
+
1878
+
1879
+
1880
+
1233
1881
  * @example
1234
1882
  * // Find the least key strictly > target
1235
1883
  * const bst = new BST<number>([10, 20, 30, 40]);
@@ -1312,6 +1960,29 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
1312
1960
 
1313
1961
 
1314
1962
 
1963
+
1964
+
1965
+
1966
+
1967
+
1968
+
1969
+
1970
+
1971
+
1972
+
1973
+
1974
+
1975
+
1976
+
1977
+
1978
+
1979
+
1980
+
1981
+
1982
+
1983
+
1984
+
1985
+
1315
1986
  * @example
1316
1987
  * // Find the greatest key ≤ target
1317
1988
  * const bst = new BST<number>([10, 20, 30, 40, 50]);
@@ -1438,6 +2109,29 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
1438
2109
 
1439
2110
 
1440
2111
 
2112
+
2113
+
2114
+
2115
+
2116
+
2117
+
2118
+
2119
+
2120
+
2121
+
2122
+
2123
+
2124
+
2125
+
2126
+
2127
+
2128
+
2129
+
2130
+
2131
+
2132
+
2133
+
2134
+
1441
2135
  * @example
1442
2136
  * // Find the greatest key strictly < target
1443
2137
  * const bst = new BST<number>([10, 20, 30, 40]);
@@ -1620,6 +2314,29 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
1620
2314
 
1621
2315
 
1622
2316
 
2317
+
2318
+
2319
+
2320
+
2321
+
2322
+
2323
+
2324
+
2325
+
2326
+
2327
+
2328
+
2329
+
2330
+
2331
+
2332
+
2333
+
2334
+
2335
+
2336
+
2337
+
2338
+
2339
+
1623
2340
  * @example
1624
2341
  * // Rebalance the tree
1625
2342
  * const bst = new BST<number>();
@@ -1670,6 +2387,29 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
1670
2387
 
1671
2388
 
1672
2389
 
2390
+
2391
+
2392
+
2393
+
2394
+
2395
+
2396
+
2397
+
2398
+
2399
+
2400
+
2401
+
2402
+
2403
+
2404
+
2405
+
2406
+
2407
+
2408
+
2409
+
2410
+
2411
+
2412
+
1673
2413
  * @example
1674
2414
  * // Check if tree is height-balanced
1675
2415
  * const bst = new BST<number>([3, 1, 5, 2, 4]);
@@ -1751,6 +2491,52 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
1751
2491
 
1752
2492
 
1753
2493
 
2494
+
2495
+
2496
+
2497
+
2498
+
2499
+
2500
+
2501
+
2502
+
2503
+
2504
+
2505
+
2506
+
2507
+
2508
+
2509
+
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
+
1754
2540
 
1755
2541
  * @example
1756
2542
  * // Transform to new tree
@@ -1851,15 +2637,13 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
1851
2637
  if (a instanceof Date && b instanceof Date) {
1852
2638
  const ta = a.getTime();
1853
2639
  const tb = b.getTime();
1854
- if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate('BST'));
2640
+ if (Number.isNaN(ta) || Number.isNaN(tb)) raise(TypeError, ERR.invalidDate('BST'));
1855
2641
  return ta > tb ? 1 : ta < tb ? -1 : 0;
1856
2642
  }
1857
2643
 
1858
2644
  // If keys are objects and no comparator is provided, throw an error
1859
2645
  if (typeof a === 'object' || typeof b === 'object') {
1860
- throw new TypeError(
1861
- ERR.comparatorRequired('BST')
1862
- );
2646
+ raise(TypeError, ERR.comparatorRequired('BST'));
1863
2647
  }
1864
2648
 
1865
2649
  // Default: keys are equal (fallback case)
@@ -2324,7 +3108,8 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
2324
3108
  protected override _snapshotOptions<TK = K, TV = V, TR = R>(): BSTOptions<TK, TV, TR> {
2325
3109
  return {
2326
3110
  ...super._snapshotOptions<TK, TV, TR>(),
2327
- comparator: this._comparator as unknown as BSTOptions<TK, TV, TR>['comparator']
3111
+ comparator: this._comparator as unknown as BSTOptions<TK, TV, TR>['comparator'],
3112
+ enableOrderStatistic: this._enableOrderStatistic
2328
3113
  };
2329
3114
  }
2330
3115
 
@@ -2351,6 +3136,129 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
2351
3136
  *
2352
3137
  * @param v - The node to set as root.
2353
3138
  */
3139
+ /**
3140
+ * (Protected) Recalculates the subtree count for a single node.
3141
+ * @remarks Time O(1). Only active when enableOrderStatistic is true.
3142
+ */
3143
+ protected _updateCount(node: BSTNode<K, V>): void {
3144
+ if (!this._enableOrderStatistic) return;
3145
+ node._count = 1
3146
+ + (this.isRealNode(node.left) ? node.left._count : 0)
3147
+ + (this.isRealNode(node.right) ? node.right._count : 0);
3148
+ }
3149
+
3150
+ /**
3151
+ * (Protected) Updates subtree counts from a node up to the root.
3152
+ * @remarks Time O(log n). Only active when enableOrderStatistic is true.
3153
+ */
3154
+ protected _updateCountAlongPath(node: OptNode<BSTNode<K, V>>): void {
3155
+ if (!this._enableOrderStatistic) return;
3156
+ let current = node;
3157
+ while (current) {
3158
+ this._updateCount(current);
3159
+ current = current.parent as BSTNode<K, V> | undefined;
3160
+ }
3161
+ }
3162
+
3163
+ /**
3164
+ * (Protected) Finds the node at position k in tree order (iterative).
3165
+ * @remarks Time O(log n), Space O(1)
3166
+ */
3167
+ protected _getByRankIterative(node: OptNode<BSTNode<K, V>>, k: number): BSTNode<K, V> | undefined {
3168
+ let current = node;
3169
+ let remaining = k;
3170
+ while (current) {
3171
+ const leftCount = this.isRealNode(current.left) ? current.left._count : 0;
3172
+ if (remaining < leftCount) {
3173
+ current = current.left as BSTNode<K, V> | undefined;
3174
+ } else if (remaining === leftCount) {
3175
+ return current;
3176
+ } else {
3177
+ remaining = remaining - leftCount - 1;
3178
+ current = current.right as BSTNode<K, V> | undefined;
3179
+ }
3180
+ }
3181
+ return undefined;
3182
+ }
3183
+
3184
+ /**
3185
+ * (Protected) Finds the node at position k in tree order (recursive).
3186
+ * @remarks Time O(log n), Space O(log n) call stack
3187
+ */
3188
+ protected _getByRankRecursive(node: OptNode<BSTNode<K, V>>, k: number): BSTNode<K, V> | undefined {
3189
+ if (!node) return undefined;
3190
+ const leftCount = this.isRealNode(node.left) ? node.left._count : 0;
3191
+ if (k < leftCount) return this._getByRankRecursive(node.left as BSTNode<K, V> | undefined, k);
3192
+ if (k === leftCount) return node;
3193
+ return this._getByRankRecursive(node.right as BSTNode<K, V> | undefined, k - leftCount - 1);
3194
+ }
3195
+
3196
+ /**
3197
+ * (Protected) Computes the rank of a key iteratively.
3198
+ * @remarks Time O(log n), Space O(1)
3199
+ */
3200
+ protected _getRankIterative(node: OptNode<BSTNode<K, V>>, key: K): number {
3201
+ let rank = 0;
3202
+ let current = node;
3203
+ while (this.isRealNode(current)) {
3204
+ const cmp = this._compare(current.key, key);
3205
+ if (cmp > 0) {
3206
+ // key < current.key, go left
3207
+ current = current.left as BSTNode<K, V> | undefined;
3208
+ } else if (cmp < 0) {
3209
+ // key > current.key
3210
+ rank += (this.isRealNode(current.left) ? current.left._count : 0) + 1;
3211
+ current = current.right as BSTNode<K, V> | undefined;
3212
+ } else {
3213
+ // Found
3214
+ rank += this.isRealNode(current.left) ? current.left._count : 0;
3215
+ return rank;
3216
+ }
3217
+ }
3218
+ // Key not found, rank = insertion position
3219
+ return rank;
3220
+ }
3221
+
3222
+ /**
3223
+ * (Protected) Computes the rank of a key recursively.
3224
+ * @remarks Time O(log n), Space O(log n) call stack
3225
+ */
3226
+ protected _getRankRecursive(node: OptNode<BSTNode<K, V>>, key: K): number {
3227
+ if (!node) return 0;
3228
+ const cmp = this._compare(node.key, key);
3229
+ if (cmp > 0) {
3230
+ return this._getRankRecursive(node.left as BSTNode<K, V> | undefined, key);
3231
+ } else if (cmp < 0) {
3232
+ return (this.isRealNode(node.left) ? node.left._count : 0) + 1
3233
+ + this._getRankRecursive(node.right as BSTNode<K, V> | undefined, key);
3234
+ } else {
3235
+ return this.isRealNode(node.left) ? node.left._count : 0;
3236
+ }
3237
+ }
3238
+
3239
+ /**
3240
+ * (Protected) Finds the in-order successor of a node.
3241
+ * @remarks Time O(log n), Space O(1)
3242
+ */
3243
+ protected _next(node: BSTNode<K, V>): BSTNode<K, V> | undefined {
3244
+ if (this.isRealNode(node.right)) {
3245
+ // Leftmost in right subtree
3246
+ let current = node.right as BSTNode<K, V>;
3247
+ while (this.isRealNode(current.left)) {
3248
+ current = current.left as BSTNode<K, V>;
3249
+ }
3250
+ return current;
3251
+ }
3252
+ // Go up until we come from a left child
3253
+ let current: BSTNode<K, V> | undefined = node;
3254
+ let parent = current.parent as BSTNode<K, V> | undefined;
3255
+ while (parent && current === parent.right) {
3256
+ current = parent;
3257
+ parent = parent.parent as BSTNode<K, V> | undefined;
3258
+ }
3259
+ return parent;
3260
+ }
3261
+
2354
3262
  protected override _setRoot(v: OptNode<BSTNode<K, V>>) {
2355
3263
  if (v) v.parent = undefined;
2356
3264
  this._root = v;
@@ -2407,25 +3315,32 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
2407
3315
  };
2408
3316
 
2409
3317
  // 2. Perform deletion
3318
+ let countUpdateStart: BSTNode<K, V> | undefined;
2410
3319
  if (node.left === undefined) {
2411
3320
  // Case 1: No left child
3321
+ countUpdateStart = node.parent as BSTNode<K, V> | undefined;
2412
3322
  transplant(node, node.right as BSTNode<K, V> | undefined);
2413
3323
  } else if (node.right === undefined) {
2414
3324
  // Case 2: No right child
3325
+ countUpdateStart = node.parent as BSTNode<K, V> | undefined;
2415
3326
  transplant(node, node.left as BSTNode<K, V> | undefined);
2416
3327
  } else {
2417
3328
  // Case 3: Two children
2418
3329
  const succ = minNode(node.right as BSTNode<K, V> | undefined)!; // Find successor
2419
3330
  if (succ.parent !== node) {
3331
+ countUpdateStart = succ.parent as BSTNode<K, V> | undefined;
2420
3332
  transplant(succ, succ.right as BSTNode<K, V> | undefined);
2421
3333
  succ.right = node.right as BSTNode<K, V> | undefined;
2422
3334
  if (succ.right) (succ.right as BSTNode<K, V>).parent = succ;
3335
+ } else {
3336
+ countUpdateStart = succ;
2423
3337
  }
2424
3338
  transplant(node, succ);
2425
3339
  succ.left = node.left as BSTNode<K, V> | undefined;
2426
3340
  if (succ.left) (succ.left as BSTNode<K, V>).parent = succ;
2427
3341
  }
2428
3342
 
3343
+ this._updateCountAlongPath(countUpdateStart);
2429
3344
  this._size = Math.max(0, this._size - 1);
2430
3345
  return true;
2431
3346
  }