data-structure-typed 1.50.9 → 1.51.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/CHANGELOG.md +1 -1
- package/README.md +14 -14
- package/benchmark/report.html +37 -1
- package/benchmark/report.json +378 -12
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js +1 -1
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/avl-tree.d.ts +1 -1
- package/dist/cjs/data-structures/binary-tree/avl-tree.js +2 -2
- package/dist/cjs/data-structures/binary-tree/avl-tree.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 +73 -73
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/bst.js +39 -39
- package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.js +3 -3
- 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 +1 -1
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +2 -2
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
- package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.js +1 -1
- package/dist/mjs/data-structures/binary-tree/avl-tree.d.ts +1 -1
- package/dist/mjs/data-structures/binary-tree/avl-tree.js +2 -2
- package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/mjs/data-structures/binary-tree/binary-tree.js +73 -73
- package/dist/mjs/data-structures/binary-tree/bst.js +39 -39
- package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +1 -1
- package/dist/mjs/data-structures/binary-tree/rb-tree.js +3 -3
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.js +2 -2
- package/dist/umd/data-structure-typed.js +119 -119
- package/dist/umd/data-structure-typed.min.js +2 -2
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +7 -7
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +1 -1
- package/src/data-structures/binary-tree/avl-tree.ts +2 -2
- package/src/data-structures/binary-tree/binary-tree.ts +71 -71
- package/src/data-structures/binary-tree/bst.ts +33 -33
- package/src/data-structures/binary-tree/rb-tree.ts +3 -3
- package/src/data-structures/binary-tree/tree-multi-map.ts +2 -2
- package/test/integration/avl-tree.test.ts +4 -4
- package/test/integration/bst.test.ts +7 -7
- package/test/integration/index.html +2 -2
- package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +1 -0
- package/test/utils/big-o.ts +12 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "data-structure-typed",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.51.1",
|
|
4
4
|
"description": "Javascript Data Structure. Heap, Binary Tree, Red Black Tree, Linked List, Deque, Trie, HashMap, Directed Graph, Undirected Graph, Binary Search Tree(BST), AVL Tree, Priority Queue, Graph, Queue, Tree Multiset, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue, Stack. Benchmark compared with C++ STL. API aligned with ES6 and Java.util. Usability is comparable to Python",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/mjs/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"format:test": "prettier --write 'test/**/*.{js,ts}'",
|
|
35
35
|
"format": "npm run format:src && npm run format:test",
|
|
36
36
|
"check:exist-latest": "sh scripts/check_exist_remotely.sh",
|
|
37
|
-
"ci": "env && git fetch --tags && npm run inspect && npm run lint && npm run build && npm run test:unit && npm run changelog",
|
|
37
|
+
"ci": "env && git fetch --tags && npm run update:subs && npm run inspect && npm run lint && npm run build && npm run test:unit && npm run changelog",
|
|
38
38
|
"update:subs": "npm i avl-tree-typed binary-tree-typed bst-typed heap-typed data-structure-typed --save-dev",
|
|
39
39
|
"install:all-subs": "npm i avl-tree-typed binary-tree-typed bst-typed deque-typed directed-graph-typed doubly-linked-list-typed graph-typed heap-typed linked-list-typed max-heap-typed max-priority-queue-typed min-heap-typed min-priority-queue-typed priority-queue-typed singly-linked-list-typed stack-typed tree-multimap-typed trie-typed undirected-graph-typed queue-typed --save-dev",
|
|
40
40
|
"changelog": "auto-changelog",
|
|
@@ -66,11 +66,11 @@
|
|
|
66
66
|
"@typescript-eslint/eslint-plugin": "^6.7.4",
|
|
67
67
|
"@typescript-eslint/parser": "^6.7.4",
|
|
68
68
|
"auto-changelog": "^2.4.0",
|
|
69
|
-
"avl-tree-typed": "^1.
|
|
69
|
+
"avl-tree-typed": "^1.51.0",
|
|
70
70
|
"benchmark": "^2.1.4",
|
|
71
|
-
"binary-tree-typed": "^1.
|
|
72
|
-
"bst-typed": "^1.
|
|
73
|
-
"data-structure-typed": "^1.
|
|
71
|
+
"binary-tree-typed": "^1.51.0",
|
|
72
|
+
"bst-typed": "^1.51.0",
|
|
73
|
+
"data-structure-typed": "^1.51.0",
|
|
74
74
|
"dependency-cruiser": "^14.1.0",
|
|
75
75
|
"doctoc": "^2.2.1",
|
|
76
76
|
"eslint": "^8.50.0",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"eslint-import-resolver-typescript": "^3.6.1",
|
|
80
80
|
"eslint-plugin-import": "^2.28.1",
|
|
81
81
|
"fast-glob": "^3.3.1",
|
|
82
|
-
"heap-typed": "^1.
|
|
82
|
+
"heap-typed": "^1.51.0",
|
|
83
83
|
"istanbul-badges-readme": "^1.8.5",
|
|
84
84
|
"jest": "^29.7.0",
|
|
85
85
|
"js-sdsl": "^4.4.2",
|
|
@@ -240,7 +240,7 @@ export class AVLTreeMultiMap<
|
|
|
240
240
|
*/
|
|
241
241
|
override delete<C extends BTNCallback<NODE>>(
|
|
242
242
|
identifier: ReturnType<C>,
|
|
243
|
-
callback: C = this.
|
|
243
|
+
callback: C = this._DEFAULT_CALLBACK as C,
|
|
244
244
|
ignoreCount = false
|
|
245
245
|
): BinaryTreeDeleteResult<NODE>[] {
|
|
246
246
|
const deletedResult: BinaryTreeDeleteResult<NODE>[] = [];
|
|
@@ -164,13 +164,13 @@ export class AVLTree<
|
|
|
164
164
|
* `callback` function.
|
|
165
165
|
* @param {C} callback - The `callback` parameter is a function that will be called for each node
|
|
166
166
|
* that is deleted from the binary tree. It is an optional parameter and if not provided, it will
|
|
167
|
-
* default to the `
|
|
167
|
+
* default to the `_DEFAULT_CALLBACK` function. The `callback` function should have a single
|
|
168
168
|
* parameter of type `NODE
|
|
169
169
|
* @returns The method is returning an array of `BinaryTreeDeleteResult<NODE>`.
|
|
170
170
|
*/
|
|
171
171
|
override delete<C extends BTNCallback<NODE>>(
|
|
172
172
|
identifier: ReturnType<C>,
|
|
173
|
-
callback: C = this.
|
|
173
|
+
callback: C = this._DEFAULT_CALLBACK as C
|
|
174
174
|
): BinaryTreeDeleteResult<NODE>[] {
|
|
175
175
|
if ((identifier as any) instanceof AVLTreeNode) callback = (node => node) as C;
|
|
176
176
|
const deletedResults = super.delete(identifier, callback);
|
|
@@ -268,17 +268,17 @@ export class BinaryTree<
|
|
|
268
268
|
keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>,
|
|
269
269
|
iterationType: IterationType = 'ITERATIVE'
|
|
270
270
|
): NODE | null | undefined {
|
|
271
|
-
let res: NODE | null | undefined;
|
|
272
271
|
if (this.isRealNode(keyOrNodeOrEntry)) {
|
|
273
|
-
|
|
272
|
+
return keyOrNodeOrEntry;
|
|
274
273
|
} else if (this.isEntry(keyOrNodeOrEntry)) {
|
|
275
|
-
if (keyOrNodeOrEntry[0] === null)
|
|
276
|
-
|
|
274
|
+
if (keyOrNodeOrEntry[0] === null) return null;
|
|
275
|
+
if (keyOrNodeOrEntry[0] === undefined) return;
|
|
276
|
+
return this.getNodeByKey(keyOrNodeOrEntry[0], iterationType);
|
|
277
277
|
} else {
|
|
278
|
-
if (keyOrNodeOrEntry === null)
|
|
279
|
-
|
|
278
|
+
if (keyOrNodeOrEntry === null) return null;
|
|
279
|
+
if (keyOrNodeOrEntry === undefined) return;
|
|
280
|
+
return this.getNodeByKey(keyOrNodeOrEntry, iterationType);
|
|
280
281
|
}
|
|
281
|
-
return res;
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
/**
|
|
@@ -486,16 +486,16 @@ export class BinaryTree<
|
|
|
486
486
|
* specific node based on its value or object.
|
|
487
487
|
* @param {C} callback - The `callback` parameter is a function that is used to determine the
|
|
488
488
|
* identifier of the node to be deleted. It is optional and has a default value of
|
|
489
|
-
* `this.
|
|
489
|
+
* `this._DEFAULT_CALLBACK`. The `callback` function should return the identifier of the node.
|
|
490
490
|
* @returns an array of `BinaryTreeDeleteResult<NODE>`.
|
|
491
491
|
*/
|
|
492
492
|
delete<C extends BTNCallback<NODE>>(
|
|
493
493
|
identifier: ReturnType<C> | null | undefined,
|
|
494
|
-
callback: C = this.
|
|
494
|
+
callback: C = this._DEFAULT_CALLBACK as C
|
|
495
495
|
): BinaryTreeDeleteResult<NODE>[] {
|
|
496
496
|
const deletedResult: BinaryTreeDeleteResult<NODE>[] = [];
|
|
497
497
|
if (!this.root) return deletedResult;
|
|
498
|
-
if ((!callback || callback === this.
|
|
498
|
+
if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
|
|
499
499
|
callback = (node => node) as C;
|
|
500
500
|
|
|
501
501
|
const curr = this.getNode(identifier, callback);
|
|
@@ -579,7 +579,7 @@ export class BinaryTree<
|
|
|
579
579
|
* specific value.
|
|
580
580
|
* @param {C} callback - The `callback` parameter is a function that takes a node of type `NODE` as
|
|
581
581
|
* input and returns a value of type `C`. It is used to determine if a node matches the given
|
|
582
|
-
* identifier. If no callback is provided, the `
|
|
582
|
+
* identifier. If no callback is provided, the `_DEFAULT_CALLBACK` function is used as the
|
|
583
583
|
* default
|
|
584
584
|
* @param [onlyOne=false] - A boolean value indicating whether to only return the first node that
|
|
585
585
|
* matches the identifier. If set to true, the function will stop iterating once it finds a matching
|
|
@@ -594,12 +594,12 @@ export class BinaryTree<
|
|
|
594
594
|
*/
|
|
595
595
|
getNodes<C extends BTNCallback<NODE>>(
|
|
596
596
|
identifier: ReturnType<C> | null | undefined,
|
|
597
|
-
callback: C = this.
|
|
597
|
+
callback: C = this._DEFAULT_CALLBACK as C,
|
|
598
598
|
onlyOne = false,
|
|
599
599
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
600
600
|
iterationType: IterationType = this.iterationType
|
|
601
601
|
): NODE[] {
|
|
602
|
-
if ((!callback || callback === this.
|
|
602
|
+
if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
|
|
603
603
|
callback = (node => node) as C;
|
|
604
604
|
beginRoot = this.ensureNode(beginRoot);
|
|
605
605
|
if (!beginRoot) return [];
|
|
@@ -607,28 +607,28 @@ export class BinaryTree<
|
|
|
607
607
|
const ans: NODE[] = [];
|
|
608
608
|
|
|
609
609
|
if (iterationType === 'RECURSIVE') {
|
|
610
|
-
const
|
|
610
|
+
const dfs = (cur: NODE) => {
|
|
611
611
|
if (callback(cur) === identifier) {
|
|
612
612
|
ans.push(cur);
|
|
613
613
|
if (onlyOne) return;
|
|
614
614
|
}
|
|
615
615
|
if (!cur.left && !cur.right) return;
|
|
616
|
-
cur.left &&
|
|
617
|
-
cur.right &&
|
|
616
|
+
cur.left && dfs(cur.left);
|
|
617
|
+
cur.right && dfs(cur.right);
|
|
618
618
|
};
|
|
619
619
|
|
|
620
|
-
|
|
620
|
+
dfs(beginRoot);
|
|
621
621
|
} else {
|
|
622
|
-
const
|
|
623
|
-
while (
|
|
624
|
-
const cur =
|
|
622
|
+
const stack = [beginRoot];
|
|
623
|
+
while (stack.length > 0) {
|
|
624
|
+
const cur = stack.pop();
|
|
625
625
|
if (cur) {
|
|
626
626
|
if (callback(cur) === identifier) {
|
|
627
627
|
ans.push(cur);
|
|
628
628
|
if (onlyOne) return ans;
|
|
629
629
|
}
|
|
630
|
-
cur.left &&
|
|
631
|
-
cur.right &&
|
|
630
|
+
cur.left && stack.push(cur.left);
|
|
631
|
+
cur.right && stack.push(cur.right);
|
|
632
632
|
}
|
|
633
633
|
}
|
|
634
634
|
}
|
|
@@ -685,11 +685,11 @@ export class BinaryTree<
|
|
|
685
685
|
*/
|
|
686
686
|
getNode<C extends BTNCallback<NODE>>(
|
|
687
687
|
identifier: ReturnType<C> | null | undefined,
|
|
688
|
-
callback: C = this.
|
|
688
|
+
callback: C = this._DEFAULT_CALLBACK as C,
|
|
689
689
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
690
690
|
iterationType: IterationType = this.iterationType
|
|
691
691
|
): NODE | null | undefined {
|
|
692
|
-
if ((!callback || callback === this.
|
|
692
|
+
if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
|
|
693
693
|
callback = (node => node) as C;
|
|
694
694
|
|
|
695
695
|
return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;
|
|
@@ -717,23 +717,23 @@ export class BinaryTree<
|
|
|
717
717
|
getNodeByKey(key: K, iterationType: IterationType = 'ITERATIVE'): NODE | undefined {
|
|
718
718
|
if (!this.root) return undefined;
|
|
719
719
|
if (iterationType === 'RECURSIVE') {
|
|
720
|
-
const
|
|
720
|
+
const dfs = (cur: NODE): NODE | undefined => {
|
|
721
721
|
if (cur.key === key) return cur;
|
|
722
722
|
|
|
723
723
|
if (!cur.left && !cur.right) return;
|
|
724
|
-
if (cur.left) return
|
|
725
|
-
if (cur.right) return
|
|
724
|
+
if (cur.left) return dfs(cur.left);
|
|
725
|
+
if (cur.right) return dfs(cur.right);
|
|
726
726
|
};
|
|
727
727
|
|
|
728
|
-
return
|
|
728
|
+
return dfs(this.root);
|
|
729
729
|
} else {
|
|
730
|
-
const
|
|
731
|
-
while (
|
|
732
|
-
const cur =
|
|
730
|
+
const stack = [this.root];
|
|
731
|
+
while (stack.length > 0) {
|
|
732
|
+
const cur = stack.pop();
|
|
733
733
|
if (cur) {
|
|
734
734
|
if (cur.key === key) return cur;
|
|
735
|
-
cur.left &&
|
|
736
|
-
cur.right &&
|
|
735
|
+
cur.left && stack.push(cur.left);
|
|
736
|
+
cur.right && stack.push(cur.right);
|
|
737
737
|
}
|
|
738
738
|
}
|
|
739
739
|
}
|
|
@@ -789,11 +789,11 @@ export class BinaryTree<
|
|
|
789
789
|
*/
|
|
790
790
|
override get<C extends BTNCallback<NODE>>(
|
|
791
791
|
identifier: ReturnType<C> | null | undefined,
|
|
792
|
-
callback: C = this.
|
|
792
|
+
callback: C = this._DEFAULT_CALLBACK as C,
|
|
793
793
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
794
794
|
iterationType: IterationType = this.iterationType
|
|
795
795
|
): V | undefined {
|
|
796
|
-
if ((!callback || callback === this.
|
|
796
|
+
if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
|
|
797
797
|
callback = (node => node) as C;
|
|
798
798
|
|
|
799
799
|
return this.getNode(identifier, callback, beginRoot, iterationType)?.value ?? undefined;
|
|
@@ -848,11 +848,11 @@ export class BinaryTree<
|
|
|
848
848
|
*/
|
|
849
849
|
override has<C extends BTNCallback<NODE>>(
|
|
850
850
|
identifier: ReturnType<C> | null | undefined,
|
|
851
|
-
callback: C = this.
|
|
851
|
+
callback: C = this._DEFAULT_CALLBACK as C,
|
|
852
852
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
853
853
|
iterationType: IterationType = this.iterationType
|
|
854
854
|
): boolean {
|
|
855
|
-
if ((!callback || callback === this.
|
|
855
|
+
if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
|
|
856
856
|
callback = (node => node) as C;
|
|
857
857
|
|
|
858
858
|
return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
|
|
@@ -1184,20 +1184,20 @@ export class BinaryTree<
|
|
|
1184
1184
|
if (!this.isRealNode(beginRoot)) return beginRoot;
|
|
1185
1185
|
|
|
1186
1186
|
if (iterationType === 'RECURSIVE') {
|
|
1187
|
-
const
|
|
1187
|
+
const dfs = (cur: NODE): NODE => {
|
|
1188
1188
|
if (!this.isRealNode(cur.left)) return cur;
|
|
1189
|
-
return
|
|
1189
|
+
return dfs(cur.left);
|
|
1190
1190
|
};
|
|
1191
1191
|
|
|
1192
|
-
return
|
|
1192
|
+
return dfs(beginRoot);
|
|
1193
1193
|
} else {
|
|
1194
1194
|
// Indirect implementation of iteration using tail recursion optimization
|
|
1195
|
-
const
|
|
1195
|
+
const dfs = trampoline((cur: NODE) => {
|
|
1196
1196
|
if (!this.isRealNode(cur.left)) return cur;
|
|
1197
|
-
return
|
|
1197
|
+
return dfs.cont(cur.left);
|
|
1198
1198
|
});
|
|
1199
1199
|
|
|
1200
|
-
return
|
|
1200
|
+
return dfs(beginRoot);
|
|
1201
1201
|
}
|
|
1202
1202
|
}
|
|
1203
1203
|
|
|
@@ -1231,20 +1231,20 @@ export class BinaryTree<
|
|
|
1231
1231
|
if (!beginRoot) return beginRoot;
|
|
1232
1232
|
|
|
1233
1233
|
if (iterationType === 'RECURSIVE') {
|
|
1234
|
-
const
|
|
1234
|
+
const dfs = (cur: NODE): NODE => {
|
|
1235
1235
|
if (!this.isRealNode(cur.right)) return cur;
|
|
1236
|
-
return
|
|
1236
|
+
return dfs(cur.right);
|
|
1237
1237
|
};
|
|
1238
1238
|
|
|
1239
|
-
return
|
|
1239
|
+
return dfs(beginRoot);
|
|
1240
1240
|
} else {
|
|
1241
1241
|
// Indirect implementation of iteration using tail recursion optimization
|
|
1242
|
-
const
|
|
1242
|
+
const dfs = trampoline((cur: NODE) => {
|
|
1243
1243
|
if (!this.isRealNode(cur.right)) return cur;
|
|
1244
|
-
return
|
|
1244
|
+
return dfs.cont(cur.right);
|
|
1245
1245
|
});
|
|
1246
1246
|
|
|
1247
|
-
return
|
|
1247
|
+
return dfs(beginRoot);
|
|
1248
1248
|
}
|
|
1249
1249
|
}
|
|
1250
1250
|
|
|
@@ -1351,7 +1351,7 @@ export class BinaryTree<
|
|
|
1351
1351
|
* @returns an array of values that are the return values of the callback function.
|
|
1352
1352
|
*/
|
|
1353
1353
|
dfs<C extends BTNCallback<NODE | null | undefined>>(
|
|
1354
|
-
callback: C = this.
|
|
1354
|
+
callback: C = this._DEFAULT_CALLBACK as C,
|
|
1355
1355
|
pattern: DFSOrderPattern = 'IN',
|
|
1356
1356
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
1357
1357
|
iterationType: IterationType = 'ITERATIVE',
|
|
@@ -1361,38 +1361,38 @@ export class BinaryTree<
|
|
|
1361
1361
|
if (!beginRoot) return [];
|
|
1362
1362
|
const ans: ReturnType<C>[] = [];
|
|
1363
1363
|
if (iterationType === 'RECURSIVE') {
|
|
1364
|
-
const
|
|
1364
|
+
const dfs = (node: NODE | null | undefined) => {
|
|
1365
1365
|
switch (pattern) {
|
|
1366
1366
|
case 'IN':
|
|
1367
1367
|
if (includeNull) {
|
|
1368
|
-
if (this.isRealNode(node) && this.isNodeOrNull(node.left))
|
|
1368
|
+
if (this.isRealNode(node) && this.isNodeOrNull(node.left)) dfs(node.left);
|
|
1369
1369
|
this.isNodeOrNull(node) && ans.push(callback(node));
|
|
1370
|
-
if (this.isRealNode(node) && this.isNodeOrNull(node.right))
|
|
1370
|
+
if (this.isRealNode(node) && this.isNodeOrNull(node.right)) dfs(node.right);
|
|
1371
1371
|
} else {
|
|
1372
|
-
if (this.isRealNode(node) && this.isRealNode(node.left))
|
|
1372
|
+
if (this.isRealNode(node) && this.isRealNode(node.left)) dfs(node.left);
|
|
1373
1373
|
this.isRealNode(node) && ans.push(callback(node));
|
|
1374
|
-
if (this.isRealNode(node) && this.isRealNode(node.right))
|
|
1374
|
+
if (this.isRealNode(node) && this.isRealNode(node.right)) dfs(node.right);
|
|
1375
1375
|
}
|
|
1376
1376
|
break;
|
|
1377
1377
|
case 'PRE':
|
|
1378
1378
|
if (includeNull) {
|
|
1379
1379
|
this.isNodeOrNull(node) && ans.push(callback(node));
|
|
1380
|
-
if (this.isRealNode(node) && this.isNodeOrNull(node.left))
|
|
1381
|
-
if (this.isRealNode(node) && this.isNodeOrNull(node.right))
|
|
1380
|
+
if (this.isRealNode(node) && this.isNodeOrNull(node.left)) dfs(node.left);
|
|
1381
|
+
if (this.isRealNode(node) && this.isNodeOrNull(node.right)) dfs(node.right);
|
|
1382
1382
|
} else {
|
|
1383
1383
|
this.isRealNode(node) && ans.push(callback(node));
|
|
1384
|
-
if (this.isRealNode(node) && this.isRealNode(node.left))
|
|
1385
|
-
if (this.isRealNode(node) && this.isRealNode(node.right))
|
|
1384
|
+
if (this.isRealNode(node) && this.isRealNode(node.left)) dfs(node.left);
|
|
1385
|
+
if (this.isRealNode(node) && this.isRealNode(node.right)) dfs(node.right);
|
|
1386
1386
|
}
|
|
1387
1387
|
break;
|
|
1388
1388
|
case 'POST':
|
|
1389
1389
|
if (includeNull) {
|
|
1390
|
-
if (this.isRealNode(node) && this.isNodeOrNull(node.left))
|
|
1391
|
-
if (this.isRealNode(node) && this.isNodeOrNull(node.right))
|
|
1390
|
+
if (this.isRealNode(node) && this.isNodeOrNull(node.left)) dfs(node.left);
|
|
1391
|
+
if (this.isRealNode(node) && this.isNodeOrNull(node.right)) dfs(node.right);
|
|
1392
1392
|
this.isNodeOrNull(node) && ans.push(callback(node));
|
|
1393
1393
|
} else {
|
|
1394
|
-
if (this.isRealNode(node) && this.isRealNode(node.left))
|
|
1395
|
-
if (this.isRealNode(node) && this.isRealNode(node.right))
|
|
1394
|
+
if (this.isRealNode(node) && this.isRealNode(node.left)) dfs(node.left);
|
|
1395
|
+
if (this.isRealNode(node) && this.isRealNode(node.right)) dfs(node.right);
|
|
1396
1396
|
this.isRealNode(node) && ans.push(callback(node));
|
|
1397
1397
|
}
|
|
1398
1398
|
|
|
@@ -1400,7 +1400,7 @@ export class BinaryTree<
|
|
|
1400
1400
|
}
|
|
1401
1401
|
};
|
|
1402
1402
|
|
|
1403
|
-
|
|
1403
|
+
dfs(beginRoot);
|
|
1404
1404
|
} else {
|
|
1405
1405
|
// 0: visit, 1: print
|
|
1406
1406
|
const stack: { opt: 0 | 1; node: NODE | null | undefined }[] = [{ opt: 0, node: beginRoot }];
|
|
@@ -1486,7 +1486,7 @@ export class BinaryTree<
|
|
|
1486
1486
|
* the breadth-first traversal of a binary tree.
|
|
1487
1487
|
*/
|
|
1488
1488
|
bfs<C extends BTNCallback<NODE | null>>(
|
|
1489
|
-
callback: C = this.
|
|
1489
|
+
callback: C = this._DEFAULT_CALLBACK as C,
|
|
1490
1490
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
1491
1491
|
iterationType: IterationType = this.iterationType,
|
|
1492
1492
|
includeNull = false
|
|
@@ -1499,7 +1499,7 @@ export class BinaryTree<
|
|
|
1499
1499
|
if (iterationType === 'RECURSIVE') {
|
|
1500
1500
|
const queue: Queue<NODE | null | undefined> = new Queue<NODE | null | undefined>([beginRoot]);
|
|
1501
1501
|
|
|
1502
|
-
const
|
|
1502
|
+
const dfs = (level: number) => {
|
|
1503
1503
|
if (queue.size === 0) return;
|
|
1504
1504
|
|
|
1505
1505
|
const current = queue.shift()!;
|
|
@@ -1513,10 +1513,10 @@ export class BinaryTree<
|
|
|
1513
1513
|
if (this.isRealNode(current.right)) queue.push(current.right);
|
|
1514
1514
|
}
|
|
1515
1515
|
|
|
1516
|
-
|
|
1516
|
+
dfs(level + 1);
|
|
1517
1517
|
};
|
|
1518
1518
|
|
|
1519
|
-
|
|
1519
|
+
dfs(0);
|
|
1520
1520
|
} else {
|
|
1521
1521
|
const queue = new Queue<NODE | null | undefined>([beginRoot]);
|
|
1522
1522
|
while (queue.size > 0) {
|
|
@@ -1580,7 +1580,7 @@ export class BinaryTree<
|
|
|
1580
1580
|
* @returns The function `listLevels` returns a two-dimensional array of type `ReturnType<C>[][]`.
|
|
1581
1581
|
*/
|
|
1582
1582
|
listLevels<C extends BTNCallback<NODE | null>>(
|
|
1583
|
-
callback: C = this.
|
|
1583
|
+
callback: C = this._DEFAULT_CALLBACK as C,
|
|
1584
1584
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
1585
1585
|
iterationType: IterationType = this.iterationType,
|
|
1586
1586
|
includeNull = false
|
|
@@ -1651,7 +1651,7 @@ export class BinaryTree<
|
|
|
1651
1651
|
* by the return type of the `callback` function.
|
|
1652
1652
|
*/
|
|
1653
1653
|
morris<C extends BTNCallback<NODE>>(
|
|
1654
|
-
callback: C = this.
|
|
1654
|
+
callback: C = this._DEFAULT_CALLBACK as C,
|
|
1655
1655
|
pattern: DFSOrderPattern = 'IN',
|
|
1656
1656
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root
|
|
1657
1657
|
): ReturnType<C>[] {
|
|
@@ -1995,7 +1995,7 @@ export class BinaryTree<
|
|
|
1995
1995
|
}
|
|
1996
1996
|
}
|
|
1997
1997
|
|
|
1998
|
-
protected
|
|
1998
|
+
protected _DEFAULT_CALLBACK = (node: NODE | null | undefined) => (node ? node.key : undefined);
|
|
1999
1999
|
|
|
2000
2000
|
/**
|
|
2001
2001
|
* Swap the data of two nodes in the binary tree.
|
|
@@ -214,15 +214,15 @@ export class BST<
|
|
|
214
214
|
keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>,
|
|
215
215
|
iterationType: IterationType = 'ITERATIVE'
|
|
216
216
|
): NODE | undefined {
|
|
217
|
-
let res: NODE | undefined;
|
|
218
217
|
if (this.isRealNode(keyOrNodeOrEntry)) {
|
|
219
|
-
|
|
218
|
+
return keyOrNodeOrEntry;
|
|
220
219
|
} else if (this.isEntry(keyOrNodeOrEntry)) {
|
|
221
|
-
if (keyOrNodeOrEntry[0]
|
|
220
|
+
if (keyOrNodeOrEntry[0] === null || keyOrNodeOrEntry[0] === undefined) return;
|
|
221
|
+
return this.getNodeByKey(keyOrNodeOrEntry[0], iterationType);
|
|
222
222
|
} else {
|
|
223
|
-
if (keyOrNodeOrEntry
|
|
223
|
+
if (keyOrNodeOrEntry === null || keyOrNodeOrEntry === undefined) return;
|
|
224
|
+
return this.getNodeByKey(keyOrNodeOrEntry, iterationType);
|
|
224
225
|
}
|
|
225
|
-
return res;
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
/**
|
|
@@ -426,26 +426,26 @@ export class BST<
|
|
|
426
426
|
* found in the binary tree. If no node is found, it returns `undefined`.
|
|
427
427
|
*/
|
|
428
428
|
override getNodeByKey(key: K, iterationType: IterationType = 'ITERATIVE'): NODE | undefined {
|
|
429
|
-
// return this.getNodes(key, this.
|
|
430
|
-
if (!this.isRealNode(this.root)) return
|
|
429
|
+
// return this.getNodes(key, this._DEFAULT_CALLBACK, true, this.root, iterationType)[0];
|
|
430
|
+
if (!this.isRealNode(this.root)) return;
|
|
431
431
|
if (iterationType === 'RECURSIVE') {
|
|
432
|
-
const
|
|
432
|
+
const dfs = (cur: NODE): NODE | undefined => {
|
|
433
433
|
if (cur.key === key) return cur;
|
|
434
434
|
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
|
|
435
435
|
|
|
436
|
-
if (this._compare(cur.key, key) === 'GT'
|
|
437
|
-
if (this._compare(cur.key, key) === 'LT'
|
|
436
|
+
if (this.isRealNode(cur.left) && this._compare(cur.key, key) === 'GT') return dfs(cur.left);
|
|
437
|
+
if (this.isRealNode(cur.right) && this._compare(cur.key, key) === 'LT') return dfs(cur.right);
|
|
438
438
|
};
|
|
439
439
|
|
|
440
|
-
return
|
|
440
|
+
return dfs(this.root);
|
|
441
441
|
} else {
|
|
442
|
-
const
|
|
443
|
-
while (
|
|
444
|
-
const cur =
|
|
442
|
+
const stack = [this.root];
|
|
443
|
+
while (stack.length > 0) {
|
|
444
|
+
const cur = stack.pop();
|
|
445
445
|
if (this.isRealNode(cur)) {
|
|
446
446
|
if (this._compare(cur.key, key) === 'EQ') return cur;
|
|
447
|
-
if (this._compare(cur.key, key) === 'GT')
|
|
448
|
-
if (this._compare(cur.key, key) === 'LT')
|
|
447
|
+
if (this.isRealNode(cur.left) && this._compare(cur.key, key) === 'GT') stack.push(cur.left);
|
|
448
|
+
if (this.isRealNode(cur.right) && this._compare(cur.key, key) === 'LT') stack.push(cur.right);
|
|
449
449
|
}
|
|
450
450
|
}
|
|
451
451
|
}
|
|
@@ -481,7 +481,7 @@ export class BST<
|
|
|
481
481
|
*/
|
|
482
482
|
override getNodes<C extends BTNCallback<NODE>>(
|
|
483
483
|
identifier: ReturnType<C> | undefined,
|
|
484
|
-
callback: C = this.
|
|
484
|
+
callback: C = this._DEFAULT_CALLBACK as C,
|
|
485
485
|
onlyOne = false,
|
|
486
486
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
487
487
|
iterationType: IterationType = this.iterationType
|
|
@@ -491,7 +491,7 @@ export class BST<
|
|
|
491
491
|
const ans: NODE[] = [];
|
|
492
492
|
|
|
493
493
|
if (iterationType === 'RECURSIVE') {
|
|
494
|
-
const
|
|
494
|
+
const dfs = (cur: NODE) => {
|
|
495
495
|
const callbackResult = callback(cur);
|
|
496
496
|
if (callbackResult === identifier) {
|
|
497
497
|
ans.push(cur);
|
|
@@ -500,16 +500,16 @@ export class BST<
|
|
|
500
500
|
|
|
501
501
|
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
|
|
502
502
|
// TODO potential bug
|
|
503
|
-
if (callback === this.
|
|
504
|
-
if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT')
|
|
505
|
-
if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT')
|
|
503
|
+
if (callback === this._DEFAULT_CALLBACK) {
|
|
504
|
+
if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') dfs(cur.left);
|
|
505
|
+
if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') dfs(cur.right);
|
|
506
506
|
} else {
|
|
507
|
-
this.isRealNode(cur.left) &&
|
|
508
|
-
this.isRealNode(cur.right) &&
|
|
507
|
+
this.isRealNode(cur.left) && dfs(cur.left);
|
|
508
|
+
this.isRealNode(cur.right) && dfs(cur.right);
|
|
509
509
|
}
|
|
510
510
|
};
|
|
511
511
|
|
|
512
|
-
|
|
512
|
+
dfs(beginRoot);
|
|
513
513
|
} else {
|
|
514
514
|
const stack = [beginRoot];
|
|
515
515
|
while (stack.length > 0) {
|
|
@@ -521,7 +521,7 @@ export class BST<
|
|
|
521
521
|
if (onlyOne) return ans;
|
|
522
522
|
}
|
|
523
523
|
// TODO potential bug
|
|
524
|
-
if (callback === this.
|
|
524
|
+
if (callback === this._DEFAULT_CALLBACK) {
|
|
525
525
|
if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') stack.push(cur.right);
|
|
526
526
|
if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') stack.push(cur.left);
|
|
527
527
|
|
|
@@ -568,7 +568,7 @@ export class BST<
|
|
|
568
568
|
* @returns The method is returning an array of the return type of the callback function.
|
|
569
569
|
*/
|
|
570
570
|
override dfs<C extends BTNCallback<NODE>>(
|
|
571
|
-
callback: C = this.
|
|
571
|
+
callback: C = this._DEFAULT_CALLBACK as C,
|
|
572
572
|
pattern: DFSOrderPattern = 'IN',
|
|
573
573
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
574
574
|
iterationType: IterationType = 'ITERATIVE'
|
|
@@ -599,7 +599,7 @@ export class BST<
|
|
|
599
599
|
* @returns The method is returning an array of the return type of the callback function.
|
|
600
600
|
*/
|
|
601
601
|
override bfs<C extends BTNCallback<NODE>>(
|
|
602
|
-
callback: C = this.
|
|
602
|
+
callback: C = this._DEFAULT_CALLBACK as C,
|
|
603
603
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
604
604
|
iterationType: IterationType = this.iterationType
|
|
605
605
|
): ReturnType<C>[] {
|
|
@@ -630,7 +630,7 @@ export class BST<
|
|
|
630
630
|
* function.
|
|
631
631
|
*/
|
|
632
632
|
override listLevels<C extends BTNCallback<NODE>>(
|
|
633
|
-
callback: C = this.
|
|
633
|
+
callback: C = this._DEFAULT_CALLBACK as C,
|
|
634
634
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
635
635
|
iterationType: IterationType = this.iterationType
|
|
636
636
|
): ReturnType<C>[][] {
|
|
@@ -700,7 +700,7 @@ export class BST<
|
|
|
700
700
|
* `ReturnType<C>`, which is the return type of the callback function passed as an argument.
|
|
701
701
|
*/
|
|
702
702
|
lesserOrGreaterTraverse<C extends BTNCallback<NODE>>(
|
|
703
|
-
callback: C = this.
|
|
703
|
+
callback: C = this._DEFAULT_CALLBACK as C,
|
|
704
704
|
lesserOrGreater: CP = 'LT',
|
|
705
705
|
targetNode: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
706
706
|
iterationType: IterationType = this.iterationType
|
|
@@ -713,15 +713,15 @@ export class BST<
|
|
|
713
713
|
const targetKey = targetNode.key;
|
|
714
714
|
|
|
715
715
|
if (iterationType === 'RECURSIVE') {
|
|
716
|
-
const
|
|
716
|
+
const dfs = (cur: NODE) => {
|
|
717
717
|
const compared = this._compare(cur.key, targetKey);
|
|
718
718
|
if (compared === lesserOrGreater) ans.push(callback(cur));
|
|
719
719
|
|
|
720
|
-
if (this.isRealNode(cur.left))
|
|
721
|
-
if (this.isRealNode(cur.right))
|
|
720
|
+
if (this.isRealNode(cur.left)) dfs(cur.left);
|
|
721
|
+
if (this.isRealNode(cur.right)) dfs(cur.right);
|
|
722
722
|
};
|
|
723
723
|
|
|
724
|
-
|
|
724
|
+
dfs(this.root);
|
|
725
725
|
return ans;
|
|
726
726
|
} else {
|
|
727
727
|
const queue = new Queue<NODE>([this.root]);
|
|
@@ -231,7 +231,7 @@ export class RedBlackTree<
|
|
|
231
231
|
*/
|
|
232
232
|
override getNode<C extends BTNCallback<NODE>>(
|
|
233
233
|
identifier: ReturnType<C> | undefined,
|
|
234
|
-
callback: C = this.
|
|
234
|
+
callback: C = this._DEFAULT_CALLBACK as C,
|
|
235
235
|
beginRoot: BSTNKeyOrNode<K, NODE> = this.root,
|
|
236
236
|
iterationType: IterationType = this.iterationType
|
|
237
237
|
): NODE | null | undefined {
|
|
@@ -308,13 +308,13 @@ export class RedBlackTree<
|
|
|
308
308
|
* deleted is not found.
|
|
309
309
|
* @param {C} callback - The `callback` parameter is a function that is used to retrieve a node from
|
|
310
310
|
* the binary tree based on its identifier. It is an optional parameter and if not provided, the
|
|
311
|
-
* `
|
|
311
|
+
* `_DEFAULT_CALLBACK` function is used as the default callback. The callback function should
|
|
312
312
|
* return the identifier of the node to
|
|
313
313
|
* @returns an array of BinaryTreeDeleteResult<NODE> objects.
|
|
314
314
|
*/
|
|
315
315
|
override delete<C extends BTNCallback<NODE>>(
|
|
316
316
|
identifier: ReturnType<C> | null | undefined,
|
|
317
|
-
callback: C = this.
|
|
317
|
+
callback: C = this._DEFAULT_CALLBACK as C
|
|
318
318
|
): BinaryTreeDeleteResult<NODE>[] {
|
|
319
319
|
if (identifier === null) return [];
|
|
320
320
|
const results: BinaryTreeDeleteResult<NODE>[] = [];
|
|
@@ -242,7 +242,7 @@ export class TreeMultiMap<
|
|
|
242
242
|
* function. It can also be null or undefined if no node needs to be deleted.
|
|
243
243
|
* @param {C} callback - The `callback` parameter is a function that takes a node of type `NODE` as
|
|
244
244
|
* input and returns a value of type `ReturnType<C>`. It is used to determine if a node matches the
|
|
245
|
-
* identifier for deletion. If no callback is provided, the `
|
|
245
|
+
* identifier for deletion. If no callback is provided, the `_DEFAULT_CALLBACK` function is
|
|
246
246
|
* used
|
|
247
247
|
* @param [ignoreCount=false] - A boolean value indicating whether to ignore the count of the target
|
|
248
248
|
* node when performing deletion. If set to true, the count of the target node will not be considered
|
|
@@ -252,7 +252,7 @@ export class TreeMultiMap<
|
|
|
252
252
|
*/
|
|
253
253
|
override delete<C extends BTNCallback<NODE>>(
|
|
254
254
|
identifier: ReturnType<C> | null | undefined,
|
|
255
|
-
callback: C = this.
|
|
255
|
+
callback: C = this._DEFAULT_CALLBACK as C,
|
|
256
256
|
ignoreCount = false
|
|
257
257
|
): BinaryTreeDeleteResult<NODE>[] {
|
|
258
258
|
if (identifier === null) return [];
|