max-priority-queue-typed 2.4.5 → 2.5.0
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/README.md +63 -0
- package/dist/cjs/index.cjs +400 -119
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +399 -118
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +400 -119
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +399 -118
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +429 -78
- package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +212 -32
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
- package/dist/types/data-structures/graph/directed-graph.d.ts +219 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +204 -59
- package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
- package/dist/types/data-structures/heap/heap.d.ts +287 -99
- package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
- package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
- package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
- package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
- package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
- package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
- package/dist/types/data-structures/queue/deque.d.ts +272 -65
- package/dist/types/data-structures/queue/queue.d.ts +211 -42
- package/dist/types/data-structures/stack/stack.d.ts +174 -32
- package/dist/types/data-structures/trie/trie.d.ts +213 -43
- package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
- package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
- package/dist/umd/max-priority-queue-typed.js +397 -116
- package/dist/umd/max-priority-queue-typed.js.map +1 -1
- package/dist/umd/max-priority-queue-typed.min.js +1 -1
- package/dist/umd/max-priority-queue-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/data-structures/base/iterable-element-base.ts +4 -5
- package/src/data-structures/binary-tree/avl-tree.ts +134 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +302 -247
- package/src/data-structures/binary-tree/binary-tree.ts +429 -79
- package/src/data-structures/binary-tree/bst.ts +335 -34
- package/src/data-structures/binary-tree/red-black-tree.ts +290 -97
- package/src/data-structures/binary-tree/segment-tree.ts +372 -248
- package/src/data-structures/binary-tree/tree-map.ts +1284 -6
- package/src/data-structures/binary-tree/tree-multi-map.ts +1094 -211
- package/src/data-structures/binary-tree/tree-multi-set.ts +858 -65
- package/src/data-structures/binary-tree/tree-set.ts +1136 -9
- package/src/data-structures/graph/directed-graph.ts +219 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +204 -59
- package/src/data-structures/hash/hash-map.ts +230 -77
- package/src/data-structures/heap/heap.ts +287 -99
- package/src/data-structures/heap/max-heap.ts +46 -0
- package/src/data-structures/heap/min-heap.ts +59 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +286 -44
- package/src/data-structures/linked-list/singly-linked-list.ts +278 -65
- package/src/data-structures/linked-list/skip-linked-list.ts +689 -90
- package/src/data-structures/matrix/matrix.ts +416 -12
- package/src/data-structures/priority-queue/max-priority-queue.ts +57 -0
- package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
- package/src/data-structures/priority-queue/priority-queue.ts +60 -0
- package/src/data-structures/queue/deque.ts +272 -65
- package/src/data-structures/queue/queue.ts +211 -42
- package/src/data-structures/stack/stack.ts +174 -32
- package/src/data-structures/trie/trie.ts +213 -43
- package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
- package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
|
@@ -105,6 +105,7 @@ export class BSTNode<K = any, V = any> {
|
|
|
105
105
|
*
|
|
106
106
|
* @returns The height.
|
|
107
107
|
*/
|
|
108
|
+
/* istanbul ignore next -- covered by AVLTree/RedBlackTree tests (subclass uses height) */
|
|
108
109
|
get height(): number {
|
|
109
110
|
return this._height;
|
|
110
111
|
}
|
|
@@ -115,6 +116,7 @@ export class BSTNode<K = any, V = any> {
|
|
|
115
116
|
*
|
|
116
117
|
* @param value - The new height.
|
|
117
118
|
*/
|
|
119
|
+
/* istanbul ignore next -- covered by AVLTree/RedBlackTree tests (subclass uses height) */
|
|
118
120
|
set height(value: number) {
|
|
119
121
|
this._height = value;
|
|
120
122
|
}
|
|
@@ -127,6 +129,7 @@ export class BSTNode<K = any, V = any> {
|
|
|
127
129
|
*
|
|
128
130
|
* @returns The node's color.
|
|
129
131
|
*/
|
|
132
|
+
/* istanbul ignore next -- covered by RedBlackTree tests (subclass uses color) */
|
|
130
133
|
get color(): RBTNColor {
|
|
131
134
|
return this._color;
|
|
132
135
|
}
|
|
@@ -137,6 +140,7 @@ export class BSTNode<K = any, V = any> {
|
|
|
137
140
|
*
|
|
138
141
|
* @param value - The new color.
|
|
139
142
|
*/
|
|
143
|
+
/* istanbul ignore next -- covered by RedBlackTree tests (subclass uses color) */
|
|
140
144
|
set color(value: RBTNColor) {
|
|
141
145
|
this._color = value;
|
|
142
146
|
}
|
|
@@ -149,6 +153,7 @@ export class BSTNode<K = any, V = any> {
|
|
|
149
153
|
*
|
|
150
154
|
* @returns The subtree node count.
|
|
151
155
|
*/
|
|
156
|
+
/* istanbul ignore next -- internal field used by subclasses */
|
|
152
157
|
get count(): number {
|
|
153
158
|
return this._count;
|
|
154
159
|
}
|
|
@@ -159,6 +164,7 @@ export class BSTNode<K = any, V = any> {
|
|
|
159
164
|
*
|
|
160
165
|
* @param value - The new count.
|
|
161
166
|
*/
|
|
167
|
+
/* istanbul ignore next -- internal field used by subclasses */
|
|
162
168
|
set count(value: number) {
|
|
163
169
|
this._count = value;
|
|
164
170
|
}
|
|
@@ -200,34 +206,6 @@ export class BSTNode<K = any, V = any> {
|
|
|
200
206
|
* 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.
|
|
201
207
|
*
|
|
202
208
|
* @example
|
|
203
|
-
* // basic BST creation and add operation
|
|
204
|
-
* // Create a simple BST with numeric keys
|
|
205
|
-
* const bst = new BST<number>([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]);
|
|
206
|
-
*
|
|
207
|
-
* // Keep the example output in source comments but avoid noisy test logs.
|
|
208
|
-
* await withMutedConsole(() => bst.print());
|
|
209
|
-
* // _______8__________
|
|
210
|
-
* // / \
|
|
211
|
-
* // ___4___ ____12_____
|
|
212
|
-
* // / \ / \
|
|
213
|
-
* // _2_ _6_ _10__ _14__
|
|
214
|
-
* // / \ / \ / \ / \
|
|
215
|
-
* // 1 3 5 7 9 11 13 15__
|
|
216
|
-
* // \
|
|
217
|
-
* // 16
|
|
218
|
-
*
|
|
219
|
-
* // Verify size
|
|
220
|
-
* console.log(bst.size); // 16;
|
|
221
|
-
*
|
|
222
|
-
* // Add new elements
|
|
223
|
-
* bst.set(17);
|
|
224
|
-
* bst.set(0);
|
|
225
|
-
* console.log(bst.size); // 18;
|
|
226
|
-
*
|
|
227
|
-
* // Verify keys are searchable
|
|
228
|
-
* console.log(bst.has(11)); // true;
|
|
229
|
-
* console.log(bst.has(100)); // false;
|
|
230
|
-
* @example
|
|
231
209
|
* // BST delete and search after deletion
|
|
232
210
|
* const bst = new BST<number>([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]);
|
|
233
211
|
*
|
|
@@ -454,6 +432,36 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
454
432
|
return isComparable(key);
|
|
455
433
|
}
|
|
456
434
|
|
|
435
|
+
/**
|
|
436
|
+
* Depth-first search traversal
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
* @example
|
|
460
|
+
* // Depth-first traversal
|
|
461
|
+
* const bst = new BST<number>([5, 3, 7, 1, 4]);
|
|
462
|
+
* const inOrder = bst.dfs(node => node.key, 'IN');
|
|
463
|
+
* console.log(inOrder); // [1, 3, 4, 5, 7];
|
|
464
|
+
*/
|
|
457
465
|
override dfs(): (K | undefined)[];
|
|
458
466
|
|
|
459
467
|
override dfs<C extends NodeCallback<BSTNode<K, V>>>(
|
|
@@ -486,6 +494,28 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
486
494
|
return super.dfs(callback, pattern, onlyOne, startNode, iterationType);
|
|
487
495
|
}
|
|
488
496
|
|
|
497
|
+
/**
|
|
498
|
+
* BinaryTree level-order traversal
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
* @example
|
|
514
|
+
* // Breadth-first traversal
|
|
515
|
+
* const bst = new BST<number>([5, 3, 7]);
|
|
516
|
+
* const result = bst.bfs(node => node.key);
|
|
517
|
+
* console.log(result.length); // 3;
|
|
518
|
+
*/
|
|
489
519
|
override bfs(): (K | undefined)[];
|
|
490
520
|
override bfs<C extends NodeCallback<BSTNode<K, V>>>(
|
|
491
521
|
callback: C,
|
|
@@ -511,6 +541,34 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
511
541
|
return super.bfs(callback, startNode, iterationType, false);
|
|
512
542
|
}
|
|
513
543
|
|
|
544
|
+
/**
|
|
545
|
+
* Level-order grouping
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
* @example
|
|
564
|
+
* // Level-order grouping
|
|
565
|
+
* const bst = new BST<number>([5, 3, 7, 1, 4]);
|
|
566
|
+
* const levels = bst.listLevels(node => node.key);
|
|
567
|
+
* console.log(levels.length); // > 0;
|
|
568
|
+
* console.log(levels[0].length); // 1; // root level has 1 node
|
|
569
|
+
* const allKeys = levels.flat().sort((a, b) => a - b);
|
|
570
|
+
* console.log(allKeys); // [1, 3, 4, 5, 7];
|
|
571
|
+
*/
|
|
514
572
|
override listLevels(): (K | undefined)[][];
|
|
515
573
|
|
|
516
574
|
override listLevels<C extends NodeCallback<BSTNode<K, V>>>(
|
|
@@ -545,6 +603,31 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
545
603
|
* @param [startNode=this._root] - The node to start the search from.
|
|
546
604
|
* @param [iterationType=this.iterationType] - The traversal method.
|
|
547
605
|
* @returns The first matching node, or undefined if not found.
|
|
606
|
+
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
* @example
|
|
626
|
+
* // Get node object by key
|
|
627
|
+
* const bst = new BST<number, string>([[5, 'root'], [3, 'left'], [7, 'right']]);
|
|
628
|
+
* const node = bst.getNode(3);
|
|
629
|
+
* console.log(node?.key); // 3;
|
|
630
|
+
* console.log(node?.value); // 'left';
|
|
548
631
|
*/
|
|
549
632
|
override getNode(
|
|
550
633
|
keyNodeEntryOrPredicate:
|
|
@@ -606,6 +689,26 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
606
689
|
}
|
|
607
690
|
|
|
608
691
|
|
|
692
|
+
/**
|
|
693
|
+
* Search nodes by predicate
|
|
694
|
+
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
* @example
|
|
707
|
+
* // Search nodes by predicate
|
|
708
|
+
* const bst = new BST<number, string>([[1, 'a'], [2, 'b'], [3, 'c'], [4, 'd']]);
|
|
709
|
+
* const found = bst.search(node => node.key > 2, true);
|
|
710
|
+
* console.log(found.length); // >= 1;
|
|
711
|
+
*/
|
|
609
712
|
override search(
|
|
610
713
|
keyNodeEntryOrPredicate:
|
|
611
714
|
| K
|
|
@@ -699,6 +802,7 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
699
802
|
let predicate: NodePredicate<BSTNode<K, V>>;
|
|
700
803
|
if (isRange) {
|
|
701
804
|
predicate = node => {
|
|
805
|
+
/* istanbul ignore next -- node is always defined in iteration callbacks */
|
|
702
806
|
if (!node) return false;
|
|
703
807
|
return (keyNodeEntryOrPredicate).isInRange(node.key, this._comparator);
|
|
704
808
|
};
|
|
@@ -708,7 +812,7 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
708
812
|
|
|
709
813
|
// Optimization: Pruning logic
|
|
710
814
|
const shouldVisitLeft = (cur: BSTNode<K, V> | null | undefined) => {
|
|
711
|
-
if (!cur) return false;
|
|
815
|
+
/* istanbul ignore next -- defensive: cur is always defined when called from iteration */ if (!cur) return false;
|
|
712
816
|
if (!this.isRealNode(cur.left)) return false;
|
|
713
817
|
if (isRange) {
|
|
714
818
|
// Range search: Only go left if the current key is >= the lower bound
|
|
@@ -726,7 +830,7 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
726
830
|
};
|
|
727
831
|
|
|
728
832
|
const shouldVisitRight = (cur: BSTNode<K, V> | null | undefined) => {
|
|
729
|
-
if (!cur) return false;
|
|
833
|
+
/* istanbul ignore next -- defensive */ if (!cur) return false;
|
|
730
834
|
if (!this.isRealNode(cur.right)) return false;
|
|
731
835
|
if (isRange) {
|
|
732
836
|
// Range search: Only go right if current key <= upper bound
|
|
@@ -757,6 +861,24 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
757
861
|
);
|
|
758
862
|
}
|
|
759
863
|
|
|
864
|
+
/**
|
|
865
|
+
* Find all keys in a range
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
|
|
872
|
+
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
* @example
|
|
878
|
+
* // Find all keys in a range
|
|
879
|
+
* const bst = new BST<number>([10, 20, 30, 40, 50]);
|
|
880
|
+
* console.log(bst.rangeSearch([15, 35])); // [20, 30];
|
|
881
|
+
*/
|
|
760
882
|
rangeSearch(range: Range<K> | [K, K]): (K | undefined)[];
|
|
761
883
|
|
|
762
884
|
rangeSearch<C extends NodeCallback<BSTNode<K, V>>>(
|
|
@@ -794,6 +916,37 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
794
916
|
* @param keyNodeOrEntry - The key, node, or entry to set.
|
|
795
917
|
* @param [value] - The value, if providing just a key.
|
|
796
918
|
* @returns True if the addition was successful, false otherwise.
|
|
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
|
+
* @example
|
|
945
|
+
* // Set a key-value pair
|
|
946
|
+
* const bst = new BST<number, string>();
|
|
947
|
+
* bst.set(1, 'one');
|
|
948
|
+
* bst.set(2, 'two');
|
|
949
|
+
* console.log(bst.get(1)); // 'one';
|
|
797
950
|
*/
|
|
798
951
|
override set(
|
|
799
952
|
keyNodeOrEntry: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
|
|
@@ -836,6 +989,7 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
836
989
|
if (current.right !== null) current = current.right;
|
|
837
990
|
}
|
|
838
991
|
}
|
|
992
|
+
/* istanbul ignore next -- defensive: traversal always finds undefined slot before exhausting tree */
|
|
839
993
|
return false;
|
|
840
994
|
}
|
|
841
995
|
|
|
@@ -850,6 +1004,23 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
850
1004
|
* @param [isBalanceAdd=true] - If true, builds a balanced tree from the items.
|
|
851
1005
|
* @param [iterationType=this.iterationType] - The traversal method for balanced set (recursive or iterative).
|
|
852
1006
|
* @returns An array of booleans indicating the success of each individual `set` operation.
|
|
1007
|
+
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
|
|
1014
|
+
|
|
1015
|
+
|
|
1016
|
+
|
|
1017
|
+
|
|
1018
|
+
* @example
|
|
1019
|
+
* // Set multiple key-value pairs
|
|
1020
|
+
* const bst = new BST<number, string>();
|
|
1021
|
+
* bst.setMany([[1, 'a'], [2, 'b'], [3, 'c']]);
|
|
1022
|
+
* console.log(bst.size); // 3;
|
|
1023
|
+
* console.log(bst.get(2)); // 'b';
|
|
853
1024
|
*/
|
|
854
1025
|
override setMany(
|
|
855
1026
|
keysNodesEntriesOrRaws: Iterable<R | BTNRep<K, V, BSTNode<K, V>>>,
|
|
@@ -920,6 +1091,7 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
920
1091
|
const stack: Array<[number, number]> = [[0, n - 1]];
|
|
921
1092
|
while (stack.length > 0) {
|
|
922
1093
|
const popped = stack.pop();
|
|
1094
|
+
/* istanbul ignore next -- stack.pop() on non-empty stack always returns a value */
|
|
923
1095
|
if (!popped) continue;
|
|
924
1096
|
const [l, r] = popped;
|
|
925
1097
|
if (l > r) continue;
|
|
@@ -947,6 +1119,23 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
947
1119
|
* Equivalent to Java TreeMap.ceiling.
|
|
948
1120
|
* Time Complexity: O(log n) average, O(h) worst case.
|
|
949
1121
|
* Space Complexity: O(h) for recursion, O(1) for iteration.
|
|
1122
|
+
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
|
|
1132
|
+
|
|
1133
|
+
* @example
|
|
1134
|
+
* // Find the least key ≥ target
|
|
1135
|
+
* const bst = new BST<number>([10, 20, 30, 40, 50]);
|
|
1136
|
+
* console.log(bst.ceiling(25)); // 30;
|
|
1137
|
+
* console.log(bst.ceiling(30)); // 30;
|
|
1138
|
+
* console.log(bst.ceiling(55)); // undefined;
|
|
950
1139
|
*/
|
|
951
1140
|
ceiling(
|
|
952
1141
|
keyNodeEntryOrPredicate:
|
|
@@ -1012,6 +1201,22 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
1012
1201
|
* Equivalent to Java TreeMap.higher.
|
|
1013
1202
|
* Time Complexity: O(log n) average, O(h) worst case.
|
|
1014
1203
|
* Space Complexity: O(h) for recursion, O(1) for iteration.
|
|
1204
|
+
|
|
1205
|
+
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
|
|
1209
|
+
|
|
1210
|
+
|
|
1211
|
+
|
|
1212
|
+
|
|
1213
|
+
|
|
1214
|
+
|
|
1215
|
+
* @example
|
|
1216
|
+
* // Find the least key strictly > target
|
|
1217
|
+
* const bst = new BST<number>([10, 20, 30, 40]);
|
|
1218
|
+
* console.log(bst.higher(20)); // 30;
|
|
1219
|
+
* console.log(bst.higher(40)); // undefined;
|
|
1015
1220
|
*/
|
|
1016
1221
|
higher(
|
|
1017
1222
|
keyNodeEntryOrPredicate:
|
|
@@ -1077,6 +1282,23 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
1077
1282
|
* Equivalent to Java TreeMap.floor.
|
|
1078
1283
|
* Time Complexity: O(log n) average, O(h) worst case.
|
|
1079
1284
|
* Space Complexity: O(h) for recursion, O(1) for iteration.
|
|
1285
|
+
|
|
1286
|
+
|
|
1287
|
+
|
|
1288
|
+
|
|
1289
|
+
|
|
1290
|
+
|
|
1291
|
+
|
|
1292
|
+
|
|
1293
|
+
|
|
1294
|
+
|
|
1295
|
+
|
|
1296
|
+
* @example
|
|
1297
|
+
* // Find the greatest key ≤ target
|
|
1298
|
+
* const bst = new BST<number>([10, 20, 30, 40, 50]);
|
|
1299
|
+
* console.log(bst.floor(25)); // 20;
|
|
1300
|
+
* console.log(bst.floor(10)); // 10;
|
|
1301
|
+
* console.log(bst.floor(5)); // undefined;
|
|
1080
1302
|
*/
|
|
1081
1303
|
floor(
|
|
1082
1304
|
keyNodeEntryOrPredicate:
|
|
@@ -1117,7 +1339,7 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
1117
1339
|
iterationType?: IterationType
|
|
1118
1340
|
): K | undefined | ReturnType<C> {
|
|
1119
1341
|
if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === undefined) {
|
|
1120
|
-
if (typeof callback === 'string' || !callback) {
|
|
1342
|
+
/* istanbul ignore next */ if (typeof callback === 'string' || !callback) {
|
|
1121
1343
|
return undefined;
|
|
1122
1344
|
}
|
|
1123
1345
|
return undefined;
|
|
@@ -1151,7 +1373,7 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
1151
1373
|
} else if (this.isEntry(keyNodeEntryOrPredicate)) {
|
|
1152
1374
|
const key = keyNodeEntryOrPredicate[0];
|
|
1153
1375
|
if (key === null || key === undefined) {
|
|
1154
|
-
if (typeof callback === 'string' || !callback) {
|
|
1376
|
+
/* istanbul ignore next */ if (typeof callback === 'string' || !callback) {
|
|
1155
1377
|
return undefined;
|
|
1156
1378
|
}
|
|
1157
1379
|
return undefined;
|
|
@@ -1164,6 +1386,7 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
1164
1386
|
if (targetKey !== undefined) {
|
|
1165
1387
|
const node = this._floorByKey(targetKey, actualIterationType);
|
|
1166
1388
|
|
|
1389
|
+
/* istanbul ignore next */
|
|
1167
1390
|
if (!actualCallback) {
|
|
1168
1391
|
return node?.key;
|
|
1169
1392
|
}
|
|
@@ -1171,9 +1394,11 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
1171
1394
|
return node ? actualCallback(node) : undefined;
|
|
1172
1395
|
}
|
|
1173
1396
|
|
|
1397
|
+
/* istanbul ignore next -- targetKey is always defined if we reach here (null/undefined caught above) */
|
|
1174
1398
|
if (typeof callback === 'string' || !callback) {
|
|
1175
1399
|
return undefined;
|
|
1176
1400
|
}
|
|
1401
|
+
/* istanbul ignore next */
|
|
1177
1402
|
return undefined;
|
|
1178
1403
|
}
|
|
1179
1404
|
|
|
@@ -1182,6 +1407,22 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
1182
1407
|
* Equivalent to Java TreeMap.lower.
|
|
1183
1408
|
* Time Complexity: O(log n) average, O(h) worst case.
|
|
1184
1409
|
* Space Complexity: O(h) for recursion, O(1) for iteration.
|
|
1410
|
+
|
|
1411
|
+
|
|
1412
|
+
|
|
1413
|
+
|
|
1414
|
+
|
|
1415
|
+
|
|
1416
|
+
|
|
1417
|
+
|
|
1418
|
+
|
|
1419
|
+
|
|
1420
|
+
|
|
1421
|
+
* @example
|
|
1422
|
+
* // Find the greatest key strictly < target
|
|
1423
|
+
* const bst = new BST<number>([10, 20, 30, 40]);
|
|
1424
|
+
* console.log(bst.lower(30)); // 20;
|
|
1425
|
+
* console.log(bst.lower(10)); // undefined;
|
|
1185
1426
|
*/
|
|
1186
1427
|
lower(
|
|
1187
1428
|
keyNodeEntryOrPredicate:
|
|
@@ -1222,9 +1463,10 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
1222
1463
|
iterationType?: IterationType
|
|
1223
1464
|
): K | undefined | ReturnType<C> {
|
|
1224
1465
|
if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === undefined) {
|
|
1225
|
-
if (typeof callback === 'string' || !callback) {
|
|
1466
|
+
/* istanbul ignore next */ if (typeof callback === 'string' || !callback) {
|
|
1226
1467
|
return undefined;
|
|
1227
1468
|
}
|
|
1469
|
+
/* istanbul ignore next */
|
|
1228
1470
|
return undefined;
|
|
1229
1471
|
}
|
|
1230
1472
|
|
|
@@ -1256,9 +1498,10 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
1256
1498
|
} else if (this.isEntry(keyNodeEntryOrPredicate)) {
|
|
1257
1499
|
const key = keyNodeEntryOrPredicate[0];
|
|
1258
1500
|
if (key === null || key === undefined) {
|
|
1259
|
-
if (typeof callback === 'string' || !callback) {
|
|
1501
|
+
/* istanbul ignore next */ if (typeof callback === 'string' || !callback) {
|
|
1260
1502
|
return undefined;
|
|
1261
1503
|
}
|
|
1504
|
+
/* istanbul ignore next */
|
|
1262
1505
|
return undefined;
|
|
1263
1506
|
}
|
|
1264
1507
|
targetKey = key;
|
|
@@ -1276,9 +1519,11 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
1276
1519
|
return node ? actualCallback(node) : undefined;
|
|
1277
1520
|
}
|
|
1278
1521
|
|
|
1522
|
+
/* istanbul ignore next -- targetKey is always defined if we reach here (null/undefined caught above) */
|
|
1279
1523
|
if (typeof callback === 'string' || !callback) {
|
|
1280
1524
|
return undefined;
|
|
1281
1525
|
}
|
|
1526
|
+
/* istanbul ignore next */
|
|
1282
1527
|
return undefined;
|
|
1283
1528
|
}
|
|
1284
1529
|
|
|
@@ -1345,6 +1590,23 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
1345
1590
|
*
|
|
1346
1591
|
* @param [iterationType=this.iterationType] - The traversal method for the initial node export.
|
|
1347
1592
|
* @returns True if successful, false if the tree was empty.
|
|
1593
|
+
|
|
1594
|
+
|
|
1595
|
+
|
|
1596
|
+
|
|
1597
|
+
|
|
1598
|
+
|
|
1599
|
+
|
|
1600
|
+
|
|
1601
|
+
|
|
1602
|
+
* @example
|
|
1603
|
+
* // Rebalance the tree
|
|
1604
|
+
* const bst = new BST<number>();
|
|
1605
|
+
* // Insert in sorted order (worst case for BST)
|
|
1606
|
+
* for (let i = 1; i <= 7; i++) bst.add(i);
|
|
1607
|
+
* console.log(bst.isAVLBalanced()); // false;
|
|
1608
|
+
* bst.perfectlyBalance();
|
|
1609
|
+
* console.log(bst.isAVLBalanced()); // true;
|
|
1348
1610
|
*/
|
|
1349
1611
|
perfectlyBalance(iterationType: IterationType = this.iterationType): boolean {
|
|
1350
1612
|
const nodes = this.dfs(node => node, 'IN', false, this._root, iterationType);
|
|
@@ -1377,6 +1639,19 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
1377
1639
|
*
|
|
1378
1640
|
* @param [iterationType=this.iterationType] - The traversal method.
|
|
1379
1641
|
* @returns True if the tree is AVL balanced, false otherwise.
|
|
1642
|
+
|
|
1643
|
+
|
|
1644
|
+
|
|
1645
|
+
|
|
1646
|
+
|
|
1647
|
+
|
|
1648
|
+
|
|
1649
|
+
|
|
1650
|
+
|
|
1651
|
+
* @example
|
|
1652
|
+
* // Check if tree is height-balanced
|
|
1653
|
+
* const bst = new BST<number>([3, 1, 5, 2, 4]);
|
|
1654
|
+
* console.log(bst.isAVLBalanced()); // true;
|
|
1380
1655
|
*/
|
|
1381
1656
|
isAVLBalanced(iterationType: IterationType = this.iterationType): boolean {
|
|
1382
1657
|
if (!this._root) return true;
|
|
@@ -1434,6 +1709,30 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
1434
1709
|
* @param [options] - Options for the new BST.
|
|
1435
1710
|
* @param [thisArg] - `this` context for the callback.
|
|
1436
1711
|
* @returns A new, mapped BST.
|
|
1712
|
+
|
|
1713
|
+
|
|
1714
|
+
|
|
1715
|
+
|
|
1716
|
+
|
|
1717
|
+
|
|
1718
|
+
|
|
1719
|
+
|
|
1720
|
+
|
|
1721
|
+
|
|
1722
|
+
|
|
1723
|
+
|
|
1724
|
+
|
|
1725
|
+
|
|
1726
|
+
|
|
1727
|
+
|
|
1728
|
+
|
|
1729
|
+
|
|
1730
|
+
|
|
1731
|
+
* @example
|
|
1732
|
+
* // Transform to new tree
|
|
1733
|
+
* const bst = new BST<number, number>([[1, 10], [2, 20], [3, 30]]);
|
|
1734
|
+
* const doubled = bst.map((value, key) => [key, (value ?? 0) * 2] as [number, number]);
|
|
1735
|
+
* console.log([...doubled.values()]); // [20, 40, 60];
|
|
1437
1736
|
*/
|
|
1438
1737
|
override map<MK = K, MV = V, MR = any>(
|
|
1439
1738
|
callback: EntryCallback<K, V | undefined, [MK, MV]>,
|
|
@@ -1523,6 +1822,7 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
1523
1822
|
return 0;
|
|
1524
1823
|
}
|
|
1525
1824
|
|
|
1825
|
+
/* istanbul ignore next -- Date objects satisfy isComparable(), so this branch is unreachable via default comparator */
|
|
1526
1826
|
// Date keys: compare by getTime()
|
|
1527
1827
|
if (a instanceof Date && b instanceof Date) {
|
|
1528
1828
|
const ta = a.getTime();
|
|
@@ -1831,6 +2131,7 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
1831
2131
|
return this._boundByKey(targetKey, isLower, iterationType);
|
|
1832
2132
|
}
|
|
1833
2133
|
|
|
2134
|
+
/* istanbul ignore next -- defensive: targetKey is always defined if predicate path was skipped */
|
|
1834
2135
|
return undefined;
|
|
1835
2136
|
}
|
|
1836
2137
|
|