binary-tree-typed 2.4.5 → 2.5.1
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 +0 -84
- package/dist/cjs/index.cjs +1476 -404
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +1473 -401
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +1476 -404
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +1473 -401
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/data-structures/base/index.d.ts +1 -0
- package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
- 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 +380 -51
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +487 -147
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +956 -80
- package/dist/types/data-structures/binary-tree/bst.d.ts +816 -29
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +610 -31
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +326 -135
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +3781 -6
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +3607 -201
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +2874 -65
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +3528 -6
- package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -4
- package/dist/types/data-structures/graph/directed-graph.d.ts +429 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +393 -59
- package/dist/types/data-structures/hash/hash-map.d.ts +473 -89
- package/dist/types/data-structures/heap/heap.d.ts +581 -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 +646 -47
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +596 -68
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +793 -12
- package/dist/types/data-structures/matrix/matrix.d.ts +499 -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 +593 -71
- package/dist/types/data-structures/queue/queue.d.ts +463 -42
- package/dist/types/data-structures/stack/stack.d.ts +384 -32
- package/dist/types/data-structures/trie/trie.d.ts +470 -48
- 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/segment-tree.d.ts +1 -1
- package/dist/types/types/data-structures/heap/heap.d.ts +1 -0
- package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
- 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/binary-tree-typed.js +1469 -397
- package/dist/umd/binary-tree-typed.js.map +1 -1
- package/dist/umd/binary-tree-typed.min.js +5 -5
- package/dist/umd/binary-tree-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/data-structures/base/index.ts +1 -0
- package/src/data-structures/base/iterable-element-base.ts +4 -5
- 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 +386 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +596 -247
- package/src/data-structures/binary-tree/binary-tree.ts +956 -81
- package/src/data-structures/binary-tree/bst.ts +840 -35
- package/src/data-structures/binary-tree/red-black-tree.ts +689 -97
- package/src/data-structures/binary-tree/segment-tree.ts +498 -249
- package/src/data-structures/binary-tree/tree-map.ts +3784 -7
- package/src/data-structures/binary-tree/tree-multi-map.ts +3614 -211
- package/src/data-structures/binary-tree/tree-multi-set.ts +2874 -65
- package/src/data-structures/binary-tree/tree-set.ts +3531 -10
- package/src/data-structures/graph/abstract-graph.ts +4 -4
- package/src/data-structures/graph/directed-graph.ts +429 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +393 -59
- package/src/data-structures/hash/hash-map.ts +476 -92
- package/src/data-structures/heap/heap.ts +581 -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 +646 -47
- package/src/data-structures/linked-list/singly-linked-list.ts +596 -68
- package/src/data-structures/linked-list/skip-linked-list.ts +1067 -90
- package/src/data-structures/matrix/matrix.ts +584 -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 +592 -70
- package/src/data-structures/queue/queue.ts +463 -42
- package/src/data-structures/stack/stack.ts +384 -32
- package/src/data-structures/trie/trie.ts +470 -48
- package/src/interfaces/graph.ts +1 -1
- package/src/types/common.ts +2 -2
- package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
- package/src/types/data-structures/heap/heap.ts +1 -0
- package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
- package/src/types/data-structures/priority-queue/priority-queue.ts +1 -0
- package/src/types/utils/validate-type.ts +4 -4
|
@@ -98,16 +98,12 @@ export class RedBlackTreeNode<K = any, V = any> {
|
|
|
98
98
|
*
|
|
99
99
|
* @returns The height.
|
|
100
100
|
*/
|
|
101
|
+
/* istanbul ignore next -- covered by AVLTree tests (subclass uses height) */
|
|
101
102
|
get height(): number {
|
|
102
103
|
return this._height;
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
|
|
106
|
-
* Sets the height of the node.
|
|
107
|
-
* @remarks Time O(1), Space O(1)
|
|
108
|
-
*
|
|
109
|
-
* @param value - The new height.
|
|
110
|
-
*/
|
|
106
|
+
/* istanbul ignore next -- covered by AVLTree tests (subclass uses height) */
|
|
111
107
|
set height(value: number) {
|
|
112
108
|
this._height = value;
|
|
113
109
|
}
|
|
@@ -142,20 +138,11 @@ export class RedBlackTreeNode<K = any, V = any> {
|
|
|
142
138
|
*
|
|
143
139
|
* @returns The subtree node count.
|
|
144
140
|
*/
|
|
141
|
+
/* istanbul ignore next -- internal field, exercised indirectly via tree operations */
|
|
145
142
|
get count(): number {
|
|
146
143
|
return this._count;
|
|
147
144
|
}
|
|
148
145
|
|
|
149
|
-
/**
|
|
150
|
-
* Sets the count of nodes in the subtree.
|
|
151
|
-
* @remarks Time O(1), Space O(1)
|
|
152
|
-
*
|
|
153
|
-
* @param value - The new count.
|
|
154
|
-
*/
|
|
155
|
-
set count(value: number) {
|
|
156
|
-
this._count = value;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
146
|
/**
|
|
160
147
|
* Gets the position of the node relative to its parent.
|
|
161
148
|
* @remarks Time O(1), Space O(1)
|
|
@@ -173,6 +160,7 @@ export class RedBlackTreeNode<K = any, V = any> {
|
|
|
173
160
|
return this.left || this.right ? 'ROOT_RIGHT' : 'RIGHT';
|
|
174
161
|
}
|
|
175
162
|
|
|
163
|
+
/* istanbul ignore next -- defensive: unreachable if tree structure is correct */
|
|
176
164
|
return 'MAL_NODE';
|
|
177
165
|
}
|
|
178
166
|
}
|
|
@@ -187,23 +175,6 @@ export class RedBlackTreeNode<K = any, V = any> {
|
|
|
187
175
|
* 2. It is BST itself. Compared with Heap which is not completely ordered, RedBlackTree is completely ordered.
|
|
188
176
|
*
|
|
189
177
|
* @example
|
|
190
|
-
* // basic Red-Black Tree with simple number keys
|
|
191
|
-
* // Create a simple Red-Black Tree with numeric keys
|
|
192
|
-
* const tree = new RedBlackTree([5, 2, 8, 1, 9]);
|
|
193
|
-
*
|
|
194
|
-
* tree.print();
|
|
195
|
-
* // _2___
|
|
196
|
-
* // / \
|
|
197
|
-
* // 1 _8_
|
|
198
|
-
* // / \
|
|
199
|
-
* // 5 9
|
|
200
|
-
*
|
|
201
|
-
* // Verify the tree maintains sorted order
|
|
202
|
-
* console.log([...tree.keys()]); // [1, 2, 5, 8, 9];
|
|
203
|
-
*
|
|
204
|
-
* // Check size
|
|
205
|
-
* console.log(tree.size); // 5;
|
|
206
|
-
* @example
|
|
207
178
|
* // Red-Black Tree with key-value pairs for lookups
|
|
208
179
|
* interface Employee {
|
|
209
180
|
* id: number;
|
|
@@ -369,6 +340,130 @@ export class RedBlackTree<K = any, V = any, R = any> extends BST<K, V, R> implem
|
|
|
369
340
|
/**
|
|
370
341
|
* Remove all nodes and clear internal caches.
|
|
371
342
|
* @remarks Time O(n) average, Space O(1)
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
* @example
|
|
463
|
+
* // Remove all entries
|
|
464
|
+
* const rbt = new RedBlackTree<number>([1, 2, 3]);
|
|
465
|
+
* rbt.clear();
|
|
466
|
+
* console.log(rbt.isEmpty()); // true;
|
|
372
467
|
*/
|
|
373
468
|
override clear() {
|
|
374
469
|
super.clear();
|
|
@@ -604,10 +699,10 @@ export class RedBlackTree<K = any, V = any, R = any> extends BST<K, V, R> implem
|
|
|
604
699
|
if (hMin === NIL || hMax === NIL) {
|
|
605
700
|
this._setMinCache(newNode);
|
|
606
701
|
this._setMaxCache(newNode);
|
|
607
|
-
} else if (parent === hMax && lastCompared > 0) {
|
|
608
|
-
this._setMaxCache(newNode);
|
|
609
|
-
} else if (parent === hMin && lastCompared < 0) {
|
|
610
|
-
this._setMinCache(newNode);
|
|
702
|
+
} else /* istanbul ignore next -- boundary fast-paths at top of _setKVNode intercept boundary inserts before normal path */ if (parent === hMax && lastCompared > 0) {
|
|
703
|
+
/* istanbul ignore next */ this._setMaxCache(newNode);
|
|
704
|
+
} else /* istanbul ignore next */ if (parent === hMin && lastCompared < 0) {
|
|
705
|
+
/* istanbul ignore next */ this._setMinCache(newNode);
|
|
611
706
|
} else {
|
|
612
707
|
if (cmp(newNode.key, hMin.key) < 0) this._setMinCache(newNode);
|
|
613
708
|
if (cmp(newNode.key, hMax.key) > 0) this._setMaxCache(newNode);
|
|
@@ -701,6 +796,7 @@ export class RedBlackTree<K = any, V = any, R = any> extends BST<K, V, R> implem
|
|
|
701
796
|
return newNode;
|
|
702
797
|
}
|
|
703
798
|
|
|
799
|
+
/* istanbul ignore next -- structurally unreachable: predecessor never has a right child (it's the max of left subtree) */
|
|
704
800
|
return this._setKVNode(key, value)?.node;
|
|
705
801
|
}
|
|
706
802
|
|
|
@@ -741,6 +837,7 @@ export class RedBlackTree<K = any, V = any, R = any> extends BST<K, V, R> implem
|
|
|
741
837
|
return newNode;
|
|
742
838
|
}
|
|
743
839
|
|
|
840
|
+
/* istanbul ignore next -- structurally unreachable: successor never has a left child (it's the min of right subtree) */
|
|
744
841
|
return this._setKVNode(key, value)?.node;
|
|
745
842
|
}
|
|
746
843
|
|
|
@@ -760,6 +857,143 @@ export class RedBlackTree<K = any, V = any, R = any> extends BST<K, V, R> implem
|
|
|
760
857
|
* - updates via a single-pass search (no double walk)
|
|
761
858
|
*
|
|
762
859
|
* @remarks Time O(log n) average, Space O(1)
|
|
860
|
+
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
|
|
872
|
+
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
|
|
880
|
+
|
|
881
|
+
|
|
882
|
+
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
|
|
890
|
+
|
|
891
|
+
|
|
892
|
+
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
|
|
896
|
+
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
|
|
908
|
+
|
|
909
|
+
|
|
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
|
+
|
|
951
|
+
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
|
|
965
|
+
|
|
966
|
+
|
|
967
|
+
|
|
968
|
+
|
|
969
|
+
|
|
970
|
+
|
|
971
|
+
|
|
972
|
+
|
|
973
|
+
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
* @example
|
|
981
|
+
* // basic Red-Black Tree with simple number keys
|
|
982
|
+
* // Create a simple Red-Black Tree with numeric keys
|
|
983
|
+
* const tree = new RedBlackTree([5, 2, 8, 1, 9]);
|
|
984
|
+
*
|
|
985
|
+
* tree.print();
|
|
986
|
+
* // _2___
|
|
987
|
+
* // / \
|
|
988
|
+
* // 1 _8_
|
|
989
|
+
* // / \
|
|
990
|
+
* // 5 9
|
|
991
|
+
*
|
|
992
|
+
* // Verify the tree maintains sorted order
|
|
993
|
+
* console.log([...tree.keys()]); // [1, 2, 5, 8, 9];
|
|
994
|
+
*
|
|
995
|
+
* // Check size
|
|
996
|
+
* console.log(tree.size); // 5;
|
|
763
997
|
*/
|
|
764
998
|
override set(
|
|
765
999
|
keyNodeOrEntry: K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
|
|
@@ -812,6 +1046,7 @@ export class RedBlackTree<K = any, V = any, R = any> extends BST<K, V, R> implem
|
|
|
812
1046
|
}
|
|
813
1047
|
return true;
|
|
814
1048
|
}
|
|
1049
|
+
/* istanbul ignore next -- defensive: _insert only returns CREATED|UPDATED */
|
|
815
1050
|
return false;
|
|
816
1051
|
}
|
|
817
1052
|
|
|
@@ -820,6 +1055,134 @@ export class RedBlackTree<K = any, V = any, R = any> extends BST<K, V, R> implem
|
|
|
820
1055
|
* @remarks Time O(log n) average, Space O(1)
|
|
821
1056
|
* @param keyNodeEntryRawOrPredicate - Key, node, or [key, value] entry identifying the node to delete.
|
|
822
1057
|
* @returns Array with deletion metadata (removed node, rebalancing hint if any).
|
|
1058
|
+
|
|
1059
|
+
|
|
1060
|
+
|
|
1061
|
+
|
|
1062
|
+
|
|
1063
|
+
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
|
|
1105
|
+
|
|
1106
|
+
|
|
1107
|
+
|
|
1108
|
+
|
|
1109
|
+
|
|
1110
|
+
|
|
1111
|
+
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
|
|
1115
|
+
|
|
1116
|
+
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
|
|
1120
|
+
|
|
1121
|
+
|
|
1122
|
+
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
|
|
1135
|
+
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
|
|
1143
|
+
|
|
1144
|
+
|
|
1145
|
+
|
|
1146
|
+
|
|
1147
|
+
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+
|
|
1151
|
+
|
|
1152
|
+
|
|
1153
|
+
|
|
1154
|
+
|
|
1155
|
+
|
|
1156
|
+
|
|
1157
|
+
|
|
1158
|
+
|
|
1159
|
+
|
|
1160
|
+
|
|
1161
|
+
|
|
1162
|
+
|
|
1163
|
+
|
|
1164
|
+
|
|
1165
|
+
|
|
1166
|
+
|
|
1167
|
+
|
|
1168
|
+
|
|
1169
|
+
|
|
1170
|
+
|
|
1171
|
+
|
|
1172
|
+
|
|
1173
|
+
|
|
1174
|
+
|
|
1175
|
+
|
|
1176
|
+
|
|
1177
|
+
|
|
1178
|
+
|
|
1179
|
+
|
|
1180
|
+
* @example
|
|
1181
|
+
* // Remove and rebalance
|
|
1182
|
+
* const rbt = new RedBlackTree<number>([10, 5, 15, 3, 7]);
|
|
1183
|
+
* rbt.delete(5);
|
|
1184
|
+
* console.log(rbt.has(5)); // false;
|
|
1185
|
+
* console.log(rbt.size); // 4;
|
|
823
1186
|
*/
|
|
824
1187
|
override delete(
|
|
825
1188
|
keyNodeEntryRawOrPredicate: BTNRep<K, V, RedBlackTreeNode<K, V>> | NodePredicate<RedBlackTreeNode<K, V> | null>
|
|
@@ -842,39 +1205,38 @@ export class RedBlackTree<K = any, V = any, R = any> extends BST<K, V, R> implem
|
|
|
842
1205
|
const nextMax = willDeleteMax ? this._predecessorOf(nodeToDelete) : undefined;
|
|
843
1206
|
|
|
844
1207
|
let originalColor = nodeToDelete.color;
|
|
845
|
-
|
|
1208
|
+
const NIL = this.NIL;
|
|
1209
|
+
let replacementNode: RedBlackTreeNode<K, V> = NIL;
|
|
846
1210
|
|
|
847
1211
|
if (!this.isRealNode(nodeToDelete.left)) {
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
}
|
|
1212
|
+
// No real left child → replace with right (may be NIL)
|
|
1213
|
+
replacementNode = nodeToDelete.right ?? NIL;
|
|
1214
|
+
this._transplant(nodeToDelete, replacementNode);
|
|
852
1215
|
} else if (!this.isRealNode(nodeToDelete.right)) {
|
|
1216
|
+
// No real right child → replace with left
|
|
853
1217
|
replacementNode = nodeToDelete.left;
|
|
854
|
-
this._transplant(nodeToDelete,
|
|
1218
|
+
this._transplant(nodeToDelete, replacementNode);
|
|
855
1219
|
} else {
|
|
1220
|
+
// Two children → find in-order successor
|
|
856
1221
|
const successor = this.getLeftMost(node => node, nodeToDelete.right);
|
|
857
1222
|
if (successor) {
|
|
858
1223
|
originalColor = successor.color;
|
|
859
|
-
|
|
1224
|
+
replacementNode = successor.right ?? NIL;
|
|
860
1225
|
|
|
861
1226
|
if (successor.parent === nodeToDelete) {
|
|
862
|
-
if
|
|
863
|
-
|
|
864
|
-
}
|
|
1227
|
+
// Even if replacementNode is NIL, set its parent for fixup
|
|
1228
|
+
replacementNode.parent = successor;
|
|
865
1229
|
} else {
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
}
|
|
870
|
-
if (this.isRealNode(successor.right)) {
|
|
1230
|
+
this._transplant(successor, replacementNode);
|
|
1231
|
+
successor.right = nodeToDelete.right;
|
|
1232
|
+
if (successor.right) {
|
|
871
1233
|
successor.right.parent = successor;
|
|
872
1234
|
}
|
|
873
1235
|
}
|
|
874
1236
|
|
|
875
1237
|
this._transplant(nodeToDelete, successor);
|
|
876
1238
|
successor.left = nodeToDelete.left;
|
|
877
|
-
if (
|
|
1239
|
+
if (successor.left) {
|
|
878
1240
|
successor.left.parent = successor;
|
|
879
1241
|
}
|
|
880
1242
|
successor.color = nodeToDelete.color;
|
|
@@ -923,8 +1285,101 @@ export class RedBlackTree<K = any, V = any, R = any> extends BST<K, V, R> implem
|
|
|
923
1285
|
* Red-Black trees are self-balancing — `perfectlyBalance` rebuilds via
|
|
924
1286
|
* sorted bulk insert, which naturally produces a balanced RBT.
|
|
925
1287
|
* @remarks Time O(N), Space O(N)
|
|
1288
|
+
|
|
1289
|
+
|
|
1290
|
+
|
|
1291
|
+
|
|
1292
|
+
|
|
1293
|
+
|
|
1294
|
+
|
|
1295
|
+
|
|
1296
|
+
|
|
1297
|
+
|
|
1298
|
+
|
|
1299
|
+
|
|
1300
|
+
|
|
1301
|
+
|
|
1302
|
+
|
|
1303
|
+
|
|
1304
|
+
|
|
1305
|
+
|
|
1306
|
+
|
|
1307
|
+
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
|
|
1311
|
+
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
|
|
1320
|
+
|
|
1321
|
+
|
|
1322
|
+
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
|
|
1326
|
+
|
|
1327
|
+
|
|
1328
|
+
|
|
1329
|
+
|
|
1330
|
+
|
|
1331
|
+
|
|
1332
|
+
|
|
1333
|
+
|
|
1334
|
+
|
|
1335
|
+
|
|
1336
|
+
|
|
1337
|
+
|
|
1338
|
+
|
|
1339
|
+
|
|
1340
|
+
|
|
1341
|
+
|
|
1342
|
+
|
|
1343
|
+
|
|
1344
|
+
|
|
1345
|
+
|
|
1346
|
+
|
|
1347
|
+
|
|
1348
|
+
|
|
1349
|
+
|
|
1350
|
+
|
|
1351
|
+
|
|
1352
|
+
|
|
1353
|
+
|
|
1354
|
+
|
|
1355
|
+
|
|
1356
|
+
|
|
1357
|
+
|
|
1358
|
+
|
|
1359
|
+
|
|
1360
|
+
|
|
1361
|
+
|
|
1362
|
+
|
|
1363
|
+
|
|
1364
|
+
|
|
1365
|
+
|
|
1366
|
+
|
|
1367
|
+
|
|
1368
|
+
|
|
1369
|
+
|
|
1370
|
+
|
|
1371
|
+
|
|
1372
|
+
|
|
1373
|
+
|
|
1374
|
+
|
|
1375
|
+
|
|
1376
|
+
* @example
|
|
1377
|
+
* // Rebalance tree
|
|
1378
|
+
* const rbt = new RedBlackTree<number>([1, 2, 3, 4, 5]);
|
|
1379
|
+
* rbt.perfectlyBalance();
|
|
1380
|
+
* console.log(rbt.isAVLBalanced()); // true;
|
|
926
1381
|
*/
|
|
927
|
-
override perfectlyBalance(
|
|
1382
|
+
override perfectlyBalance(_iterationType?: IterationType): boolean {
|
|
928
1383
|
// Extract sorted entries, clear, re-insert — RBT self-balances on insert
|
|
929
1384
|
const entries: [K, V | undefined][] = [];
|
|
930
1385
|
for (const [key, value] of this) entries.push([key, value]);
|
|
@@ -938,6 +1393,133 @@ export class RedBlackTree<K = any, V = any, R = any> extends BST<K, V, R> implem
|
|
|
938
1393
|
return true;
|
|
939
1394
|
}
|
|
940
1395
|
|
|
1396
|
+
/**
|
|
1397
|
+
* Transform to new tree
|
|
1398
|
+
|
|
1399
|
+
|
|
1400
|
+
|
|
1401
|
+
|
|
1402
|
+
|
|
1403
|
+
|
|
1404
|
+
|
|
1405
|
+
|
|
1406
|
+
|
|
1407
|
+
|
|
1408
|
+
|
|
1409
|
+
|
|
1410
|
+
|
|
1411
|
+
|
|
1412
|
+
|
|
1413
|
+
|
|
1414
|
+
|
|
1415
|
+
|
|
1416
|
+
|
|
1417
|
+
|
|
1418
|
+
|
|
1419
|
+
|
|
1420
|
+
|
|
1421
|
+
|
|
1422
|
+
|
|
1423
|
+
|
|
1424
|
+
|
|
1425
|
+
|
|
1426
|
+
|
|
1427
|
+
|
|
1428
|
+
|
|
1429
|
+
|
|
1430
|
+
|
|
1431
|
+
|
|
1432
|
+
|
|
1433
|
+
|
|
1434
|
+
|
|
1435
|
+
|
|
1436
|
+
|
|
1437
|
+
|
|
1438
|
+
|
|
1439
|
+
|
|
1440
|
+
|
|
1441
|
+
|
|
1442
|
+
|
|
1443
|
+
|
|
1444
|
+
|
|
1445
|
+
|
|
1446
|
+
|
|
1447
|
+
|
|
1448
|
+
|
|
1449
|
+
|
|
1450
|
+
|
|
1451
|
+
|
|
1452
|
+
|
|
1453
|
+
|
|
1454
|
+
|
|
1455
|
+
|
|
1456
|
+
|
|
1457
|
+
|
|
1458
|
+
|
|
1459
|
+
|
|
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
|
+
|
|
1503
|
+
|
|
1504
|
+
|
|
1505
|
+
|
|
1506
|
+
|
|
1507
|
+
|
|
1508
|
+
|
|
1509
|
+
|
|
1510
|
+
|
|
1511
|
+
|
|
1512
|
+
|
|
1513
|
+
|
|
1514
|
+
|
|
1515
|
+
|
|
1516
|
+
|
|
1517
|
+
* @example
|
|
1518
|
+
* // Transform to new tree
|
|
1519
|
+
* const rbt = new RedBlackTree<number, number>([[1, 10], [2, 20]]);
|
|
1520
|
+
* const doubled = rbt.map((v, k) => [k, (v ?? 0) * 2] as [number, number]);
|
|
1521
|
+
* console.log([...doubled.values()]); // [20, 40];
|
|
1522
|
+
*/
|
|
941
1523
|
override map<MK = K, MV = V, MR = any>(
|
|
942
1524
|
callback: EntryCallback<K, V | undefined, [MK, MV]>,
|
|
943
1525
|
options?: Partial<RedBlackTreeOptions<MK, MV, MR>>,
|
|
@@ -1151,66 +1733,76 @@ export class RedBlackTree<K = any, V = any, R = any> extends BST<K, V, R> implem
|
|
|
1151
1733
|
* @returns void
|
|
1152
1734
|
*/
|
|
1153
1735
|
protected _deleteFixup(node: RedBlackTreeNode<K, V> | undefined): void {
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
return;
|
|
1159
|
-
}
|
|
1736
|
+
// Standard CLRS RB-DELETE-FIXUP: restore black-height invariant.
|
|
1737
|
+
// `node` is the child that replaced the deleted node (may be NIL sentinel).
|
|
1738
|
+
// If RED → just recolor BLACK (trivial fix). If BLACK → double-black repair.
|
|
1739
|
+
if (!node) return;
|
|
1160
1740
|
|
|
1161
|
-
|
|
1162
|
-
|
|
1741
|
+
const NIL = this.NIL;
|
|
1742
|
+
let current: RedBlackTreeNode<K, V> = node;
|
|
1163
1743
|
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1744
|
+
while (current !== this.root && current.color === 'BLACK') {
|
|
1745
|
+
const parent: RedBlackTreeNode<K, V> | undefined = current.parent;
|
|
1746
|
+
if (!parent) break;
|
|
1167
1747
|
|
|
1168
|
-
|
|
1169
|
-
|
|
1748
|
+
const nodeIsLeft = current === parent.left;
|
|
1749
|
+
let sibling = nodeIsLeft ? parent.right : parent.left;
|
|
1170
1750
|
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1751
|
+
// Case 1: sibling is RED → rotate to get a BLACK sibling
|
|
1752
|
+
if (sibling && sibling.color === 'RED') {
|
|
1753
|
+
sibling.color = 'BLACK';
|
|
1754
|
+
parent.color = 'RED';
|
|
1755
|
+
if (nodeIsLeft) {
|
|
1174
1756
|
this._leftRotate(parent);
|
|
1175
1757
|
sibling = parent.right;
|
|
1176
|
-
}
|
|
1177
|
-
|
|
1178
|
-
if ((sibling?.left?.color ?? 'BLACK') === 'BLACK') {
|
|
1179
|
-
if (sibling) sibling.color = 'RED';
|
|
1180
|
-
node = parent;
|
|
1181
1758
|
} else {
|
|
1182
|
-
if (sibling?.left) sibling.left.color = 'BLACK';
|
|
1183
|
-
if (sibling) sibling.color = parent.color;
|
|
1184
|
-
parent.color = 'BLACK';
|
|
1185
1759
|
this._rightRotate(parent);
|
|
1186
|
-
|
|
1760
|
+
sibling = parent.left;
|
|
1187
1761
|
}
|
|
1188
|
-
}
|
|
1189
|
-
let sibling = parent.left;
|
|
1762
|
+
}
|
|
1190
1763
|
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
if (parent) sibling = parent.left;
|
|
1196
|
-
}
|
|
1764
|
+
const sibLeft = sibling?.left;
|
|
1765
|
+
const sibRight = sibling?.right;
|
|
1766
|
+
const sibLeftBlack = !sibLeft || sibLeft === NIL || sibLeft.color === 'BLACK';
|
|
1767
|
+
const sibRightBlack = !sibRight || sibRight === NIL || sibRight.color === 'BLACK';
|
|
1197
1768
|
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1769
|
+
if (sibLeftBlack && sibRightBlack) {
|
|
1770
|
+
// Case 2: sibling's children are both BLACK → recolor sibling RED, move up
|
|
1771
|
+
if (sibling) sibling.color = 'RED';
|
|
1772
|
+
current = parent;
|
|
1773
|
+
} else {
|
|
1774
|
+
if (nodeIsLeft) {
|
|
1775
|
+
// Case 3: sibling's right child is BLACK → rotate sibling right first
|
|
1776
|
+
if (sibRightBlack) {
|
|
1777
|
+
if (sibLeft) sibLeft.color = 'BLACK';
|
|
1778
|
+
if (sibling) sibling.color = 'RED';
|
|
1779
|
+
if (sibling) this._rightRotate(sibling);
|
|
1780
|
+
sibling = parent.right;
|
|
1781
|
+
}
|
|
1782
|
+
// Case 4: sibling's right child is RED → final rotation
|
|
1203
1783
|
if (sibling) sibling.color = parent.color;
|
|
1204
|
-
|
|
1784
|
+
parent.color = 'BLACK';
|
|
1785
|
+
if (sibling?.right) sibling.right.color = 'BLACK';
|
|
1205
1786
|
this._leftRotate(parent);
|
|
1206
|
-
|
|
1787
|
+
} else {
|
|
1788
|
+
// Case 3 (mirror): sibling's left child is BLACK → rotate sibling left first
|
|
1789
|
+
if (sibLeftBlack) {
|
|
1790
|
+
if (sibRight) sibRight.color = 'BLACK';
|
|
1791
|
+
if (sibling) sibling.color = 'RED';
|
|
1792
|
+
if (sibling) this._leftRotate(sibling);
|
|
1793
|
+
sibling = parent.left;
|
|
1794
|
+
}
|
|
1795
|
+
// Case 4 (mirror): sibling's left child is RED → final rotation
|
|
1796
|
+
if (sibling) sibling.color = parent.color;
|
|
1797
|
+
parent.color = 'BLACK';
|
|
1798
|
+
if (sibling?.left) sibling.left.color = 'BLACK';
|
|
1799
|
+
this._rightRotate(parent);
|
|
1207
1800
|
}
|
|
1801
|
+
current = this.root!;
|
|
1208
1802
|
}
|
|
1209
1803
|
}
|
|
1210
1804
|
|
|
1211
|
-
|
|
1212
|
-
node.color = 'BLACK';
|
|
1213
|
-
}
|
|
1805
|
+
current.color = 'BLACK';
|
|
1214
1806
|
}
|
|
1215
1807
|
|
|
1216
1808
|
/**
|