data-structure-typed 1.36.8 → 1.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -1
- package/README.md +8 -0
- package/dist/data-structures/binary-tree/avl-tree.d.ts +5 -5
- package/dist/data-structures/binary-tree/avl-tree.js +6 -6
- package/dist/data-structures/binary-tree/avl-tree.js.map +1 -1
- package/dist/data-structures/binary-tree/binary-tree.d.ts +18 -95
- package/dist/data-structures/binary-tree/binary-tree.js +82 -183
- package/dist/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/data-structures/binary-tree/bst.d.ts +6 -20
- package/dist/data-structures/binary-tree/bst.js +22 -122
- package/dist/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/data-structures/binary-tree/tree-multiset.d.ts +6 -67
- package/dist/data-structures/binary-tree/tree-multiset.js +10 -257
- package/dist/data-structures/binary-tree/tree-multiset.js.map +1 -1
- package/dist/data-structures/graph/abstract-graph.js +4 -3
- package/dist/data-structures/graph/abstract-graph.js.map +1 -1
- package/dist/data-structures/hash/hash-map.d.ts +1 -1
- package/dist/data-structures/hash/hash-map.js +1 -1
- package/dist/data-structures/hash/hash-table.d.ts +3 -3
- package/dist/data-structures/hash/hash-table.js +3 -3
- package/dist/data-structures/heap/heap.js.map +1 -1
- package/dist/data-structures/linked-list/skip-linked-list.d.ts +3 -3
- package/dist/data-structures/linked-list/skip-linked-list.js +3 -3
- package/dist/data-structures/queue/deque.d.ts +2 -2
- package/dist/data-structures/queue/deque.js +2 -2
- package/dist/data-structures/queue/queue.js +1 -1
- package/dist/data-structures/trie/trie.d.ts +2 -2
- package/dist/data-structures/trie/trie.js +2 -2
- package/dist/interfaces/binary-tree.d.ts +1 -1
- package/lib/data-structures/binary-tree/avl-tree.d.ts +5 -5
- package/lib/data-structures/binary-tree/avl-tree.js +6 -6
- package/lib/data-structures/binary-tree/binary-tree.d.ts +18 -95
- package/lib/data-structures/binary-tree/binary-tree.js +82 -183
- package/lib/data-structures/binary-tree/bst.d.ts +6 -20
- package/lib/data-structures/binary-tree/bst.js +22 -122
- package/lib/data-structures/binary-tree/tree-multiset.d.ts +6 -67
- package/lib/data-structures/binary-tree/tree-multiset.js +10 -257
- package/lib/data-structures/graph/abstract-graph.js +4 -3
- package/lib/data-structures/hash/hash-map.d.ts +1 -1
- package/lib/data-structures/hash/hash-map.js +1 -1
- package/lib/data-structures/hash/hash-table.d.ts +3 -3
- package/lib/data-structures/hash/hash-table.js +3 -3
- package/lib/data-structures/linked-list/skip-linked-list.d.ts +3 -3
- package/lib/data-structures/linked-list/skip-linked-list.js +3 -3
- package/lib/data-structures/queue/deque.d.ts +2 -2
- package/lib/data-structures/queue/deque.js +2 -2
- package/lib/data-structures/queue/queue.js +1 -1
- package/lib/data-structures/trie/trie.d.ts +2 -2
- package/lib/data-structures/trie/trie.js +2 -2
- package/lib/interfaces/binary-tree.d.ts +1 -1
- package/package.json +9 -7
- package/src/data-structures/binary-tree/avl-tree.ts +6 -6
- package/src/data-structures/binary-tree/binary-tree.ts +85 -274
- package/src/data-structures/binary-tree/bst.ts +22 -106
- package/src/data-structures/binary-tree/rb-tree.ts +3 -3
- package/src/data-structures/binary-tree/tree-multiset.ts +10 -249
- package/src/data-structures/graph/abstract-graph.ts +4 -3
- package/src/data-structures/hash/hash-map.ts +1 -1
- package/src/data-structures/hash/hash-table.ts +3 -3
- package/src/data-structures/heap/heap.ts +5 -2
- package/src/data-structures/linked-list/skip-linked-list.ts +3 -3
- package/src/data-structures/queue/deque.ts +2 -2
- package/src/data-structures/queue/queue.ts +1 -1
- package/src/data-structures/trie/trie.ts +2 -2
- package/src/interfaces/binary-tree.ts +1 -1
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +19 -17
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +2 -2
- package/test/unit/data-structures/binary-tree/bst.test.ts +72 -35
- package/test/unit/data-structures/binary-tree/overall.test.ts +4 -4
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +1 -1
- package/test/unit/data-structures/binary-tree/tree-multiset.test.ts +67 -37
- package/test/unit/data-structures/graph/directed-graph.test.ts +1 -1
- package/test/unit/data-structures/graph/undirected-graph.test.ts +1 -1
- package/test/unit/data-structures/hash/hash-map.test.ts +2 -2
- package/test/unit/data-structures/hash/hash-table.test.ts +5 -5
- package/test/unit/data-structures/heap/heap.test.ts +15 -12
- package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +7 -7
- package/test/unit/data-structures/linked-list/skip-list.test.ts +2 -2
- package/test/unit/data-structures/priority-queue/max-priority-queue.test.ts +1 -1
- package/test/unit/data-structures/queue/deque.test.ts +20 -3
- package/test/unit/data-structures/queue/queue.test.ts +42 -0
- package/test/unit/data-structures/trie/trie.test.ts +5 -5
- package/test/utils/big-o.ts +64 -57
- package/umd/bundle.min.js +1 -1
- package/umd/bundle.min.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "data-structure-typed",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.37.0",
|
|
4
4
|
"description": "Data Structures of Javascript & TypeScript. Binary Tree, BST, Graph, Heap, Priority Queue, Linked List, Queue, Deque, Stack, AVL Tree, Tree Multiset, Trie, Directed Graph, Undirected Graph, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "lib/index.js",
|
|
@@ -33,8 +33,10 @@
|
|
|
33
33
|
"check:deps": "dependency-cruiser src",
|
|
34
34
|
"changelog": "auto-changelog",
|
|
35
35
|
"coverage:badge": "istanbul-badges-readme",
|
|
36
|
-
"ci": "env && npm run lint && npm run build && npm run update:individuals && npm run test &&
|
|
37
|
-
"publish:
|
|
36
|
+
"ci": "env && git fetch --tags && npm run lint && npm run build && npm run update:individuals && npm run test && npm run changelog",
|
|
37
|
+
"publish:individuals": "sh scripts/publish_all_subs.sh",
|
|
38
|
+
"publish:docs": "sh scripts/publish_docs.sh",
|
|
39
|
+
"publish:all": "npm run ci && npm publish && npm run publish:individuals && npm run publish:docs"
|
|
38
40
|
},
|
|
39
41
|
"repository": {
|
|
40
42
|
"type": "git",
|
|
@@ -56,17 +58,17 @@
|
|
|
56
58
|
"@typescript-eslint/eslint-plugin": "^6.7.4",
|
|
57
59
|
"@typescript-eslint/parser": "^6.7.4",
|
|
58
60
|
"auto-changelog": "^2.4.0",
|
|
59
|
-
"avl-tree-typed": "^1.36.
|
|
61
|
+
"avl-tree-typed": "^1.36.9",
|
|
60
62
|
"benchmark": "^2.1.4",
|
|
61
|
-
"binary-tree-typed": "^1.36.
|
|
62
|
-
"bst-typed": "^1.36.
|
|
63
|
+
"binary-tree-typed": "^1.36.9",
|
|
64
|
+
"bst-typed": "^1.36.9",
|
|
63
65
|
"dependency-cruiser": "^14.1.0",
|
|
64
66
|
"eslint": "^8.50.0",
|
|
65
67
|
"eslint-config-prettier": "^9.0.0",
|
|
66
68
|
"eslint-import-resolver-alias": "^1.1.2",
|
|
67
69
|
"eslint-import-resolver-typescript": "^3.6.1",
|
|
68
70
|
"eslint-plugin-import": "^2.28.1",
|
|
69
|
-
"heap-typed": "^1.36.
|
|
71
|
+
"heap-typed": "^1.36.9",
|
|
70
72
|
"istanbul-badges-readme": "^1.8.5",
|
|
71
73
|
"jest": "^29.7.0",
|
|
72
74
|
"prettier": "^3.0.3",
|
|
@@ -33,13 +33,13 @@ export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode> extends B
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
|
-
* The `
|
|
37
|
-
* @param {N} srcNode - The source node that you want to
|
|
36
|
+
* The `_swap` function swaps the location of two nodes in a binary tree.
|
|
37
|
+
* @param {N} srcNode - The source node that you want to _swap with the destination node.
|
|
38
38
|
* @param {N} destNode - The `destNode` parameter represents the destination node where the values from `srcNode` will
|
|
39
39
|
* be swapped to.
|
|
40
40
|
* @returns The `destNode` is being returned.
|
|
41
41
|
*/
|
|
42
|
-
override
|
|
42
|
+
protected override _swap(srcNode: N, destNode: N): N {
|
|
43
43
|
const {key, val, height} = destNode;
|
|
44
44
|
const tempNode = this.createNode(key, val);
|
|
45
45
|
|
|
@@ -85,14 +85,14 @@ export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode> extends B
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
/**
|
|
88
|
-
* The function overrides the
|
|
88
|
+
* The function overrides the delete method of a binary tree and performs additional operations to balance the tree after
|
|
89
89
|
* deletion.
|
|
90
90
|
* @param {BinaryTreeNodeKey} key - The `key` parameter represents the identifier of the binary tree node that needs to be
|
|
91
91
|
* removed.
|
|
92
92
|
* @returns The method is returning an array of `BinaryTreeDeletedResult<N>` objects.
|
|
93
93
|
*/
|
|
94
|
-
override
|
|
95
|
-
const deletedResults = super.
|
|
94
|
+
override delete(key: BinaryTreeNodeKey): BinaryTreeDeletedResult<N>[] {
|
|
95
|
+
const deletedResults = super.delete(key);
|
|
96
96
|
for (const {needBalanced} of deletedResults) {
|
|
97
97
|
if (needBalanced) {
|
|
98
98
|
this._balancePath(needBalanced);
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
} from '../../types';
|
|
24
24
|
import {IBinaryTree} from '../../interfaces';
|
|
25
25
|
import {trampoline} from '../../utils';
|
|
26
|
+
import {Queue} from '../queue';
|
|
26
27
|
|
|
27
28
|
export class BinaryTreeNode<V = any, FAMILY extends BinaryTreeNode<V, FAMILY> = BinaryTreeNodeNested<V>> {
|
|
28
29
|
/**
|
|
@@ -145,6 +146,10 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
145
146
|
return this._loopType;
|
|
146
147
|
}
|
|
147
148
|
|
|
149
|
+
set loopType(v: LoopType) {
|
|
150
|
+
this._loopType = v;
|
|
151
|
+
}
|
|
152
|
+
|
|
148
153
|
visitedKey: BinaryTreeNodeKey[] = [];
|
|
149
154
|
|
|
150
155
|
visitedVal: N['val'][] = [];
|
|
@@ -152,13 +157,13 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
152
157
|
visitedNode: N[] = [];
|
|
153
158
|
|
|
154
159
|
/**
|
|
155
|
-
* The `
|
|
156
|
-
* @param {N} srcNode - The source node that you want to
|
|
160
|
+
* The `_swap` function swaps the location of two nodes in a binary tree.
|
|
161
|
+
* @param {N} srcNode - The source node that you want to _swap with the destination node.
|
|
157
162
|
* @param {N} destNode - The `destNode` parameter represents the destination node where the values from `srcNode` will
|
|
158
163
|
* be swapped to.
|
|
159
164
|
* @returns The `destNode` is being returned.
|
|
160
165
|
*/
|
|
161
|
-
|
|
166
|
+
protected _swap(srcNode: N, destNode: N): N {
|
|
162
167
|
const {key, val} = destNode;
|
|
163
168
|
const tempNode = this.createNode(key, val);
|
|
164
169
|
|
|
@@ -206,8 +211,8 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
206
211
|
*/
|
|
207
212
|
add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val']): N | null | undefined {
|
|
208
213
|
const _bfs = (root: N, newNode: N | null): N | undefined | null => {
|
|
209
|
-
const queue
|
|
210
|
-
while (queue.
|
|
214
|
+
const queue = new Queue<N | null>([root]);
|
|
215
|
+
while (queue.size > 0) {
|
|
211
216
|
const cur = queue.shift();
|
|
212
217
|
if (cur) {
|
|
213
218
|
if (newNode && cur.key === newNode.key) return;
|
|
@@ -300,13 +305,13 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
300
305
|
}
|
|
301
306
|
|
|
302
307
|
/**
|
|
303
|
-
* The `
|
|
308
|
+
* The `delete` function in TypeScript is used to delete a node from a binary search tree and returns an array of objects
|
|
304
309
|
* containing the deleted node and the node that needs to be balanced.
|
|
305
310
|
* @param {N | BinaryTreeNodeKey} nodeOrKey - The `nodeOrKey` parameter can be either a node object (`N`) or a binary tree
|
|
306
311
|
* node ID (`BinaryTreeNodeKey`).
|
|
307
|
-
* @returns The function `
|
|
312
|
+
* @returns The function `delete` returns an array of `BinaryTreeDeletedResult<N>` objects.
|
|
308
313
|
*/
|
|
309
|
-
|
|
314
|
+
delete(nodeOrKey: N | BinaryTreeNodeKey): BinaryTreeDeletedResult<N>[] {
|
|
310
315
|
const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
|
|
311
316
|
if (!this.root) return bstDeletedResult;
|
|
312
317
|
|
|
@@ -333,7 +338,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
333
338
|
const leftSubTreeRightMost = curr.left ? this.getRightMost(curr.left) : null;
|
|
334
339
|
if (leftSubTreeRightMost) {
|
|
335
340
|
const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
|
|
336
|
-
orgCurrent = this.
|
|
341
|
+
orgCurrent = this._swap(curr, leftSubTreeRightMost);
|
|
337
342
|
if (parentOfLeftSubTreeMax) {
|
|
338
343
|
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
|
|
339
344
|
parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
|
|
@@ -505,8 +510,8 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
505
510
|
|
|
506
511
|
_traverse(this.root);
|
|
507
512
|
} else {
|
|
508
|
-
const queue
|
|
509
|
-
while (queue.
|
|
513
|
+
const queue = new Queue<N>([this.root]);
|
|
514
|
+
while (queue.size > 0) {
|
|
510
515
|
const cur = queue.shift();
|
|
511
516
|
if (cur) {
|
|
512
517
|
if (this._pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne)) return result;
|
|
@@ -683,12 +688,12 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
683
688
|
|
|
684
689
|
/**
|
|
685
690
|
* The function checks if a binary search tree is valid by traversing it either recursively or iteratively.
|
|
686
|
-
* @param {N | null}
|
|
691
|
+
* @param {N | null} subTreeRoot - The `node` parameter represents the root node of a binary search tree (BST).
|
|
687
692
|
* @returns a boolean value.
|
|
688
693
|
*/
|
|
689
|
-
isSubtreeBST(
|
|
694
|
+
isSubtreeBST(subTreeRoot: N | null): boolean {
|
|
690
695
|
// TODO there is a bug
|
|
691
|
-
if (!
|
|
696
|
+
if (!subTreeRoot) return true;
|
|
692
697
|
|
|
693
698
|
if (this._loopType === LoopType.RECURSIVE) {
|
|
694
699
|
const dfs = (cur: N | null | undefined, min: BinaryTreeNodeKey, max: BinaryTreeNodeKey): boolean => {
|
|
@@ -697,11 +702,11 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
697
702
|
return dfs(cur.left, min, cur.key) && dfs(cur.right, cur.key, max);
|
|
698
703
|
};
|
|
699
704
|
|
|
700
|
-
return dfs(
|
|
705
|
+
return dfs(subTreeRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
|
|
701
706
|
} else {
|
|
702
707
|
const stack = [];
|
|
703
708
|
let prev = Number.MIN_SAFE_INTEGER,
|
|
704
|
-
curr: N | null | undefined =
|
|
709
|
+
curr: N | null | undefined = subTreeRoot;
|
|
705
710
|
while (curr || stack.length > 0) {
|
|
706
711
|
while (curr) {
|
|
707
712
|
stack.push(curr);
|
|
@@ -759,92 +764,21 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
759
764
|
}
|
|
760
765
|
|
|
761
766
|
/**
|
|
762
|
-
* The function `
|
|
763
|
-
* @param {N | BinaryTreeNodeKey | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a binary
|
|
764
|
-
* tree or the ID of a binary tree node. It can also be `null` if there is no subtree.
|
|
765
|
-
* @param {BinaryTreeNodePropertyName} [propertyName] - propertyName is an optional parameter that specifies the
|
|
766
|
-
* property of the binary tree node to use for calculating the sum. It can be either 'key' or 'val'. If propertyName is
|
|
767
|
-
* not provided, it defaults to 'key'.
|
|
768
|
-
* @returns a number, which is the sum of the values of the specified property in the subtree rooted at `subTreeRoot`.
|
|
769
|
-
*/
|
|
770
|
-
subTreeSum(subTreeRoot: N | BinaryTreeNodeKey | null, propertyName: BinaryTreeNodePropertyName = 'key'): number {
|
|
771
|
-
if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot, 'key');
|
|
772
|
-
|
|
773
|
-
if (!subTreeRoot) return 0;
|
|
774
|
-
|
|
775
|
-
let sum = 0;
|
|
776
|
-
|
|
777
|
-
const _sumByProperty = (cur: N) => {
|
|
778
|
-
let needSum: number;
|
|
779
|
-
switch (propertyName) {
|
|
780
|
-
case 'key':
|
|
781
|
-
needSum = cur.key;
|
|
782
|
-
break;
|
|
783
|
-
case 'val':
|
|
784
|
-
needSum = typeof cur.val === 'number' ? cur.val : 0;
|
|
785
|
-
break;
|
|
786
|
-
default:
|
|
787
|
-
needSum = cur.key;
|
|
788
|
-
break;
|
|
789
|
-
}
|
|
790
|
-
return needSum;
|
|
791
|
-
};
|
|
792
|
-
|
|
793
|
-
if (this._loopType === LoopType.RECURSIVE) {
|
|
794
|
-
const _traverse = (cur: N): void => {
|
|
795
|
-
sum += _sumByProperty(cur);
|
|
796
|
-
cur.left && _traverse(cur.left);
|
|
797
|
-
cur.right && _traverse(cur.right);
|
|
798
|
-
};
|
|
799
|
-
|
|
800
|
-
_traverse(subTreeRoot);
|
|
801
|
-
} else {
|
|
802
|
-
const stack: N[] = [subTreeRoot];
|
|
803
|
-
|
|
804
|
-
while (stack.length > 0) {
|
|
805
|
-
const cur = stack.pop()!;
|
|
806
|
-
sum += _sumByProperty(cur);
|
|
807
|
-
cur.right && stack.push(cur.right);
|
|
808
|
-
cur.left && stack.push(cur.left);
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
return sum;
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
/**
|
|
816
|
-
* The function `subTreeAdd` adds a delta value to a specified property of each node in a subtree.
|
|
767
|
+
* The function `subTreeForeach` adds a delta value to a specified property of each node in a subtree.
|
|
817
768
|
* @param {N | BinaryTreeNodeKey | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a binary
|
|
818
769
|
* tree or the ID of a node in the binary tree. It can also be `null` if there is no subtree to add to.
|
|
819
|
-
* @param
|
|
820
|
-
* each node in the subtree should be incremented.
|
|
821
|
-
* @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
|
|
770
|
+
* @param callback - The `callback` parameter is a function that takes a node as a parameter and returns a value.
|
|
822
771
|
* specifies the property of the binary tree node that should be modified. If not provided, it defaults to 'key'.
|
|
823
772
|
* @returns a boolean value.
|
|
824
773
|
*/
|
|
825
|
-
|
|
826
|
-
subTreeRoot: N | BinaryTreeNodeKey | null,
|
|
827
|
-
delta: number,
|
|
828
|
-
propertyName: BinaryTreeNodePropertyName = 'key'
|
|
829
|
-
): boolean {
|
|
774
|
+
subTreeForeach(subTreeRoot: N | BinaryTreeNodeKey | null, callback: (node: N) => any): boolean {
|
|
830
775
|
if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot, 'key');
|
|
831
776
|
|
|
832
777
|
if (!subTreeRoot) return false;
|
|
833
778
|
|
|
834
|
-
const _addByProperty = (cur: N) => {
|
|
835
|
-
switch (propertyName) {
|
|
836
|
-
case 'key':
|
|
837
|
-
cur.key += delta;
|
|
838
|
-
break;
|
|
839
|
-
default:
|
|
840
|
-
cur.key += delta;
|
|
841
|
-
break;
|
|
842
|
-
}
|
|
843
|
-
};
|
|
844
|
-
|
|
845
779
|
if (this._loopType === LoopType.RECURSIVE) {
|
|
846
780
|
const _traverse = (cur: N) => {
|
|
847
|
-
|
|
781
|
+
callback(cur);
|
|
848
782
|
cur.left && _traverse(cur.left);
|
|
849
783
|
cur.right && _traverse(cur.right);
|
|
850
784
|
};
|
|
@@ -856,7 +790,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
856
790
|
while (stack.length > 0) {
|
|
857
791
|
const cur = stack.pop()!;
|
|
858
792
|
|
|
859
|
-
|
|
793
|
+
callback(cur);
|
|
860
794
|
cur.right && stack.push(cur.right);
|
|
861
795
|
cur.left && stack.push(cur.left);
|
|
862
796
|
}
|
|
@@ -900,9 +834,9 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
900
834
|
*/
|
|
901
835
|
bfs(nodeOrPropertyName: NodeOrPropertyName = 'key'): BinaryTreeNodeProperties<N> {
|
|
902
836
|
this._clearResults();
|
|
903
|
-
const queue
|
|
837
|
+
const queue = new Queue<N | null | undefined>([this.root]);
|
|
904
838
|
|
|
905
|
-
while (queue.
|
|
839
|
+
while (queue.size !== 0) {
|
|
906
840
|
const cur = queue.shift();
|
|
907
841
|
if (cur) {
|
|
908
842
|
this._accumulatedByPropertyName(cur, nodeOrPropertyName);
|
|
@@ -931,215 +865,98 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
931
865
|
* Performs a depth-first search (dfs) traversal on a binary tree and accumulates properties of each node based on the specified property name.
|
|
932
866
|
* @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
|
|
933
867
|
* @param {string} nodeOrPropertyName - The name of the property to accumulate.
|
|
868
|
+
* @param loopType - The type of loop to use for the depth-first search traversal. The default value is `LoopType.ITERATIVE`.
|
|
934
869
|
* @returns An array of values corresponding to the specified property.
|
|
935
870
|
*/
|
|
936
|
-
dfs(pattern: DFSOrderPattern, nodeOrPropertyName: 'key'): BinaryTreeNodeKey[];
|
|
871
|
+
dfs(pattern: DFSOrderPattern, nodeOrPropertyName: 'key', loopType?: LoopType): BinaryTreeNodeKey[];
|
|
937
872
|
|
|
938
873
|
/**
|
|
939
874
|
* Performs a depth-first search (dfs) traversal on a binary tree and accumulates the 'val' property of each node.
|
|
940
875
|
* @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
|
|
941
876
|
* @param {'val'} nodeOrPropertyName - The name of the property to accumulate.
|
|
877
|
+
* @param loopType - The type of loop to use for the depth-first search traversal. The default value is `LoopType.ITERATIVE`.
|
|
942
878
|
* @returns An array of 'val' properties from each node.
|
|
943
879
|
*/
|
|
944
|
-
dfs(pattern: DFSOrderPattern, nodeOrPropertyName: 'val'): N[];
|
|
880
|
+
dfs(pattern: DFSOrderPattern, nodeOrPropertyName: 'val', loopType?: LoopType): N[];
|
|
945
881
|
|
|
946
882
|
/**
|
|
947
883
|
* Performs a depth-first search (dfs) traversal on a binary tree and accumulates nodes themselves.
|
|
948
884
|
* @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
|
|
949
885
|
* @param {'node'} nodeOrPropertyName - The name of the property to accumulate.
|
|
886
|
+
* @param loopType - The type of loop to use for the depth-first search traversal. The default value is `LoopType.ITERATIVE`.
|
|
950
887
|
* @returns An array of binary tree nodes.
|
|
951
888
|
*/
|
|
952
|
-
dfs(pattern: DFSOrderPattern, nodeOrPropertyName: 'node'): N[];
|
|
889
|
+
dfs(pattern: DFSOrderPattern, nodeOrPropertyName: 'node', loopType?: LoopType): N[];
|
|
953
890
|
|
|
954
891
|
/**
|
|
955
892
|
* The dfs function performs a depth-first search traversal on a binary tree and returns the accumulated properties of
|
|
956
893
|
* each node based on the specified pattern and property name.
|
|
957
894
|
* @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
|
|
958
895
|
* @param {NodeOrPropertyName} [nodeOrPropertyName] - The name of a property of the nodes in the binary tree. This property will be used to accumulate values during the depth-first search traversal. If no `nodeOrPropertyName` is provided, the default value is `'key'`.
|
|
896
|
+
* @param loopType - The type of loop to use for the depth-first search traversal. The default value is `LoopType.ITERATIVE`.
|
|
959
897
|
* @returns an instance of the BinaryTreeNodeProperties class, which contains the accumulated properties of the binary tree nodes based on the specified pattern and node or property name.
|
|
960
898
|
*/
|
|
961
|
-
dfs(
|
|
962
|
-
this._clearResults();
|
|
963
|
-
const _traverse = (node: N) => {
|
|
964
|
-
switch (pattern) {
|
|
965
|
-
case 'in':
|
|
966
|
-
if (node.left) _traverse(node.left);
|
|
967
|
-
this._accumulatedByPropertyName(node, nodeOrPropertyName);
|
|
968
|
-
if (node.right) _traverse(node.right);
|
|
969
|
-
break;
|
|
970
|
-
case 'pre':
|
|
971
|
-
this._accumulatedByPropertyName(node, nodeOrPropertyName);
|
|
972
|
-
if (node.left) _traverse(node.left);
|
|
973
|
-
if (node.right) _traverse(node.right);
|
|
974
|
-
break;
|
|
975
|
-
case 'post':
|
|
976
|
-
if (node.left) _traverse(node.left);
|
|
977
|
-
if (node.right) _traverse(node.right);
|
|
978
|
-
this._accumulatedByPropertyName(node, nodeOrPropertyName);
|
|
979
|
-
break;
|
|
980
|
-
}
|
|
981
|
-
};
|
|
982
|
-
|
|
983
|
-
this.root && _traverse(this.root);
|
|
984
|
-
return this._getResultByPropertyName(nodeOrPropertyName);
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
// --- start additional methods ---
|
|
988
|
-
|
|
989
|
-
/**
|
|
990
|
-
* Performs an iterative depth-first search (dfs) traversal on a binary tree and accumulates properties of each node based on their 'key' property.
|
|
991
|
-
* @returns An array of binary tree node IDs.
|
|
992
|
-
*/
|
|
993
|
-
dfsIterative(): BinaryTreeNodeKey[];
|
|
994
|
-
|
|
995
|
-
/**
|
|
996
|
-
* Performs an iterative depth-first search (dfs) traversal on a binary tree and accumulates properties of each node based on their 'key' property.
|
|
997
|
-
* @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
|
|
998
|
-
* @returns An array of values corresponding to the specified property.
|
|
999
|
-
*/
|
|
1000
|
-
dfsIterative(pattern: DFSOrderPattern): BinaryTreeNodeKey[];
|
|
1001
|
-
|
|
1002
|
-
/**
|
|
1003
|
-
* Performs an iterative depth-first search (dfs) traversal on a binary tree and accumulates properties of each node based on the specified property name.
|
|
1004
|
-
* @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
|
|
1005
|
-
* @param {string} nodeOrPropertyName - The name of the property to accumulate.
|
|
1006
|
-
* @returns An array of values corresponding to the specified property.
|
|
1007
|
-
*/
|
|
1008
|
-
dfsIterative(pattern: DFSOrderPattern, nodeOrPropertyName: 'key'): BinaryTreeNodeKey[];
|
|
1009
|
-
|
|
1010
|
-
/**
|
|
1011
|
-
* Performs an iterative depth-first search (dfs) traversal on a binary tree and accumulates the 'val' property of each node.
|
|
1012
|
-
* @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
|
|
1013
|
-
* @param {'val'} nodeOrPropertyName - The name of the property to accumulate.
|
|
1014
|
-
* @returns An array of 'val' properties from each node.
|
|
1015
|
-
*/
|
|
1016
|
-
dfsIterative(pattern: DFSOrderPattern, nodeOrPropertyName: 'val'): N['val'][];
|
|
1017
|
-
|
|
1018
|
-
/**
|
|
1019
|
-
* Performs an iterative depth-first search (dfs) traversal on a binary tree and accumulates nodes themselves.
|
|
1020
|
-
* @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
|
|
1021
|
-
* @param {'node'} nodeOrPropertyName - The name of the property to accumulate.
|
|
1022
|
-
* @returns An array of binary tree nodes.
|
|
1023
|
-
*/
|
|
1024
|
-
dfsIterative(pattern: DFSOrderPattern, nodeOrPropertyName: 'node'): N[];
|
|
1025
|
-
|
|
1026
|
-
/**
|
|
1027
|
-
* The dfsIterative function performs an iterative depth-first search traversal on a binary tree, with the option to
|
|
1028
|
-
* specify the traversal pattern and the property name to accumulate results by.
|
|
1029
|
-
* @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
|
|
1030
|
-
* @param {NodeOrPropertyName} [nodeOrPropertyName] - The name of a property of the nodes in the binary tree. This property will be used to accumulate values during the depth-first search traversal. By default, it is set to `'key'`.
|
|
1031
|
-
* @returns An object of type BinaryTreeNodeProperties<N>.
|
|
1032
|
-
*/
|
|
1033
|
-
dfsIterative(
|
|
899
|
+
dfs(
|
|
1034
900
|
pattern: DFSOrderPattern = 'in',
|
|
1035
|
-
nodeOrPropertyName: NodeOrPropertyName = 'key'
|
|
901
|
+
nodeOrPropertyName: NodeOrPropertyName = 'key',
|
|
902
|
+
loopType: LoopType = LoopType.ITERATIVE
|
|
1036
903
|
): BinaryTreeNodeProperties<N> {
|
|
1037
904
|
this._clearResults();
|
|
1038
|
-
if (
|
|
1039
|
-
|
|
1040
|
-
const stack: {opt: 0 | 1; node: N | null | undefined}[] = [{opt: 0, node: this.root}];
|
|
1041
|
-
|
|
1042
|
-
while (stack.length > 0) {
|
|
1043
|
-
const cur = stack.pop();
|
|
1044
|
-
if (!cur || !cur.node) continue;
|
|
1045
|
-
if (cur.opt === 1) {
|
|
1046
|
-
this._accumulatedByPropertyName(cur.node, nodeOrPropertyName);
|
|
1047
|
-
} else {
|
|
905
|
+
if (loopType === LoopType.RECURSIVE) {
|
|
906
|
+
const _traverse = (node: N) => {
|
|
1048
907
|
switch (pattern) {
|
|
1049
908
|
case 'in':
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
909
|
+
if (node.left) _traverse(node.left);
|
|
910
|
+
this._accumulatedByPropertyName(node, nodeOrPropertyName);
|
|
911
|
+
if (node.right) _traverse(node.right);
|
|
1053
912
|
break;
|
|
1054
913
|
case 'pre':
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
914
|
+
this._accumulatedByPropertyName(node, nodeOrPropertyName);
|
|
915
|
+
if (node.left) _traverse(node.left);
|
|
916
|
+
if (node.right) _traverse(node.right);
|
|
1058
917
|
break;
|
|
1059
918
|
case 'post':
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
break;
|
|
1064
|
-
default:
|
|
1065
|
-
stack.push({opt: 0, node: cur.node.right});
|
|
1066
|
-
stack.push({opt: 1, node: cur.node});
|
|
1067
|
-
stack.push({opt: 0, node: cur.node.left});
|
|
919
|
+
if (node.left) _traverse(node.left);
|
|
920
|
+
if (node.right) _traverse(node.right);
|
|
921
|
+
this._accumulatedByPropertyName(node, nodeOrPropertyName);
|
|
1068
922
|
break;
|
|
1069
923
|
}
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
return this._getResultByPropertyName(nodeOrPropertyName);
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
/**
|
|
1077
|
-
* Performs a level-order traversal on a binary tree starting from the specified node and accumulates properties of each node based on their 'key' property.
|
|
1078
|
-
* @returns An array of binary tree node IDs.
|
|
1079
|
-
*/
|
|
1080
|
-
levelIterative(): BinaryTreeNodeKey[];
|
|
1081
|
-
|
|
1082
|
-
/**
|
|
1083
|
-
* Performs a level-order traversal on a binary tree starting from the specified node and accumulates properties of each node based on their 'key' property.
|
|
1084
|
-
* @param {N | null} node - The starting node for the level order traversal. If null, the root node of the tree is used as the starting node.
|
|
1085
|
-
* @returns An array of binary tree node IDs.
|
|
1086
|
-
*/
|
|
1087
|
-
levelIterative(node: N | null): BinaryTreeNodeKey[];
|
|
1088
|
-
|
|
1089
|
-
/**
|
|
1090
|
-
* Performs a level-order traversal on a binary tree starting from the specified node and accumulates properties of each node based on the specified property name.
|
|
1091
|
-
* @param {N | null} node - The starting node for the level order traversal. If null, the root node of the tree is used as the starting node.
|
|
1092
|
-
* @param {string} nodeOrPropertyName - The name of the property to accumulate.
|
|
1093
|
-
* @returns An array of values corresponding to the specified property.
|
|
1094
|
-
*/
|
|
1095
|
-
levelIterative(node: N | null, nodeOrPropertyName: 'key'): BinaryTreeNodeKey[];
|
|
1096
|
-
|
|
1097
|
-
/**
|
|
1098
|
-
* Performs a level-order traversal on a binary tree starting from the specified node and accumulates the 'val' property of each node.
|
|
1099
|
-
* @param {N | null} node - The starting node for the level order traversal. If null, the root node of the tree is used as the starting node.
|
|
1100
|
-
* @param {'val'} nodeOrPropertyName - The name of the property to accumulate.
|
|
1101
|
-
* @returns An array of 'val' properties from each node.
|
|
1102
|
-
*/
|
|
1103
|
-
levelIterative(node: N | null, nodeOrPropertyName: 'val'): N['val'][];
|
|
1104
|
-
|
|
1105
|
-
/**
|
|
1106
|
-
* Performs a level-order traversal on a binary tree starting from the specified node and accumulates nodes themselves.
|
|
1107
|
-
* @param {N | null} node - The starting node for the level order traversal. If null, the root node of the tree is used as the starting node.
|
|
1108
|
-
* @param {'node'} nodeOrPropertyName - The name of the property to accumulate.
|
|
1109
|
-
* @returns An array of binary tree nodes.
|
|
1110
|
-
*/
|
|
1111
|
-
levelIterative(node: N | null, nodeOrPropertyName: 'node'): N[];
|
|
1112
|
-
|
|
1113
|
-
/**
|
|
1114
|
-
* The `levelIterative` function performs a level-order traversal on a binary tree and returns the values of the nodes
|
|
1115
|
-
* in an array, based on a specified property name.
|
|
1116
|
-
* @param {N | null} node - The `node` parameter is a BinaryTreeNode object representing the starting
|
|
1117
|
-
* node for the level order traversal. It can be null if no specific node is provided, in which case the root node of
|
|
1118
|
-
* the tree is used as the starting node.
|
|
1119
|
-
* @param {NodeOrPropertyName} [nodeOrPropertyName] - The `nodeOrPropertyName` parameter is an optional parameter that
|
|
1120
|
-
* can be either a `BinaryTreeNode` property name or the string `'key'`. If a property name is provided, the function
|
|
1121
|
-
* will accumulate results based on that property. If no property name is provided, the function will default to
|
|
1122
|
-
* accumulating results based on the 'key' property.
|
|
1123
|
-
* @returns An object of type `BinaryTreeNodeProperties<N>`.
|
|
1124
|
-
*/
|
|
1125
|
-
levelIterative(
|
|
1126
|
-
node: N | null = this.root,
|
|
1127
|
-
nodeOrPropertyName: NodeOrPropertyName = 'key'
|
|
1128
|
-
): BinaryTreeNodeProperties<N> {
|
|
1129
|
-
if (!node) return [];
|
|
924
|
+
};
|
|
1130
925
|
|
|
1131
|
-
|
|
1132
|
-
|
|
926
|
+
this.root && _traverse(this.root);
|
|
927
|
+
} else {
|
|
928
|
+
if (!this.root) return this._getResultByPropertyName(nodeOrPropertyName);
|
|
929
|
+
// 0: visit, 1: print
|
|
930
|
+
const stack: {opt: 0 | 1; node: N | null | undefined}[] = [{opt: 0, node: this.root}];
|
|
1133
931
|
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
932
|
+
while (stack.length > 0) {
|
|
933
|
+
const cur = stack.pop();
|
|
934
|
+
if (!cur || !cur.node) continue;
|
|
935
|
+
if (cur.opt === 1) {
|
|
936
|
+
this._accumulatedByPropertyName(cur.node, nodeOrPropertyName);
|
|
937
|
+
} else {
|
|
938
|
+
switch (pattern) {
|
|
939
|
+
case 'in':
|
|
940
|
+
stack.push({opt: 0, node: cur.node.right});
|
|
941
|
+
stack.push({opt: 1, node: cur.node});
|
|
942
|
+
stack.push({opt: 0, node: cur.node.left});
|
|
943
|
+
break;
|
|
944
|
+
case 'pre':
|
|
945
|
+
stack.push({opt: 0, node: cur.node.right});
|
|
946
|
+
stack.push({opt: 0, node: cur.node.left});
|
|
947
|
+
stack.push({opt: 1, node: cur.node});
|
|
948
|
+
break;
|
|
949
|
+
case 'post':
|
|
950
|
+
stack.push({opt: 1, node: cur.node});
|
|
951
|
+
stack.push({opt: 0, node: cur.node.right});
|
|
952
|
+
stack.push({opt: 0, node: cur.node.left});
|
|
953
|
+
break;
|
|
954
|
+
default:
|
|
955
|
+
stack.push({opt: 0, node: cur.node.right});
|
|
956
|
+
stack.push({opt: 1, node: cur.node});
|
|
957
|
+
stack.push({opt: 0, node: cur.node.left});
|
|
958
|
+
break;
|
|
959
|
+
}
|
|
1143
960
|
}
|
|
1144
961
|
}
|
|
1145
962
|
}
|
|
@@ -1147,6 +964,8 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
1147
964
|
return this._getResultByPropertyName(nodeOrPropertyName);
|
|
1148
965
|
}
|
|
1149
966
|
|
|
967
|
+
// --- start additional methods ---
|
|
968
|
+
|
|
1150
969
|
/**
|
|
1151
970
|
* Collects nodes from a binary tree by a specified property and organizes them into levels.
|
|
1152
971
|
* @returns A 2D array of AbstractBinaryTreeNodeProperty<N> objects.
|
|
@@ -1425,14 +1244,6 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
1425
1244
|
}
|
|
1426
1245
|
}
|
|
1427
1246
|
|
|
1428
|
-
/**
|
|
1429
|
-
* The function sets the loop type for a protected variable.
|
|
1430
|
-
* @param {LoopType} value - The value parameter is of type LoopType.
|
|
1431
|
-
*/
|
|
1432
|
-
protected _setLoopType(value: LoopType) {
|
|
1433
|
-
this._loopType = value;
|
|
1434
|
-
}
|
|
1435
|
-
|
|
1436
1247
|
/**
|
|
1437
1248
|
* The function sets the root property of an object to a given value, and if the value is not null, it also sets the
|
|
1438
1249
|
* parent property of the value to undefined.
|