data-structure-typed 1.50.7 → 1.50.9
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/CHANGELOG.md +1 -1
- package/README.md +73 -67
- package/benchmark/report.html +1 -37
- package/benchmark/report.json +15 -393
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +14 -3
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js +17 -6
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +33 -34
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/bst.d.ts +22 -3
- package/dist/cjs/data-structures/binary-tree/bst.js +78 -39
- package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +5 -5
- package/dist/cjs/data-structures/binary-tree/rb-tree.js +47 -50
- package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +40 -23
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +44 -28
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
- package/dist/cjs/data-structures/heap/heap.d.ts +1 -1
- package/dist/cjs/data-structures/heap/heap.js +5 -5
- package/dist/cjs/types/common.d.ts +6 -29
- package/dist/cjs/types/common.js +0 -40
- package/dist/cjs/types/common.js.map +1 -1
- package/dist/cjs/types/data-structures/binary-tree/rb-tree.d.ts +1 -4
- package/dist/cjs/types/data-structures/binary-tree/rb-tree.js +0 -6
- package/dist/cjs/types/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +14 -3
- package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.js +17 -6
- package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/mjs/data-structures/binary-tree/binary-tree.js +33 -34
- package/dist/mjs/data-structures/binary-tree/bst.d.ts +22 -3
- package/dist/mjs/data-structures/binary-tree/bst.js +78 -39
- package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +5 -5
- package/dist/mjs/data-structures/binary-tree/rb-tree.js +47 -50
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.d.ts +40 -23
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.js +44 -28
- package/dist/mjs/data-structures/heap/heap.d.ts +1 -1
- package/dist/mjs/data-structures/heap/heap.js +5 -5
- package/dist/mjs/types/common.d.ts +6 -29
- package/dist/mjs/types/common.js +1 -39
- package/dist/mjs/types/data-structures/binary-tree/rb-tree.d.ts +1 -4
- package/dist/mjs/types/data-structures/binary-tree/rb-tree.js +1 -5
- package/dist/umd/data-structure-typed.js +212 -206
- package/dist/umd/data-structure-typed.min.js +2 -2
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +6 -6
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +20 -7
- package/src/data-structures/binary-tree/binary-tree.ts +54 -45
- package/src/data-structures/binary-tree/bst.ts +86 -42
- package/src/data-structures/binary-tree/rb-tree.ts +49 -49
- package/src/data-structures/binary-tree/tree-multi-map.ts +48 -29
- package/src/data-structures/heap/heap.ts +5 -5
- package/src/types/common.ts +6 -30
- package/src/types/data-structures/binary-tree/rb-tree.ts +1 -1
- package/test/integration/all-in-one.test.ts +4 -4
- package/test/integration/avl-tree.test.ts +1 -1
- package/test/integration/bst.test.ts +2 -2
- package/test/performance/data-structures/binary-tree/avl-tree.test.ts +20 -15
- package/test/performance/data-structures/binary-tree/binary-tree.test.ts +1 -1
- package/test/performance/data-structures/binary-tree/rb-tree.test.ts +13 -22
- package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +15 -23
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +8 -8
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +127 -74
- package/test/unit/data-structures/binary-tree/bst.test.ts +20 -20
- package/test/unit/data-structures/binary-tree/overall.test.ts +7 -7
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +31 -26
- package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +26 -34
- package/test/unit/data-structures/priority-queue/priority-queue.test.ts +3 -3
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { BSTVariant, CP, IterationType } from '../../types';
|
|
2
1
|
import { BinaryTree, BinaryTreeNode } from './binary-tree';
|
|
3
2
|
import { Queue } from '../queue';
|
|
4
3
|
export class BSTNode extends BinaryTreeNode {
|
|
@@ -86,7 +85,7 @@ export class BST extends BinaryTree {
|
|
|
86
85
|
get root() {
|
|
87
86
|
return this._root;
|
|
88
87
|
}
|
|
89
|
-
_variant =
|
|
88
|
+
_variant = 'STANDARD';
|
|
90
89
|
/**
|
|
91
90
|
* The function returns the value of the _variant property.
|
|
92
91
|
* @returns The value of the `_variant` property.
|
|
@@ -166,10 +165,10 @@ export class BST extends BinaryTree {
|
|
|
166
165
|
* @param {K | NODE | undefined} keyOrNodeOrEntry - The `key` parameter can be of type `K`, `NODE`, or
|
|
167
166
|
* `undefined`.
|
|
168
167
|
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
169
|
-
* type of iteration to be performed. It has a default value of `
|
|
168
|
+
* type of iteration to be performed. It has a default value of `'ITERATIVE'`.
|
|
170
169
|
* @returns either a node object (NODE) or undefined.
|
|
171
170
|
*/
|
|
172
|
-
ensureNode(keyOrNodeOrEntry, iterationType =
|
|
171
|
+
ensureNode(keyOrNodeOrEntry, iterationType = 'ITERATIVE') {
|
|
173
172
|
let res;
|
|
174
173
|
if (this.isRealNode(keyOrNodeOrEntry)) {
|
|
175
174
|
res = keyOrNodeOrEntry;
|
|
@@ -219,7 +218,7 @@ export class BST extends BinaryTree {
|
|
|
219
218
|
}
|
|
220
219
|
let current = this.root;
|
|
221
220
|
while (current !== undefined) {
|
|
222
|
-
if (this._compare(current.key, newNode.key) ===
|
|
221
|
+
if (this._compare(current.key, newNode.key) === 'EQ') {
|
|
223
222
|
// if (current !== newNode) {
|
|
224
223
|
// The key value is the same but the reference is different, update the value of the existing node
|
|
225
224
|
this._replaceNode(current, newNode);
|
|
@@ -230,7 +229,7 @@ export class BST extends BinaryTree {
|
|
|
230
229
|
// return;
|
|
231
230
|
// }
|
|
232
231
|
}
|
|
233
|
-
else if (this._compare(current.key, newNode.key) ===
|
|
232
|
+
else if (this._compare(current.key, newNode.key) === 'GT') {
|
|
234
233
|
if (current.left === undefined) {
|
|
235
234
|
current.left = newNode;
|
|
236
235
|
this._size++;
|
|
@@ -339,7 +338,7 @@ export class BST extends BinaryTree {
|
|
|
339
338
|
}
|
|
340
339
|
}
|
|
341
340
|
};
|
|
342
|
-
if (iterationType ===
|
|
341
|
+
if (iterationType === 'RECURSIVE') {
|
|
343
342
|
_dfs(sorted);
|
|
344
343
|
}
|
|
345
344
|
else {
|
|
@@ -365,18 +364,19 @@ export class BST extends BinaryTree {
|
|
|
365
364
|
* @returns The function `getNodeByKey` returns a node (`NODE`) if a node with the specified key is
|
|
366
365
|
* found in the binary tree. If no node is found, it returns `undefined`.
|
|
367
366
|
*/
|
|
368
|
-
getNodeByKey(key, iterationType =
|
|
367
|
+
getNodeByKey(key, iterationType = 'ITERATIVE') {
|
|
368
|
+
// return this.getNodes(key, this._defaultOneParamCallback, true, this.root, iterationType)[0];
|
|
369
369
|
if (!this.isRealNode(this.root))
|
|
370
370
|
return undefined;
|
|
371
|
-
if (iterationType ===
|
|
371
|
+
if (iterationType === 'RECURSIVE') {
|
|
372
372
|
const _dfs = (cur) => {
|
|
373
373
|
if (cur.key === key)
|
|
374
374
|
return cur;
|
|
375
375
|
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right))
|
|
376
376
|
return;
|
|
377
|
-
if (this._compare(cur.key, key) ===
|
|
377
|
+
if (this._compare(cur.key, key) === 'GT' && this.isRealNode(cur.left))
|
|
378
378
|
return _dfs(cur.left);
|
|
379
|
-
if (this._compare(cur.key, key) ===
|
|
379
|
+
if (this._compare(cur.key, key) === 'LT' && this.isRealNode(cur.right))
|
|
380
380
|
return _dfs(cur.right);
|
|
381
381
|
};
|
|
382
382
|
return _dfs(this.root);
|
|
@@ -386,11 +386,11 @@ export class BST extends BinaryTree {
|
|
|
386
386
|
while (queue.size > 0) {
|
|
387
387
|
const cur = queue.shift();
|
|
388
388
|
if (this.isRealNode(cur)) {
|
|
389
|
-
if (this._compare(cur.key, key) ===
|
|
389
|
+
if (this._compare(cur.key, key) === 'EQ')
|
|
390
390
|
return cur;
|
|
391
|
-
if (this._compare(cur.key, key) ===
|
|
391
|
+
if (this._compare(cur.key, key) === 'GT')
|
|
392
392
|
this.isRealNode(cur.left) && queue.push(cur.left);
|
|
393
|
-
if (this._compare(cur.key, key) ===
|
|
393
|
+
if (this._compare(cur.key, key) === 'LT')
|
|
394
394
|
this.isRealNode(cur.right) && queue.push(cur.right);
|
|
395
395
|
}
|
|
396
396
|
}
|
|
@@ -429,7 +429,7 @@ export class BST extends BinaryTree {
|
|
|
429
429
|
if (!beginRoot)
|
|
430
430
|
return [];
|
|
431
431
|
const ans = [];
|
|
432
|
-
if (iterationType ===
|
|
432
|
+
if (iterationType === 'RECURSIVE') {
|
|
433
433
|
const _traverse = (cur) => {
|
|
434
434
|
const callbackResult = callback(cur);
|
|
435
435
|
if (callbackResult === identifier) {
|
|
@@ -441,10 +441,10 @@ export class BST extends BinaryTree {
|
|
|
441
441
|
return;
|
|
442
442
|
// TODO potential bug
|
|
443
443
|
if (callback === this._defaultOneParamCallback) {
|
|
444
|
-
if (this._compare(cur.key, identifier) ===
|
|
445
|
-
|
|
446
|
-
if (this._compare(cur.key, identifier) ===
|
|
447
|
-
|
|
444
|
+
if (this.isRealNode(cur.left) && this._compare(cur.key, identifier) === 'GT')
|
|
445
|
+
_traverse(cur.left);
|
|
446
|
+
if (this.isRealNode(cur.right) && this._compare(cur.key, identifier) === 'LT')
|
|
447
|
+
_traverse(cur.right);
|
|
448
448
|
}
|
|
449
449
|
else {
|
|
450
450
|
this.isRealNode(cur.left) && _traverse(cur.left);
|
|
@@ -454,9 +454,9 @@ export class BST extends BinaryTree {
|
|
|
454
454
|
_traverse(beginRoot);
|
|
455
455
|
}
|
|
456
456
|
else {
|
|
457
|
-
const
|
|
458
|
-
while (
|
|
459
|
-
const cur =
|
|
457
|
+
const stack = [beginRoot];
|
|
458
|
+
while (stack.length > 0) {
|
|
459
|
+
const cur = stack.pop();
|
|
460
460
|
if (this.isRealNode(cur)) {
|
|
461
461
|
const callbackResult = callback(cur);
|
|
462
462
|
if (callbackResult === identifier) {
|
|
@@ -466,14 +466,20 @@ export class BST extends BinaryTree {
|
|
|
466
466
|
}
|
|
467
467
|
// TODO potential bug
|
|
468
468
|
if (callback === this._defaultOneParamCallback) {
|
|
469
|
-
if (this._compare(cur.key, identifier) ===
|
|
470
|
-
|
|
471
|
-
if (this._compare(cur.key, identifier) ===
|
|
472
|
-
|
|
469
|
+
if (this.isRealNode(cur.right) && this._compare(cur.key, identifier) === 'LT')
|
|
470
|
+
stack.push(cur.right);
|
|
471
|
+
if (this.isRealNode(cur.left) && this._compare(cur.key, identifier) === 'GT')
|
|
472
|
+
stack.push(cur.left);
|
|
473
|
+
// if (this.isRealNode(cur.right) && this._lt(cur.key, identifier as K)) stack.push(cur.right);
|
|
474
|
+
// if (this.isRealNode(cur.left) && this._gt(cur.key, identifier as K)) stack.push(cur.left);
|
|
475
|
+
// // @ts-ignore
|
|
476
|
+
// if (this.isRealNode(cur.right) && cur.key > identifier) stack.push(cur.right);
|
|
477
|
+
// // @ts-ignore
|
|
478
|
+
// if (this.isRealNode(cur.left) && cur.key < identifier) stack.push(cur.left);
|
|
473
479
|
}
|
|
474
480
|
else {
|
|
475
|
-
this.isRealNode(cur.
|
|
476
|
-
this.isRealNode(cur.
|
|
481
|
+
this.isRealNode(cur.right) && stack.push(cur.right);
|
|
482
|
+
this.isRealNode(cur.left) && stack.push(cur.left);
|
|
477
483
|
}
|
|
478
484
|
}
|
|
479
485
|
}
|
|
@@ -503,7 +509,7 @@ export class BST extends BinaryTree {
|
|
|
503
509
|
* following values:
|
|
504
510
|
* @returns The method is returning an array of the return type of the callback function.
|
|
505
511
|
*/
|
|
506
|
-
dfs(callback = this._defaultOneParamCallback, pattern = '
|
|
512
|
+
dfs(callback = this._defaultOneParamCallback, pattern = 'IN', beginRoot = this.root, iterationType = 'ITERATIVE') {
|
|
507
513
|
return super.dfs(callback, pattern, beginRoot, iterationType, false);
|
|
508
514
|
}
|
|
509
515
|
/**
|
|
@@ -576,7 +582,7 @@ export class BST extends BinaryTree {
|
|
|
576
582
|
let current = this.ensureNode(beginRoot);
|
|
577
583
|
if (!current)
|
|
578
584
|
return undefined;
|
|
579
|
-
if (this._variant ===
|
|
585
|
+
if (this._variant === 'STANDARD') {
|
|
580
586
|
// For BSTVariant.MIN, find the rightmost node
|
|
581
587
|
while (current.right !== undefined) {
|
|
582
588
|
current = current.right;
|
|
@@ -615,7 +621,7 @@ export class BST extends BinaryTree {
|
|
|
615
621
|
* @returns The function `lesserOrGreaterTraverse` returns an array of values of type
|
|
616
622
|
* `ReturnType<C>`, which is the return type of the callback function passed as an argument.
|
|
617
623
|
*/
|
|
618
|
-
lesserOrGreaterTraverse(callback = this._defaultOneParamCallback, lesserOrGreater =
|
|
624
|
+
lesserOrGreaterTraverse(callback = this._defaultOneParamCallback, lesserOrGreater = 'LT', targetNode = this.root, iterationType = this.iterationType) {
|
|
619
625
|
targetNode = this.ensureNode(targetNode);
|
|
620
626
|
const ans = [];
|
|
621
627
|
if (!targetNode)
|
|
@@ -623,7 +629,7 @@ export class BST extends BinaryTree {
|
|
|
623
629
|
if (!this.root)
|
|
624
630
|
return ans;
|
|
625
631
|
const targetKey = targetNode.key;
|
|
626
|
-
if (iterationType ===
|
|
632
|
+
if (iterationType === 'RECURSIVE') {
|
|
627
633
|
const _traverse = (cur) => {
|
|
628
634
|
const compared = this._compare(cur.key, targetKey);
|
|
629
635
|
if (compared === lesserOrGreater)
|
|
@@ -669,11 +675,11 @@ export class BST extends BinaryTree {
|
|
|
669
675
|
* @returns The function `perfectlyBalance` returns a boolean value.
|
|
670
676
|
*/
|
|
671
677
|
perfectlyBalance(iterationType = this.iterationType) {
|
|
672
|
-
const sorted = this.dfs(node => node, '
|
|
678
|
+
const sorted = this.dfs(node => node, 'IN'), n = sorted.length;
|
|
673
679
|
this.clear();
|
|
674
680
|
if (sorted.length < 1)
|
|
675
681
|
return false;
|
|
676
|
-
if (iterationType ===
|
|
682
|
+
if (iterationType === 'RECURSIVE') {
|
|
677
683
|
const buildBalanceBST = (l, r) => {
|
|
678
684
|
if (l > r)
|
|
679
685
|
return;
|
|
@@ -730,7 +736,7 @@ export class BST extends BinaryTree {
|
|
|
730
736
|
if (!this.root)
|
|
731
737
|
return true;
|
|
732
738
|
let balanced = true;
|
|
733
|
-
if (iterationType ===
|
|
739
|
+
if (iterationType === 'RECURSIVE') {
|
|
734
740
|
const _height = (cur) => {
|
|
735
741
|
if (!cur)
|
|
736
742
|
return 0;
|
|
@@ -787,13 +793,46 @@ export class BST extends BinaryTree {
|
|
|
787
793
|
* is greater than, less than, or equal to the second value.
|
|
788
794
|
* @param {K} a - The parameter "a" is of type K.
|
|
789
795
|
* @param {K} b - The parameter "b" in the above code represents a K.
|
|
790
|
-
* @returns a value of type CP (ComparisonResult). The possible return values are
|
|
791
|
-
* than),
|
|
796
|
+
* @returns a value of type CP (ComparisonResult). The possible return values are 'GT' (greater
|
|
797
|
+
* than), 'LT' (less than), or 'EQ' (equal).
|
|
792
798
|
*/
|
|
793
799
|
_compare(a, b) {
|
|
794
800
|
const extractedA = this.extractor(a);
|
|
795
801
|
const extractedB = this.extractor(b);
|
|
796
|
-
const compared = this.variant ===
|
|
797
|
-
return compared > 0 ?
|
|
802
|
+
const compared = this.variant === 'STANDARD' ? extractedA - extractedB : extractedB - extractedA;
|
|
803
|
+
return compared > 0 ? 'GT' : compared < 0 ? 'LT' : 'EQ';
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* The function `_lt` compares two values `a` and `b` using an extractor function and returns true if
|
|
807
|
+
* `a` is less than `b` based on the specified variant.
|
|
808
|
+
* @param {K} a - The parameter "a" is of type "K", which means it can be any type. It represents the
|
|
809
|
+
* first value to be compared in the function.
|
|
810
|
+
* @param {K} b - The parameter `b` is of type `K`, which means it can be any type. It is used as one
|
|
811
|
+
* of the arguments for the comparison in the `_lt` function.
|
|
812
|
+
* @returns a boolean value.
|
|
813
|
+
*/
|
|
814
|
+
_lt(a, b) {
|
|
815
|
+
const extractedA = this.extractor(a);
|
|
816
|
+
const extractedB = this.extractor(b);
|
|
817
|
+
// return this.variant === BSTVariant.STANDARD ? extractedA < extractedB : extractedA > extractedB;
|
|
818
|
+
return this.variant === 'STANDARD' ? extractedA < extractedB : extractedA > extractedB;
|
|
819
|
+
// return extractedA < extractedB;
|
|
820
|
+
// return a < b;
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* The function compares two values using a custom extractor function and returns true if the first
|
|
824
|
+
* value is greater than the second value.
|
|
825
|
+
* @param {K} a - The parameter "a" is of type K, which means it can be any type.
|
|
826
|
+
* @param {K} b - The parameter "b" is of type K, which means it can be any type. It is used as one
|
|
827
|
+
* of the arguments for the comparison in the function.
|
|
828
|
+
* @returns a boolean value.
|
|
829
|
+
*/
|
|
830
|
+
_gt(a, b) {
|
|
831
|
+
const extractedA = this.extractor(a);
|
|
832
|
+
const extractedB = this.extractor(b);
|
|
833
|
+
// return this.variant === BSTVariant.STANDARD ? extractedA > extractedB : extractedA < extractedB;
|
|
834
|
+
return this.variant === 'STANDARD' ? extractedA > extractedB : extractedA < extractedB;
|
|
835
|
+
// return extractedA > extractedB;
|
|
836
|
+
// return a > b;
|
|
798
837
|
}
|
|
799
838
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BinaryTreeDeleteResult, BSTNKeyOrNode, BTNCallback, KeyOrNodeOrEntry, RBTreeOptions, RedBlackTreeNested, RedBlackTreeNodeNested } from '../../types';
|
|
1
|
+
import type { BinaryTreeDeleteResult, BSTNKeyOrNode, BTNCallback, IterationType, KeyOrNodeOrEntry, RBTreeOptions, RedBlackTreeNested, RedBlackTreeNodeNested } from '../../types';
|
|
2
2
|
import { CRUD, RBTNColor } from '../../types';
|
|
3
3
|
import { BST, BSTNode } from './bst';
|
|
4
4
|
import { IBinaryTree } from '../../interfaces';
|
|
@@ -12,7 +12,7 @@ export declare class RedBlackTreeNode<K = any, V = any, NODE extends RedBlackTre
|
|
|
12
12
|
* associated with the key in the Red-Black Tree Node. It is not required and can be omitted when
|
|
13
13
|
* creating a new instance of the Red-Black Tree Node.
|
|
14
14
|
* @param {RBTNColor} color - The `color` parameter is used to specify the color of the Red-Black
|
|
15
|
-
* Tree Node. It is an optional parameter with a default value of `
|
|
15
|
+
* Tree Node. It is an optional parameter with a default value of `'BLACK'`.
|
|
16
16
|
*/
|
|
17
17
|
constructor(key: K, value?: V, color?: RBTNColor);
|
|
18
18
|
protected _color: RBTNColor;
|
|
@@ -58,8 +58,8 @@ export declare class RedBlackTree<K = any, V = any, NODE extends RedBlackTreeNod
|
|
|
58
58
|
* @param {V} [value] - The `value` parameter is an optional parameter that represents the value
|
|
59
59
|
* associated with the key in the node. It is not required and can be omitted if not needed.
|
|
60
60
|
* @param {RBTNColor} color - The "color" parameter is used to specify the color of the node in a
|
|
61
|
-
* Red-Black Tree. It is an optional parameter with a default value of "
|
|
62
|
-
* can be either "
|
|
61
|
+
* Red-Black Tree. It is an optional parameter with a default value of "'BLACK'". The color
|
|
62
|
+
* can be either "'RED'" or "'BLACK'".
|
|
63
63
|
* @returns The method is returning a new instance of a RedBlackTreeNode with the specified key,
|
|
64
64
|
* value, and color.
|
|
65
65
|
*/
|
|
@@ -140,7 +140,7 @@ export declare class RedBlackTree<K = any, V = any, NODE extends RedBlackTreeNod
|
|
|
140
140
|
* its default value is taken from the `iterationType` property of the class.
|
|
141
141
|
* @returns The method is returning a value of type `NODE | null | undefined`.
|
|
142
142
|
*/
|
|
143
|
-
getNode<C extends BTNCallback<NODE>>(identifier: ReturnType<C> | undefined, callback?: C, beginRoot?: BSTNKeyOrNode<K, NODE>, iterationType?:
|
|
143
|
+
getNode<C extends BTNCallback<NODE>>(identifier: ReturnType<C> | undefined, callback?: C, beginRoot?: BSTNKeyOrNode<K, NODE>, iterationType?: IterationType): NODE | null | undefined;
|
|
144
144
|
/**
|
|
145
145
|
* Time Complexity: O(1)
|
|
146
146
|
* Space Complexity: O(1)
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { CRUD, RBTNColor } from '../../types';
|
|
2
1
|
import { BST, BSTNode } from './bst';
|
|
3
2
|
export class RedBlackTreeNode extends BSTNode {
|
|
4
3
|
/**
|
|
@@ -10,9 +9,9 @@ export class RedBlackTreeNode extends BSTNode {
|
|
|
10
9
|
* associated with the key in the Red-Black Tree Node. It is not required and can be omitted when
|
|
11
10
|
* creating a new instance of the Red-Black Tree Node.
|
|
12
11
|
* @param {RBTNColor} color - The `color` parameter is used to specify the color of the Red-Black
|
|
13
|
-
* Tree Node. It is an optional parameter with a default value of `
|
|
12
|
+
* Tree Node. It is an optional parameter with a default value of `'BLACK'`.
|
|
14
13
|
*/
|
|
15
|
-
constructor(key, value, color =
|
|
14
|
+
constructor(key, value, color = 'BLACK') {
|
|
16
15
|
super(key, value);
|
|
17
16
|
this._color = color;
|
|
18
17
|
}
|
|
@@ -73,12 +72,12 @@ export class RedBlackTree extends BST {
|
|
|
73
72
|
* @param {V} [value] - The `value` parameter is an optional parameter that represents the value
|
|
74
73
|
* associated with the key in the node. It is not required and can be omitted if not needed.
|
|
75
74
|
* @param {RBTNColor} color - The "color" parameter is used to specify the color of the node in a
|
|
76
|
-
* Red-Black Tree. It is an optional parameter with a default value of "
|
|
77
|
-
* can be either "
|
|
75
|
+
* Red-Black Tree. It is an optional parameter with a default value of "'BLACK'". The color
|
|
76
|
+
* can be either "'RED'" or "'BLACK'".
|
|
78
77
|
* @returns The method is returning a new instance of a RedBlackTreeNode with the specified key,
|
|
79
78
|
* value, and color.
|
|
80
79
|
*/
|
|
81
|
-
createNode(key, value, color =
|
|
80
|
+
createNode(key, value, color = 'BLACK') {
|
|
82
81
|
return new RedBlackTreeNode(key, value, color);
|
|
83
82
|
}
|
|
84
83
|
/**
|
|
@@ -122,11 +121,11 @@ export class RedBlackTree extends BST {
|
|
|
122
121
|
return;
|
|
123
122
|
}
|
|
124
123
|
else {
|
|
125
|
-
node = this.createNode(key, value,
|
|
124
|
+
node = this.createNode(key, value, 'RED');
|
|
126
125
|
}
|
|
127
126
|
}
|
|
128
127
|
else if (!this.isNode(keyOrNodeOrEntry)) {
|
|
129
|
-
node = this.createNode(keyOrNodeOrEntry, value,
|
|
128
|
+
node = this.createNode(keyOrNodeOrEntry, value, 'RED');
|
|
130
129
|
}
|
|
131
130
|
else {
|
|
132
131
|
return;
|
|
@@ -193,9 +192,7 @@ export class RedBlackTree extends BST {
|
|
|
193
192
|
* @returns The method is returning a value of type `NODE | null | undefined`.
|
|
194
193
|
*/
|
|
195
194
|
getNode(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
|
|
196
|
-
|
|
197
|
-
callback = (node => node);
|
|
198
|
-
return super.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined;
|
|
195
|
+
return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined;
|
|
199
196
|
}
|
|
200
197
|
/**
|
|
201
198
|
* Time Complexity: O(1)
|
|
@@ -234,10 +231,10 @@ export class RedBlackTree extends BST {
|
|
|
234
231
|
if (!this.isRealNode(newNode))
|
|
235
232
|
return false;
|
|
236
233
|
const insertStatus = this._insert(newNode);
|
|
237
|
-
if (insertStatus ===
|
|
234
|
+
if (insertStatus === 'CREATED') {
|
|
238
235
|
// Ensure the root is black
|
|
239
236
|
if (this.isRealNode(this._root)) {
|
|
240
|
-
this._root.color =
|
|
237
|
+
this._root.color = 'BLACK';
|
|
241
238
|
}
|
|
242
239
|
else {
|
|
243
240
|
return false;
|
|
@@ -246,7 +243,7 @@ export class RedBlackTree extends BST {
|
|
|
246
243
|
return true;
|
|
247
244
|
}
|
|
248
245
|
else
|
|
249
|
-
return insertStatus ===
|
|
246
|
+
return insertStatus === 'UPDATED';
|
|
250
247
|
}
|
|
251
248
|
/**
|
|
252
249
|
* Time Complexity: O(log n)
|
|
@@ -313,7 +310,7 @@ export class RedBlackTree extends BST {
|
|
|
313
310
|
}
|
|
314
311
|
this._size--;
|
|
315
312
|
// If the original color was black, fix the tree
|
|
316
|
-
if (originalColor ===
|
|
313
|
+
if (originalColor === 'BLACK') {
|
|
317
314
|
this._deleteFixup(replacementNode);
|
|
318
315
|
}
|
|
319
316
|
results.push({ deleted: nodeToDelete, needBalanced: undefined });
|
|
@@ -378,7 +375,7 @@ export class RedBlackTree extends BST {
|
|
|
378
375
|
}
|
|
379
376
|
else {
|
|
380
377
|
this._replaceNode(current, node);
|
|
381
|
-
return
|
|
378
|
+
return 'UPDATED';
|
|
382
379
|
}
|
|
383
380
|
}
|
|
384
381
|
node.parent = parent;
|
|
@@ -393,9 +390,9 @@ export class RedBlackTree extends BST {
|
|
|
393
390
|
}
|
|
394
391
|
node.left = this.SENTINEL;
|
|
395
392
|
node.right = this.SENTINEL;
|
|
396
|
-
node.color =
|
|
393
|
+
node.color = 'RED';
|
|
397
394
|
this._insertFixup(node);
|
|
398
|
-
return
|
|
395
|
+
return 'CREATED';
|
|
399
396
|
}
|
|
400
397
|
/**
|
|
401
398
|
* Time Complexity: O(1)
|
|
@@ -438,16 +435,16 @@ export class RedBlackTree extends BST {
|
|
|
438
435
|
*/
|
|
439
436
|
_insertFixup(z) {
|
|
440
437
|
// Continue fixing the tree as long as the parent of z is red
|
|
441
|
-
while (z?.parent?.color ===
|
|
438
|
+
while (z?.parent?.color === 'RED') {
|
|
442
439
|
// Check if the parent of z is the left child of its parent
|
|
443
440
|
if (z.parent === z.parent.parent?.left) {
|
|
444
441
|
// Case 1: The uncle (y) of z is red
|
|
445
442
|
const y = z.parent.parent.right;
|
|
446
|
-
if (y?.color ===
|
|
443
|
+
if (y?.color === 'RED') {
|
|
447
444
|
// Set colors to restore properties of Red-Black Tree
|
|
448
|
-
z.parent.color =
|
|
449
|
-
y.color =
|
|
450
|
-
z.parent.parent.color =
|
|
445
|
+
z.parent.color = 'BLACK';
|
|
446
|
+
y.color = 'BLACK';
|
|
447
|
+
z.parent.parent.color = 'RED';
|
|
451
448
|
// Move up the tree to continue fixing
|
|
452
449
|
z = z.parent.parent;
|
|
453
450
|
}
|
|
@@ -461,8 +458,8 @@ export class RedBlackTree extends BST {
|
|
|
461
458
|
// Case 3: The uncle (y) of z is black, and z is a left child
|
|
462
459
|
// Adjust colors and perform a right rotation
|
|
463
460
|
if (z && this.isRealNode(z.parent) && this.isRealNode(z.parent.parent)) {
|
|
464
|
-
z.parent.color =
|
|
465
|
-
z.parent.parent.color =
|
|
461
|
+
z.parent.color = 'BLACK';
|
|
462
|
+
z.parent.parent.color = 'RED';
|
|
466
463
|
this._rightRotate(z.parent.parent);
|
|
467
464
|
}
|
|
468
465
|
}
|
|
@@ -471,10 +468,10 @@ export class RedBlackTree extends BST {
|
|
|
471
468
|
// Symmetric case for the right child (left and right exchanged)
|
|
472
469
|
// Follow the same logic as above with left and right exchanged
|
|
473
470
|
const y = z?.parent?.parent?.left;
|
|
474
|
-
if (y?.color ===
|
|
475
|
-
z.parent.color =
|
|
476
|
-
y.color =
|
|
477
|
-
z.parent.parent.color =
|
|
471
|
+
if (y?.color === 'RED') {
|
|
472
|
+
z.parent.color = 'BLACK';
|
|
473
|
+
y.color = 'BLACK';
|
|
474
|
+
z.parent.parent.color = 'RED';
|
|
478
475
|
z = z.parent.parent;
|
|
479
476
|
}
|
|
480
477
|
else {
|
|
@@ -483,8 +480,8 @@ export class RedBlackTree extends BST {
|
|
|
483
480
|
this._rightRotate(z);
|
|
484
481
|
}
|
|
485
482
|
if (z && this.isRealNode(z.parent) && this.isRealNode(z.parent.parent)) {
|
|
486
|
-
z.parent.color =
|
|
487
|
-
z.parent.parent.color =
|
|
483
|
+
z.parent.color = 'BLACK';
|
|
484
|
+
z.parent.parent.color = 'RED';
|
|
488
485
|
this._leftRotate(z.parent.parent);
|
|
489
486
|
}
|
|
490
487
|
}
|
|
@@ -492,7 +489,7 @@ export class RedBlackTree extends BST {
|
|
|
492
489
|
}
|
|
493
490
|
// Ensure that the root is black after fixing
|
|
494
491
|
if (this.isRealNode(this._root))
|
|
495
|
-
this._root.color =
|
|
492
|
+
this._root.color = 'BLACK';
|
|
496
493
|
}
|
|
497
494
|
/**
|
|
498
495
|
* Time Complexity: O(log n)
|
|
@@ -510,13 +507,13 @@ export class RedBlackTree extends BST {
|
|
|
510
507
|
*/
|
|
511
508
|
_deleteFixup(node) {
|
|
512
509
|
// Early exit condition
|
|
513
|
-
if (!node || node === this.root || node.color ===
|
|
510
|
+
if (!node || node === this.root || node.color === 'BLACK') {
|
|
514
511
|
if (node) {
|
|
515
|
-
node.color =
|
|
512
|
+
node.color = 'BLACK'; // Ensure the final node is black
|
|
516
513
|
}
|
|
517
514
|
return;
|
|
518
515
|
}
|
|
519
|
-
while (node && node !== this.root && node.color ===
|
|
516
|
+
while (node && node !== this.root && node.color === 'BLACK') {
|
|
520
517
|
const parent = node.parent;
|
|
521
518
|
if (!parent) {
|
|
522
519
|
break; // Ensure the loop terminates if there's an issue with the tree structure
|
|
@@ -524,25 +521,25 @@ export class RedBlackTree extends BST {
|
|
|
524
521
|
if (node === parent.left) {
|
|
525
522
|
let sibling = parent.right;
|
|
526
523
|
// Cases 1 and 2: Sibling is red or both children of sibling are black
|
|
527
|
-
if (sibling?.color ===
|
|
528
|
-
sibling.color =
|
|
529
|
-
parent.color =
|
|
524
|
+
if (sibling?.color === 'RED') {
|
|
525
|
+
sibling.color = 'BLACK';
|
|
526
|
+
parent.color = 'RED';
|
|
530
527
|
this._leftRotate(parent);
|
|
531
528
|
sibling = parent.right;
|
|
532
529
|
}
|
|
533
530
|
// Case 3: Sibling's left child is black
|
|
534
|
-
if ((sibling?.left?.color ??
|
|
531
|
+
if ((sibling?.left?.color ?? 'BLACK') === 'BLACK') {
|
|
535
532
|
if (sibling)
|
|
536
|
-
sibling.color =
|
|
533
|
+
sibling.color = 'RED';
|
|
537
534
|
node = parent;
|
|
538
535
|
}
|
|
539
536
|
else {
|
|
540
537
|
// Case 4: Adjust colors and perform a right rotation
|
|
541
538
|
if (sibling?.left)
|
|
542
|
-
sibling.left.color =
|
|
539
|
+
sibling.left.color = 'BLACK';
|
|
543
540
|
if (sibling)
|
|
544
541
|
sibling.color = parent.color;
|
|
545
|
-
parent.color =
|
|
542
|
+
parent.color = 'BLACK';
|
|
546
543
|
this._rightRotate(parent);
|
|
547
544
|
node = this.root;
|
|
548
545
|
}
|
|
@@ -551,28 +548,28 @@ export class RedBlackTree extends BST {
|
|
|
551
548
|
// Symmetric case for the right child (left and right exchanged)
|
|
552
549
|
let sibling = parent.left;
|
|
553
550
|
// Cases 1 and 2: Sibling is red or both children of sibling are black
|
|
554
|
-
if (sibling?.color ===
|
|
555
|
-
sibling.color =
|
|
551
|
+
if (sibling?.color === 'RED') {
|
|
552
|
+
sibling.color = 'BLACK';
|
|
556
553
|
if (parent)
|
|
557
|
-
parent.color =
|
|
554
|
+
parent.color = 'RED';
|
|
558
555
|
this._rightRotate(parent);
|
|
559
556
|
if (parent)
|
|
560
557
|
sibling = parent.left;
|
|
561
558
|
}
|
|
562
559
|
// Case 3: Sibling's left child is black
|
|
563
|
-
if ((sibling?.right?.color ??
|
|
560
|
+
if ((sibling?.right?.color ?? 'BLACK') === 'BLACK') {
|
|
564
561
|
if (sibling)
|
|
565
|
-
sibling.color =
|
|
562
|
+
sibling.color = 'RED';
|
|
566
563
|
node = parent;
|
|
567
564
|
}
|
|
568
565
|
else {
|
|
569
566
|
// Case 4: Adjust colors and perform a left rotation
|
|
570
567
|
if (sibling?.right)
|
|
571
|
-
sibling.right.color =
|
|
568
|
+
sibling.right.color = 'BLACK';
|
|
572
569
|
if (sibling)
|
|
573
570
|
sibling.color = parent.color;
|
|
574
571
|
if (parent)
|
|
575
|
-
parent.color =
|
|
572
|
+
parent.color = 'BLACK';
|
|
576
573
|
this._leftRotate(parent);
|
|
577
574
|
node = this.root;
|
|
578
575
|
}
|
|
@@ -580,7 +577,7 @@ export class RedBlackTree extends BST {
|
|
|
580
577
|
}
|
|
581
578
|
// Ensure that the final node (possibly the root) is black
|
|
582
579
|
if (node) {
|
|
583
|
-
node.color =
|
|
580
|
+
node.color = 'BLACK';
|
|
584
581
|
}
|
|
585
582
|
}
|
|
586
583
|
/**
|
|
@@ -5,22 +5,24 @@
|
|
|
5
5
|
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
-
import type { BinaryTreeDeleteResult, BSTNKeyOrNode, BTNCallback, KeyOrNodeOrEntry, TreeMultiMapNested, TreeMultiMapNodeNested, TreeMultiMapOptions } from '../../types';
|
|
9
|
-
import {
|
|
8
|
+
import type { BinaryTreeDeleteResult, BSTNKeyOrNode, BTNCallback, IterationType, KeyOrNodeOrEntry, TreeMultiMapNested, TreeMultiMapNodeNested, TreeMultiMapOptions } from '../../types';
|
|
9
|
+
import { RBTNColor } from '../../types';
|
|
10
10
|
import { IBinaryTree } from '../../interfaces';
|
|
11
11
|
import { RedBlackTree, RedBlackTreeNode } from './rb-tree';
|
|
12
12
|
export declare class TreeMultiMapNode<K = any, V = any, NODE extends TreeMultiMapNode<K, V, NODE> = TreeMultiMapNodeNested<K, V>> extends RedBlackTreeNode<K, V, NODE> {
|
|
13
13
|
/**
|
|
14
|
-
* The constructor function initializes
|
|
15
|
-
* @param {K} key - The key parameter
|
|
16
|
-
*
|
|
17
|
-
* @param {V} [value] - The `value` parameter is an optional parameter
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* 1.
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
* The constructor function initializes a Red-Black Tree node with a key, value, count, and color.
|
|
15
|
+
* @param {K} key - The key parameter represents the key of the node in the Red-Black Tree. It is
|
|
16
|
+
* used to identify and locate the node within the tree.
|
|
17
|
+
* @param {V} [value] - The `value` parameter is an optional parameter that represents the value
|
|
18
|
+
* associated with the key in the Red-Black Tree node. It is not required and can be omitted when
|
|
19
|
+
* creating a new node.
|
|
20
|
+
* @param [count=1] - The `count` parameter represents the number of occurrences of a particular key
|
|
21
|
+
* in the Red-Black Tree. It is an optional parameter with a default value of 1.
|
|
22
|
+
* @param {RBTNColor} [color=BLACK] - The `color` parameter is used to specify the color of the node
|
|
23
|
+
* in a Red-Black Tree. It is optional and has a default value of `'BLACK'`.
|
|
24
|
+
*/
|
|
25
|
+
constructor(key: K, value?: V, count?: number, color?: RBTNColor);
|
|
24
26
|
protected _count: number;
|
|
25
27
|
/**
|
|
26
28
|
* The function returns the value of the private variable _count.
|
|
@@ -51,19 +53,34 @@ export declare class TreeMultiMap<K = any, V = any, NODE extends TreeMultiMapNod
|
|
|
51
53
|
* @returns the sum of the count property of all nodes in the tree.
|
|
52
54
|
*/
|
|
53
55
|
get count(): number;
|
|
54
|
-
getMutableCount(): number;
|
|
55
56
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* which is a generic type that can be replaced with any specific type when using the function.
|
|
59
|
-
* @param {V} [value] - The `value` parameter is an optional parameter that represents the value
|
|
60
|
-
* associated with the key in the node. It is of type `V`, which can be any data type.
|
|
61
|
-
* @param {number} [count] - The `count` parameter represents the number of occurrences of a
|
|
62
|
-
* key-value pair in the TreeMultiMap. It is an optional parameter, so if it is not provided, it will
|
|
63
|
-
* default to 1.
|
|
64
|
-
* @returns a new instance of the TreeMultiMapNode class, casted as NODE.
|
|
57
|
+
* Time Complexity: O(n)
|
|
58
|
+
* Space Complexity: O(1)
|
|
65
59
|
*/
|
|
66
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Time Complexity: O(n)
|
|
62
|
+
* Space Complexity: O(1)
|
|
63
|
+
*
|
|
64
|
+
* The function calculates the sum of the count property of all nodes in a tree using depth-first
|
|
65
|
+
* search.
|
|
66
|
+
* @returns the sum of the count property of all nodes in the tree.
|
|
67
|
+
*/
|
|
68
|
+
getComputedCount(): number;
|
|
69
|
+
/**
|
|
70
|
+
* The function creates a new TreeMultiMapNode with the specified key, value, color, and count.
|
|
71
|
+
* @param {K} key - The key parameter represents the key of the node being created. It is of type K,
|
|
72
|
+
* which is a generic type representing the key type of the node.
|
|
73
|
+
* @param {V} [value] - The `value` parameter represents the value associated with the key in the
|
|
74
|
+
* node. It is an optional parameter, which means it can be omitted when calling the `createNode`
|
|
75
|
+
* function. If provided, it should be of type `V`.
|
|
76
|
+
* @param {RBTNColor} [color=BLACK] - The color parameter is used to specify the color of the node in
|
|
77
|
+
* a Red-Black Tree. It can have two possible values: 'RED' or 'BLACK'. The default value is 'BLACK'.
|
|
78
|
+
* @param {number} [count] - The `count` parameter represents the number of occurrences of a key in
|
|
79
|
+
* the tree. It is an optional parameter and is used to keep track of the number of values associated
|
|
80
|
+
* with a key in the tree.
|
|
81
|
+
* @returns A new instance of the TreeMultiMapNode class is being returned.
|
|
82
|
+
*/
|
|
83
|
+
createNode(key: K, value?: V, color?: RBTNColor, count?: number): NODE;
|
|
67
84
|
/**
|
|
68
85
|
* The function creates a new instance of a TreeMultiMap with the specified options and returns it.
|
|
69
86
|
* @param [options] - The `options` parameter is an optional object that contains additional
|