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.
- package/.vitepress/cache/deps_temp_51f5f1b0/chunk-7OIKW5WK.js +12984 -0
- package/.vitepress/cache/deps_temp_51f5f1b0/package.json +3 -0
- package/.vitepress/cache/deps_temp_51f5f1b0/vitepress___@vue_devtools-api.js +4505 -0
- package/.vitepress/cache/deps_temp_51f5f1b0/vitepress___@vueuse_core.js +9731 -0
- package/.vitepress/cache/deps_temp_51f5f1b0/vue.js +347 -0
- package/CHANGELOG.md +5 -1
- package/README.md +124 -29
- package/dist/cjs/binary-tree.cjs +26282 -0
- package/dist/cjs/graph.cjs +5422 -0
- package/dist/cjs/hash.cjs +1310 -0
- package/dist/cjs/heap.cjs +1602 -0
- package/dist/cjs/index.cjs +31257 -14673
- package/dist/cjs/linked-list.cjs +4576 -0
- package/dist/cjs/matrix.cjs +1080 -0
- package/dist/cjs/priority-queue.cjs +1376 -0
- package/dist/cjs/queue.cjs +4264 -0
- package/dist/cjs/stack.cjs +907 -0
- package/dist/cjs/trie.cjs +1223 -0
- package/dist/cjs-legacy/binary-tree.cjs +26319 -0
- package/dist/cjs-legacy/graph.cjs +5420 -0
- package/dist/cjs-legacy/hash.cjs +1310 -0
- package/dist/cjs-legacy/heap.cjs +1599 -0
- package/dist/cjs-legacy/index.cjs +31268 -14679
- package/dist/cjs-legacy/linked-list.cjs +4582 -0
- package/dist/cjs-legacy/matrix.cjs +1083 -0
- package/dist/cjs-legacy/priority-queue.cjs +1374 -0
- package/dist/cjs-legacy/queue.cjs +4262 -0
- package/dist/cjs-legacy/stack.cjs +907 -0
- package/dist/cjs-legacy/trie.cjs +1222 -0
- package/dist/esm/binary-tree.mjs +26267 -0
- package/dist/esm/graph.mjs +5409 -0
- package/dist/esm/hash.mjs +1307 -0
- package/dist/esm/heap.mjs +1596 -0
- package/dist/esm/index.mjs +31254 -14674
- package/dist/esm/linked-list.mjs +4569 -0
- package/dist/esm/matrix.mjs +1076 -0
- package/dist/esm/priority-queue.mjs +1372 -0
- package/dist/esm/queue.mjs +4260 -0
- package/dist/esm/stack.mjs +905 -0
- package/dist/esm/trie.mjs +1220 -0
- package/dist/esm-legacy/binary-tree.mjs +26304 -0
- package/dist/esm-legacy/graph.mjs +5407 -0
- package/dist/esm-legacy/hash.mjs +1307 -0
- package/dist/esm-legacy/heap.mjs +1593 -0
- package/dist/esm-legacy/index.mjs +31265 -14680
- package/dist/esm-legacy/linked-list.mjs +4575 -0
- package/dist/esm-legacy/matrix.mjs +1079 -0
- package/dist/esm-legacy/priority-queue.mjs +1370 -0
- package/dist/esm-legacy/queue.mjs +4258 -0
- package/dist/esm-legacy/stack.mjs +905 -0
- package/dist/esm-legacy/trie.mjs +1219 -0
- package/dist/types/common/error.d.ts +9 -0
- package/dist/types/common/index.d.ts +1 -1
- package/dist/types/data-structures/base/index.d.ts +1 -0
- package/dist/types/data-structures/base/iterable-entry-base.d.ts +8 -8
- package/dist/types/data-structures/base/linear-base.d.ts +3 -3
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +288 -0
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +336 -0
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +618 -18
- package/dist/types/data-structures/binary-tree/bst.d.ts +676 -1
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +456 -0
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +144 -1
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +3307 -399
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +3285 -360
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +2674 -325
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +3072 -287
- package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -4
- package/dist/types/data-structures/graph/directed-graph.d.ts +240 -0
- package/dist/types/data-structures/graph/undirected-graph.d.ts +216 -0
- package/dist/types/data-structures/hash/hash-map.d.ts +274 -10
- package/dist/types/data-structures/heap/heap.d.ts +336 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +411 -3
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +363 -3
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +434 -2
- package/dist/types/data-structures/matrix/matrix.d.ts +192 -0
- package/dist/types/data-structures/queue/deque.d.ts +364 -4
- package/dist/types/data-structures/queue/queue.d.ts +288 -0
- package/dist/types/data-structures/stack/stack.d.ts +240 -0
- package/dist/types/data-structures/trie/trie.d.ts +292 -4
- package/dist/types/interfaces/graph.d.ts +1 -1
- package/dist/types/types/common.d.ts +2 -2
- package/dist/types/types/data-structures/binary-tree/bst.d.ts +1 -0
- package/dist/types/types/data-structures/binary-tree/tree-map.d.ts +5 -0
- package/dist/types/types/data-structures/binary-tree/tree-multi-set.d.ts +4 -0
- package/dist/types/types/data-structures/binary-tree/tree-set.d.ts +4 -0
- package/dist/types/types/data-structures/heap/heap.d.ts +1 -0
- package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +1 -0
- package/dist/types/types/utils/validate-type.d.ts +4 -4
- package/dist/umd/data-structure-typed.js +31196 -14608
- package/dist/umd/data-structure-typed.min.js +11 -5
- package/docs-site-docusaurus/README.md +41 -0
- package/docs-site-docusaurus/docs/api/README.md +52 -0
- package/docs-site-docusaurus/docs/api/classes/AVLTree.md +6644 -0
- package/docs-site-docusaurus/docs/api/classes/AVLTreeNode.md +282 -0
- package/docs-site-docusaurus/docs/api/classes/AbstractGraph.md +2266 -0
- package/docs-site-docusaurus/docs/api/classes/BST.md +6293 -0
- package/docs-site-docusaurus/docs/api/classes/BSTNode.md +333 -0
- package/docs-site-docusaurus/docs/api/classes/BinaryIndexedTree.md +455 -0
- package/docs-site-docusaurus/docs/api/classes/BinaryTree.md +4647 -0
- package/docs-site-docusaurus/docs/api/classes/BinaryTreeNode.md +331 -0
- package/docs-site-docusaurus/docs/api/classes/Deque.md +2767 -0
- package/docs-site-docusaurus/docs/api/classes/DirectedGraph.md +2999 -0
- package/docs-site-docusaurus/docs/api/classes/DoublyLinkedList.md +2685 -0
- package/docs-site-docusaurus/docs/api/classes/DoublyLinkedListNode.md +221 -0
- package/docs-site-docusaurus/docs/api/classes/FibonacciHeap.md +253 -0
- package/docs-site-docusaurus/docs/api/classes/FibonacciHeapNode.md +21 -0
- package/docs-site-docusaurus/docs/api/classes/HashMap.md +1333 -0
- package/docs-site-docusaurus/docs/api/classes/Heap.md +1881 -0
- package/docs-site-docusaurus/docs/api/classes/IterableElementBase.md +800 -0
- package/docs-site-docusaurus/docs/api/classes/IterableEntryBase.md +644 -0
- package/docs-site-docusaurus/docs/api/classes/LinearBase.md +1632 -0
- package/docs-site-docusaurus/docs/api/classes/LinearLinkedBase.md +1853 -0
- package/docs-site-docusaurus/docs/api/classes/LinkedHashMap.md +1108 -0
- package/docs-site-docusaurus/docs/api/classes/LinkedListNode.md +156 -0
- package/docs-site-docusaurus/docs/api/classes/LinkedListQueue.md +2824 -0
- package/docs-site-docusaurus/docs/api/classes/MapGraph.md +2929 -0
- package/docs-site-docusaurus/docs/api/classes/Matrix.md +1026 -0
- package/docs-site-docusaurus/docs/api/classes/MaxHeap.md +1866 -0
- package/docs-site-docusaurus/docs/api/classes/MaxPriorityQueue.md +1883 -0
- package/docs-site-docusaurus/docs/api/classes/MinHeap.md +1879 -0
- package/docs-site-docusaurus/docs/api/classes/MinPriorityQueue.md +1882 -0
- package/docs-site-docusaurus/docs/api/classes/Navigator.md +109 -0
- package/docs-site-docusaurus/docs/api/classes/PriorityQueue.md +1839 -0
- package/docs-site-docusaurus/docs/api/classes/Queue.md +2244 -0
- package/docs-site-docusaurus/docs/api/classes/RedBlackTree.md +6888 -0
- package/docs-site-docusaurus/docs/api/classes/SegmentTree.md +372 -0
- package/docs-site-docusaurus/docs/api/classes/SinglyLinkedList.md +2897 -0
- package/docs-site-docusaurus/docs/api/classes/SinglyLinkedListNode.md +169 -0
- package/docs-site-docusaurus/docs/api/classes/SkipList.md +1229 -0
- package/docs-site-docusaurus/docs/api/classes/Stack.md +1573 -0
- package/docs-site-docusaurus/docs/api/classes/TreeMap.md +1389 -0
- package/docs-site-docusaurus/docs/api/classes/TreeMultiMap.md +1591 -0
- package/docs-site-docusaurus/docs/api/classes/TreeSet.md +1246 -0
- package/docs-site-docusaurus/docs/api/classes/Trie.md +1708 -0
- package/docs-site-docusaurus/docs/api/classes/TrieNode.md +199 -0
- package/docs-site-docusaurus/docs/api/classes/UndirectedGraph.md +2979 -0
- package/docs-site-docusaurus/docs/guide/_category_.json +6 -0
- package/docs-site-docusaurus/docs/guide/architecture.md +615 -0
- package/docs-site-docusaurus/docs/guide/concepts.md +451 -0
- package/docs-site-docusaurus/docs/guide/faq.md +180 -0
- package/docs-site-docusaurus/docs/guide/guides.md +597 -0
- package/docs-site-docusaurus/docs/guide/installation.md +62 -0
- package/docs-site-docusaurus/docs/guide/integrations.md +825 -0
- package/docs-site-docusaurus/docs/guide/overview.md +645 -0
- package/docs-site-docusaurus/docs/guide/performance.md +835 -0
- package/docs-site-docusaurus/docs/guide/quick-start.md +104 -0
- package/docs-site-docusaurus/docs/guide/use-cases/_category_.json +6 -0
- package/docs-site-docusaurus/docs/guide/use-cases/array-sort-alternative.md +158 -0
- package/docs-site-docusaurus/docs/guide/use-cases/heap-vs-sorting.md +92 -0
- package/docs-site-docusaurus/docs/guide/use-cases/map-vs-treemap.md +151 -0
- package/docs-site-docusaurus/docs/guide/use-cases/priority-queue-typescript.md +113 -0
- package/docs-site-docusaurus/docs/guide/use-cases/treemap-javascript.md +151 -0
- package/docs-site-docusaurus/docusaurus.config.ts +159 -0
- package/docs-site-docusaurus/fix-mdx-generics.mjs +75 -0
- package/docs-site-docusaurus/package-lock.json +18667 -0
- package/docs-site-docusaurus/package.json +50 -0
- package/docs-site-docusaurus/prefix-class-to-methods.mjs +48 -0
- package/docs-site-docusaurus/sidebars.ts +23 -0
- package/docs-site-docusaurus/sort-protected.mjs +87 -0
- package/docs-site-docusaurus/src/css/custom.css +96 -0
- package/docs-site-docusaurus/src/pages/index.module.css +13 -0
- package/docs-site-docusaurus/src/pages/index.tsx +120 -0
- package/docs-site-docusaurus/src/pages/markdown-page.md +7 -0
- package/docs-site-docusaurus/src/theme/TOCItems/index.tsx +34 -0
- package/docs-site-docusaurus/static/.nojekyll +0 -0
- package/docs-site-docusaurus/static/img/docusaurus-social-card.jpg +0 -0
- package/docs-site-docusaurus/static/img/docusaurus.png +0 -0
- package/docs-site-docusaurus/static/img/favicon.ico +0 -0
- package/docs-site-docusaurus/static/img/favicon.png +0 -0
- package/docs-site-docusaurus/static/img/logo-180.png +0 -0
- package/docs-site-docusaurus/static/img/logo.jpg +0 -0
- package/docs-site-docusaurus/static/img/logo.png +0 -0
- package/docs-site-docusaurus/static/img/logo.svg +1 -0
- package/docs-site-docusaurus/static/img/og-image.png +0 -0
- package/docs-site-docusaurus/static/img/undraw_docusaurus_mountain.svg +171 -0
- package/docs-site-docusaurus/static/img/undraw_docusaurus_react.svg +170 -0
- package/docs-site-docusaurus/static/img/undraw_docusaurus_tree.svg +40 -0
- package/docs-site-docusaurus/static/llms.txt +37 -0
- package/docs-site-docusaurus/static/robots.txt +4 -0
- package/docs-site-docusaurus/typedoc.json +23 -0
- package/llms.txt +37 -0
- package/package.json +159 -55
- package/src/common/error.ts +19 -1
- package/src/common/index.ts +1 -1
- package/src/data-structures/base/index.ts +1 -0
- package/src/data-structures/base/iterable-element-base.ts +3 -2
- package/src/data-structures/base/iterable-entry-base.ts +8 -8
- package/src/data-structures/base/linear-base.ts +3 -3
- package/src/data-structures/binary-tree/avl-tree.ts +287 -0
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +327 -5
- package/src/data-structures/binary-tree/binary-tree.ts +581 -6
- package/src/data-structures/binary-tree/bst.ts +922 -7
- package/src/data-structures/binary-tree/red-black-tree.ts +453 -0
- package/src/data-structures/binary-tree/segment-tree.ts +139 -2
- package/src/data-structures/binary-tree/tree-map.ts +3300 -495
- package/src/data-structures/binary-tree/tree-multi-map.ts +3384 -563
- package/src/data-structures/binary-tree/tree-multi-set.ts +2757 -493
- package/src/data-structures/binary-tree/tree-set.ts +3122 -440
- package/src/data-structures/graph/abstract-graph.ts +6 -6
- package/src/data-structures/graph/directed-graph.ts +230 -0
- package/src/data-structures/graph/undirected-graph.ts +207 -0
- package/src/data-structures/hash/hash-map.ts +270 -19
- package/src/data-structures/heap/heap.ts +326 -4
- package/src/data-structures/heap/max-heap.ts +2 -2
- package/src/data-structures/linked-list/doubly-linked-list.ts +394 -3
- package/src/data-structures/linked-list/singly-linked-list.ts +348 -3
- package/src/data-structures/linked-list/skip-linked-list.ts +421 -7
- package/src/data-structures/matrix/matrix.ts +194 -10
- package/src/data-structures/priority-queue/max-priority-queue.ts +2 -2
- package/src/data-structures/queue/deque.ts +350 -5
- package/src/data-structures/queue/queue.ts +276 -0
- package/src/data-structures/stack/stack.ts +230 -0
- package/src/data-structures/trie/trie.ts +283 -7
- package/src/interfaces/graph.ts +1 -1
- package/src/types/common.ts +2 -2
- package/src/types/data-structures/binary-tree/bst.ts +1 -0
- package/src/types/data-structures/binary-tree/tree-map.ts +6 -0
- package/src/types/data-structures/binary-tree/tree-multi-set.ts +5 -0
- package/src/types/data-structures/binary-tree/tree-set.ts +5 -0
- package/src/types/data-structures/heap/heap.ts +1 -0
- package/src/types/data-structures/priority-queue/priority-queue.ts +1 -0
- package/src/types/utils/validate-type.ts +4 -4
- package/vercel.json +6 -0
- package/dist/leetcode/avl-tree-counter.mjs +0 -2957
- package/dist/leetcode/avl-tree-multi-map.mjs +0 -2889
- package/dist/leetcode/avl-tree.mjs +0 -2720
- package/dist/leetcode/binary-tree.mjs +0 -1594
- package/dist/leetcode/bst.mjs +0 -2398
- package/dist/leetcode/deque.mjs +0 -683
- package/dist/leetcode/directed-graph.mjs +0 -1733
- package/dist/leetcode/doubly-linked-list.mjs +0 -709
- package/dist/leetcode/hash-map.mjs +0 -493
- package/dist/leetcode/heap.mjs +0 -542
- package/dist/leetcode/max-heap.mjs +0 -375
- package/dist/leetcode/max-priority-queue.mjs +0 -383
- package/dist/leetcode/min-heap.mjs +0 -363
- package/dist/leetcode/min-priority-queue.mjs +0 -371
- package/dist/leetcode/priority-queue.mjs +0 -363
- package/dist/leetcode/queue.mjs +0 -943
- package/dist/leetcode/red-black-tree.mjs +0 -2765
- package/dist/leetcode/singly-linked-list.mjs +0 -754
- package/dist/leetcode/stack.mjs +0 -217
- package/dist/leetcode/tree-counter.mjs +0 -3039
- package/dist/leetcode/tree-multi-map.mjs +0 -2913
- package/dist/leetcode/trie.mjs +0 -413
- 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:
|
|
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))
|
|
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
|
-
|
|
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
|
}
|