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
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { FamilyPosition, LoopType } from '../../types';
|
|
9
9
|
import { trampoline } from '../../utils';
|
|
10
|
+
import { Queue } from '../queue';
|
|
10
11
|
export class BinaryTreeNode {
|
|
11
12
|
/**
|
|
12
13
|
* The constructor function initializes a BinaryTreeNode object with a key and an optional value.
|
|
@@ -114,14 +115,17 @@ export class BinaryTree {
|
|
|
114
115
|
get loopType() {
|
|
115
116
|
return this._loopType;
|
|
116
117
|
}
|
|
118
|
+
set loopType(v) {
|
|
119
|
+
this._loopType = v;
|
|
120
|
+
}
|
|
117
121
|
/**
|
|
118
|
-
* The `
|
|
119
|
-
* @param {N} srcNode - The source node that you want to
|
|
122
|
+
* The `_swap` function swaps the location of two nodes in a binary tree.
|
|
123
|
+
* @param {N} srcNode - The source node that you want to _swap with the destination node.
|
|
120
124
|
* @param {N} destNode - The `destNode` parameter represents the destination node where the values from `srcNode` will
|
|
121
125
|
* be swapped to.
|
|
122
126
|
* @returns The `destNode` is being returned.
|
|
123
127
|
*/
|
|
124
|
-
|
|
128
|
+
_swap(srcNode, destNode) {
|
|
125
129
|
const { key, val } = destNode;
|
|
126
130
|
const tempNode = this.createNode(key, val);
|
|
127
131
|
if (tempNode) {
|
|
@@ -162,8 +166,8 @@ export class BinaryTree {
|
|
|
162
166
|
*/
|
|
163
167
|
add(keyOrNode, val) {
|
|
164
168
|
const _bfs = (root, newNode) => {
|
|
165
|
-
const queue = [root];
|
|
166
|
-
while (queue.
|
|
169
|
+
const queue = new Queue([root]);
|
|
170
|
+
while (queue.size > 0) {
|
|
167
171
|
const cur = queue.shift();
|
|
168
172
|
if (cur) {
|
|
169
173
|
if (newNode && cur.key === newNode.key)
|
|
@@ -258,13 +262,13 @@ export class BinaryTree {
|
|
|
258
262
|
return keysOrNodes.length === this.addMany(keysOrNodes, data).length;
|
|
259
263
|
}
|
|
260
264
|
/**
|
|
261
|
-
* The `
|
|
265
|
+
* The `delete` function in TypeScript is used to delete a node from a binary search tree and returns an array of objects
|
|
262
266
|
* containing the deleted node and the node that needs to be balanced.
|
|
263
267
|
* @param {N | BinaryTreeNodeKey} nodeOrKey - The `nodeOrKey` parameter can be either a node object (`N`) or a binary tree
|
|
264
268
|
* node ID (`BinaryTreeNodeKey`).
|
|
265
|
-
* @returns The function `
|
|
269
|
+
* @returns The function `delete` returns an array of `BinaryTreeDeletedResult<N>` objects.
|
|
266
270
|
*/
|
|
267
|
-
|
|
271
|
+
delete(nodeOrKey) {
|
|
268
272
|
const bstDeletedResult = [];
|
|
269
273
|
if (!this.root)
|
|
270
274
|
return bstDeletedResult;
|
|
@@ -293,7 +297,7 @@ export class BinaryTree {
|
|
|
293
297
|
const leftSubTreeRightMost = curr.left ? this.getRightMost(curr.left) : null;
|
|
294
298
|
if (leftSubTreeRightMost) {
|
|
295
299
|
const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
|
|
296
|
-
orgCurrent = this.
|
|
300
|
+
orgCurrent = this._swap(curr, leftSubTreeRightMost);
|
|
297
301
|
if (parentOfLeftSubTreeMax) {
|
|
298
302
|
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
|
|
299
303
|
parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
|
|
@@ -458,8 +462,8 @@ export class BinaryTree {
|
|
|
458
462
|
_traverse(this.root);
|
|
459
463
|
}
|
|
460
464
|
else {
|
|
461
|
-
const queue = [this.root];
|
|
462
|
-
while (queue.
|
|
465
|
+
const queue = new Queue([this.root]);
|
|
466
|
+
while (queue.size > 0) {
|
|
463
467
|
const cur = queue.shift();
|
|
464
468
|
if (cur) {
|
|
465
469
|
if (this._pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne))
|
|
@@ -589,12 +593,12 @@ export class BinaryTree {
|
|
|
589
593
|
}
|
|
590
594
|
/**
|
|
591
595
|
* The function checks if a binary search tree is valid by traversing it either recursively or iteratively.
|
|
592
|
-
* @param {N | null}
|
|
596
|
+
* @param {N | null} subTreeRoot - The `node` parameter represents the root node of a binary search tree (BST).
|
|
593
597
|
* @returns a boolean value.
|
|
594
598
|
*/
|
|
595
|
-
isSubtreeBST(
|
|
599
|
+
isSubtreeBST(subTreeRoot) {
|
|
596
600
|
// TODO there is a bug
|
|
597
|
-
if (!
|
|
601
|
+
if (!subTreeRoot)
|
|
598
602
|
return true;
|
|
599
603
|
if (this._loopType === LoopType.RECURSIVE) {
|
|
600
604
|
const dfs = (cur, min, max) => {
|
|
@@ -604,11 +608,11 @@ export class BinaryTree {
|
|
|
604
608
|
return false;
|
|
605
609
|
return dfs(cur.left, min, cur.key) && dfs(cur.right, cur.key, max);
|
|
606
610
|
};
|
|
607
|
-
return dfs(
|
|
611
|
+
return dfs(subTreeRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
|
|
608
612
|
}
|
|
609
613
|
else {
|
|
610
614
|
const stack = [];
|
|
611
|
-
let prev = Number.MIN_SAFE_INTEGER, curr =
|
|
615
|
+
let prev = Number.MIN_SAFE_INTEGER, curr = subTreeRoot;
|
|
612
616
|
while (curr || stack.length > 0) {
|
|
613
617
|
while (curr) {
|
|
614
618
|
stack.push(curr);
|
|
@@ -662,82 +666,21 @@ export class BinaryTree {
|
|
|
662
666
|
}
|
|
663
667
|
}
|
|
664
668
|
/**
|
|
665
|
-
* The function `
|
|
666
|
-
* @param {N | BinaryTreeNodeKey | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a binary
|
|
667
|
-
* tree or the ID of a binary tree node. It can also be `null` if there is no subtree.
|
|
668
|
-
* @param {BinaryTreeNodePropertyName} [propertyName] - propertyName is an optional parameter that specifies the
|
|
669
|
-
* property of the binary tree node to use for calculating the sum. It can be either 'key' or 'val'. If propertyName is
|
|
670
|
-
* not provided, it defaults to 'key'.
|
|
671
|
-
* @returns a number, which is the sum of the values of the specified property in the subtree rooted at `subTreeRoot`.
|
|
672
|
-
*/
|
|
673
|
-
subTreeSum(subTreeRoot, propertyName = 'key') {
|
|
674
|
-
if (typeof subTreeRoot === 'number')
|
|
675
|
-
subTreeRoot = this.get(subTreeRoot, 'key');
|
|
676
|
-
if (!subTreeRoot)
|
|
677
|
-
return 0;
|
|
678
|
-
let sum = 0;
|
|
679
|
-
const _sumByProperty = (cur) => {
|
|
680
|
-
let needSum;
|
|
681
|
-
switch (propertyName) {
|
|
682
|
-
case 'key':
|
|
683
|
-
needSum = cur.key;
|
|
684
|
-
break;
|
|
685
|
-
case 'val':
|
|
686
|
-
needSum = typeof cur.val === 'number' ? cur.val : 0;
|
|
687
|
-
break;
|
|
688
|
-
default:
|
|
689
|
-
needSum = cur.key;
|
|
690
|
-
break;
|
|
691
|
-
}
|
|
692
|
-
return needSum;
|
|
693
|
-
};
|
|
694
|
-
if (this._loopType === LoopType.RECURSIVE) {
|
|
695
|
-
const _traverse = (cur) => {
|
|
696
|
-
sum += _sumByProperty(cur);
|
|
697
|
-
cur.left && _traverse(cur.left);
|
|
698
|
-
cur.right && _traverse(cur.right);
|
|
699
|
-
};
|
|
700
|
-
_traverse(subTreeRoot);
|
|
701
|
-
}
|
|
702
|
-
else {
|
|
703
|
-
const stack = [subTreeRoot];
|
|
704
|
-
while (stack.length > 0) {
|
|
705
|
-
const cur = stack.pop();
|
|
706
|
-
sum += _sumByProperty(cur);
|
|
707
|
-
cur.right && stack.push(cur.right);
|
|
708
|
-
cur.left && stack.push(cur.left);
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
return sum;
|
|
712
|
-
}
|
|
713
|
-
/**
|
|
714
|
-
* The function `subTreeAdd` adds a delta value to a specified property of each node in a subtree.
|
|
669
|
+
* The function `subTreeForeach` adds a delta value to a specified property of each node in a subtree.
|
|
715
670
|
* @param {N | BinaryTreeNodeKey | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a binary
|
|
716
671
|
* tree or the ID of a node in the binary tree. It can also be `null` if there is no subtree to add to.
|
|
717
|
-
* @param
|
|
718
|
-
* each node in the subtree should be incremented.
|
|
719
|
-
* @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
|
|
672
|
+
* @param callback - The `callback` parameter is a function that takes a node as a parameter and returns a value.
|
|
720
673
|
* specifies the property of the binary tree node that should be modified. If not provided, it defaults to 'key'.
|
|
721
674
|
* @returns a boolean value.
|
|
722
675
|
*/
|
|
723
|
-
|
|
676
|
+
subTreeForeach(subTreeRoot, callback) {
|
|
724
677
|
if (typeof subTreeRoot === 'number')
|
|
725
678
|
subTreeRoot = this.get(subTreeRoot, 'key');
|
|
726
679
|
if (!subTreeRoot)
|
|
727
680
|
return false;
|
|
728
|
-
const _addByProperty = (cur) => {
|
|
729
|
-
switch (propertyName) {
|
|
730
|
-
case 'key':
|
|
731
|
-
cur.key += delta;
|
|
732
|
-
break;
|
|
733
|
-
default:
|
|
734
|
-
cur.key += delta;
|
|
735
|
-
break;
|
|
736
|
-
}
|
|
737
|
-
};
|
|
738
681
|
if (this._loopType === LoopType.RECURSIVE) {
|
|
739
682
|
const _traverse = (cur) => {
|
|
740
|
-
|
|
683
|
+
callback(cur);
|
|
741
684
|
cur.left && _traverse(cur.left);
|
|
742
685
|
cur.right && _traverse(cur.right);
|
|
743
686
|
};
|
|
@@ -747,7 +690,7 @@ export class BinaryTree {
|
|
|
747
690
|
const stack = [subTreeRoot];
|
|
748
691
|
while (stack.length > 0) {
|
|
749
692
|
const cur = stack.pop();
|
|
750
|
-
|
|
693
|
+
callback(cur);
|
|
751
694
|
cur.right && stack.push(cur.right);
|
|
752
695
|
cur.left && stack.push(cur.left);
|
|
753
696
|
}
|
|
@@ -763,8 +706,8 @@ export class BinaryTree {
|
|
|
763
706
|
*/
|
|
764
707
|
bfs(nodeOrPropertyName = 'key') {
|
|
765
708
|
this._clearResults();
|
|
766
|
-
const queue = [this.root];
|
|
767
|
-
while (queue.
|
|
709
|
+
const queue = new Queue([this.root]);
|
|
710
|
+
while (queue.size !== 0) {
|
|
768
711
|
const cur = queue.shift();
|
|
769
712
|
if (cur) {
|
|
770
713
|
this._accumulatedByPropertyName(cur, nodeOrPropertyName);
|
|
@@ -781,111 +724,74 @@ export class BinaryTree {
|
|
|
781
724
|
* each node based on the specified pattern and property name.
|
|
782
725
|
* @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
|
|
783
726
|
* @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'`.
|
|
727
|
+
* @param loopType - The type of loop to use for the depth-first search traversal. The default value is `LoopType.ITERATIVE`.
|
|
784
728
|
* @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.
|
|
785
729
|
*/
|
|
786
|
-
dfs(pattern = 'in', nodeOrPropertyName = 'key') {
|
|
730
|
+
dfs(pattern = 'in', nodeOrPropertyName = 'key', loopType = LoopType.ITERATIVE) {
|
|
787
731
|
this._clearResults();
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
case 'in':
|
|
791
|
-
if (node.left)
|
|
792
|
-
_traverse(node.left);
|
|
793
|
-
this._accumulatedByPropertyName(node, nodeOrPropertyName);
|
|
794
|
-
if (node.right)
|
|
795
|
-
_traverse(node.right);
|
|
796
|
-
break;
|
|
797
|
-
case 'pre':
|
|
798
|
-
this._accumulatedByPropertyName(node, nodeOrPropertyName);
|
|
799
|
-
if (node.left)
|
|
800
|
-
_traverse(node.left);
|
|
801
|
-
if (node.right)
|
|
802
|
-
_traverse(node.right);
|
|
803
|
-
break;
|
|
804
|
-
case 'post':
|
|
805
|
-
if (node.left)
|
|
806
|
-
_traverse(node.left);
|
|
807
|
-
if (node.right)
|
|
808
|
-
_traverse(node.right);
|
|
809
|
-
this._accumulatedByPropertyName(node, nodeOrPropertyName);
|
|
810
|
-
break;
|
|
811
|
-
}
|
|
812
|
-
};
|
|
813
|
-
this.root && _traverse(this.root);
|
|
814
|
-
return this._getResultByPropertyName(nodeOrPropertyName);
|
|
815
|
-
}
|
|
816
|
-
/**
|
|
817
|
-
* The dfsIterative function performs an iterative depth-first search traversal on a binary tree, with the option to
|
|
818
|
-
* specify the traversal pattern and the property name to accumulate results by.
|
|
819
|
-
* @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
|
|
820
|
-
* @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'`.
|
|
821
|
-
* @returns An object of type BinaryTreeNodeProperties<N>.
|
|
822
|
-
*/
|
|
823
|
-
dfsIterative(pattern = 'in', nodeOrPropertyName = 'key') {
|
|
824
|
-
this._clearResults();
|
|
825
|
-
if (!this.root)
|
|
826
|
-
return this._getResultByPropertyName(nodeOrPropertyName);
|
|
827
|
-
// 0: visit, 1: print
|
|
828
|
-
const stack = [{ opt: 0, node: this.root }];
|
|
829
|
-
while (stack.length > 0) {
|
|
830
|
-
const cur = stack.pop();
|
|
831
|
-
if (!cur || !cur.node)
|
|
832
|
-
continue;
|
|
833
|
-
if (cur.opt === 1) {
|
|
834
|
-
this._accumulatedByPropertyName(cur.node, nodeOrPropertyName);
|
|
835
|
-
}
|
|
836
|
-
else {
|
|
732
|
+
if (loopType === LoopType.RECURSIVE) {
|
|
733
|
+
const _traverse = (node) => {
|
|
837
734
|
switch (pattern) {
|
|
838
735
|
case 'in':
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
736
|
+
if (node.left)
|
|
737
|
+
_traverse(node.left);
|
|
738
|
+
this._accumulatedByPropertyName(node, nodeOrPropertyName);
|
|
739
|
+
if (node.right)
|
|
740
|
+
_traverse(node.right);
|
|
842
741
|
break;
|
|
843
742
|
case 'pre':
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
743
|
+
this._accumulatedByPropertyName(node, nodeOrPropertyName);
|
|
744
|
+
if (node.left)
|
|
745
|
+
_traverse(node.left);
|
|
746
|
+
if (node.right)
|
|
747
|
+
_traverse(node.right);
|
|
847
748
|
break;
|
|
848
749
|
case 'post':
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
stack.push({ opt: 0, node: cur.node.right });
|
|
855
|
-
stack.push({ opt: 1, node: cur.node });
|
|
856
|
-
stack.push({ opt: 0, node: cur.node.left });
|
|
750
|
+
if (node.left)
|
|
751
|
+
_traverse(node.left);
|
|
752
|
+
if (node.right)
|
|
753
|
+
_traverse(node.right);
|
|
754
|
+
this._accumulatedByPropertyName(node, nodeOrPropertyName);
|
|
857
755
|
break;
|
|
858
756
|
}
|
|
859
|
-
}
|
|
757
|
+
};
|
|
758
|
+
this.root && _traverse(this.root);
|
|
860
759
|
}
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
* accumulating results based on the 'key' property.
|
|
873
|
-
* @returns An object of type `BinaryTreeNodeProperties<N>`.
|
|
874
|
-
*/
|
|
875
|
-
levelIterative(node = this.root, nodeOrPropertyName = 'key') {
|
|
876
|
-
if (!node)
|
|
877
|
-
return [];
|
|
878
|
-
this._clearResults();
|
|
879
|
-
const queue = [node];
|
|
880
|
-
while (queue.length > 0) {
|
|
881
|
-
const cur = queue.shift();
|
|
882
|
-
if (cur) {
|
|
883
|
-
this._accumulatedByPropertyName(cur, nodeOrPropertyName);
|
|
884
|
-
if (cur.left) {
|
|
885
|
-
queue.push(cur.left);
|
|
760
|
+
else {
|
|
761
|
+
if (!this.root)
|
|
762
|
+
return this._getResultByPropertyName(nodeOrPropertyName);
|
|
763
|
+
// 0: visit, 1: print
|
|
764
|
+
const stack = [{ opt: 0, node: this.root }];
|
|
765
|
+
while (stack.length > 0) {
|
|
766
|
+
const cur = stack.pop();
|
|
767
|
+
if (!cur || !cur.node)
|
|
768
|
+
continue;
|
|
769
|
+
if (cur.opt === 1) {
|
|
770
|
+
this._accumulatedByPropertyName(cur.node, nodeOrPropertyName);
|
|
886
771
|
}
|
|
887
|
-
|
|
888
|
-
|
|
772
|
+
else {
|
|
773
|
+
switch (pattern) {
|
|
774
|
+
case 'in':
|
|
775
|
+
stack.push({ opt: 0, node: cur.node.right });
|
|
776
|
+
stack.push({ opt: 1, node: cur.node });
|
|
777
|
+
stack.push({ opt: 0, node: cur.node.left });
|
|
778
|
+
break;
|
|
779
|
+
case 'pre':
|
|
780
|
+
stack.push({ opt: 0, node: cur.node.right });
|
|
781
|
+
stack.push({ opt: 0, node: cur.node.left });
|
|
782
|
+
stack.push({ opt: 1, node: cur.node });
|
|
783
|
+
break;
|
|
784
|
+
case 'post':
|
|
785
|
+
stack.push({ opt: 1, node: cur.node });
|
|
786
|
+
stack.push({ opt: 0, node: cur.node.right });
|
|
787
|
+
stack.push({ opt: 0, node: cur.node.left });
|
|
788
|
+
break;
|
|
789
|
+
default:
|
|
790
|
+
stack.push({ opt: 0, node: cur.node.right });
|
|
791
|
+
stack.push({ opt: 1, node: cur.node });
|
|
792
|
+
stack.push({ opt: 0, node: cur.node.left });
|
|
793
|
+
break;
|
|
794
|
+
}
|
|
889
795
|
}
|
|
890
796
|
}
|
|
891
797
|
}
|
|
@@ -1090,13 +996,6 @@ export class BinaryTree {
|
|
|
1090
996
|
return;
|
|
1091
997
|
}
|
|
1092
998
|
}
|
|
1093
|
-
/**
|
|
1094
|
-
* The function sets the loop type for a protected variable.
|
|
1095
|
-
* @param {LoopType} value - The value parameter is of type LoopType.
|
|
1096
|
-
*/
|
|
1097
|
-
_setLoopType(value) {
|
|
1098
|
-
this._loopType = value;
|
|
1099
|
-
}
|
|
1100
999
|
/**
|
|
1101
1000
|
* The function sets the root property of an object to a given value, and if the value is not null, it also sets the
|
|
1102
1001
|
* parent property of the value to undefined.
|
|
@@ -78,28 +78,14 @@ export declare class BST<N extends BSTNode<N['val'], N> = BSTNode> extends Binar
|
|
|
78
78
|
*/
|
|
79
79
|
getNodes(nodeProperty: BinaryTreeNodeKey | N, propertyName?: BinaryTreeNodePropertyName, onlyOne?: boolean): N[];
|
|
80
80
|
/**
|
|
81
|
-
* The `
|
|
82
|
-
* less than a given node.
|
|
83
|
-
* @param {N | BinaryTreeNodeKey | null} beginNode - The `beginNode` parameter can be one of the following:
|
|
84
|
-
* @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
|
|
85
|
-
* specifies the property name to use for calculating the sum. If not provided, it defaults to `'key'`.
|
|
86
|
-
* @returns The function `lesserSum` returns a number, which represents the sum of the values of the nodes in the
|
|
87
|
-
* binary tree that have a lesser value than the specified `beginNode` based on the `propertyName`.
|
|
88
|
-
*/
|
|
89
|
-
lesserSum(beginNode: N | BinaryTreeNodeKey | null, propertyName?: BinaryTreeNodePropertyName): number;
|
|
90
|
-
/**
|
|
91
|
-
* The `allGreaterNodesAdd` function adds a delta value to the specified property of all nodes in a binary tree that
|
|
81
|
+
* The `lesserOrGreaterForeach` function adds a delta value to the specified property of all nodes in a binary tree that
|
|
92
82
|
* have a greater value than a given node.
|
|
93
|
-
* @param {N | BinaryTreeNodeKey | null} node - The `node` parameter can be either of type `N` (a generic type),
|
|
94
|
-
*
|
|
95
|
-
* @param
|
|
96
|
-
*
|
|
97
|
-
* @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
|
|
98
|
-
* specifies the property name of the nodes in the binary tree that you want to update. If not provided, it defaults to
|
|
99
|
-
* 'key'.
|
|
100
|
-
* @returns a boolean value.
|
|
83
|
+
* @param {N | BinaryTreeNodeKey | null} node - The `node` parameter can be either of type `N` (a generic type), `BinaryTreeNodeKey`, or `null`. It
|
|
84
|
+
* represents the node in the binary tree to which the delta value will be added.
|
|
85
|
+
* @param lesserOrGreater - The `lesserOrGreater` parameter is an optional parameter that specifies whether the delta
|
|
86
|
+
* @param callback - The `callback` parameter is a function that takes a node as a parameter and returns a boolean
|
|
101
87
|
*/
|
|
102
|
-
|
|
88
|
+
lesserOrGreaterForeach(node: N | BinaryTreeNodeKey | null, lesserOrGreater: CP | undefined, callback: (node: N) => void): boolean;
|
|
103
89
|
/**
|
|
104
90
|
* Balancing Adjustment:
|
|
105
91
|
* Perfectly Balanced Binary Tree: Since the balance of a perfectly balanced binary tree is already fixed, no additional balancing adjustment is needed. Any insertion or deletion operation will disrupt the perfect balance, often requiring a complete reconstruction of the tree.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CP, LoopType } from '../../types';
|
|
2
2
|
import { BinaryTree, BinaryTreeNode } from './binary-tree';
|
|
3
|
+
import { Queue } from '../queue';
|
|
3
4
|
export class BSTNode extends BinaryTreeNode {
|
|
4
5
|
constructor(key, val) {
|
|
5
6
|
super(key, val);
|
|
@@ -41,7 +42,7 @@ export class BST extends BinaryTree {
|
|
|
41
42
|
* @returns The function `add` returns the inserted node (`inserted`) which can be of type `N`, `null`, or `undefined`.
|
|
42
43
|
*/
|
|
43
44
|
add(keyOrNode, val) {
|
|
44
|
-
// TODO support node as a
|
|
45
|
+
// TODO support node as a parameter
|
|
45
46
|
let inserted = null;
|
|
46
47
|
let newNode = null;
|
|
47
48
|
if (keyOrNode instanceof BSTNode) {
|
|
@@ -125,7 +126,8 @@ export class BST extends BinaryTree {
|
|
|
125
126
|
* @param {boolean} isBalanceAdd - If true the nodes will be balance inserted in binary search method.
|
|
126
127
|
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
|
|
127
128
|
*/
|
|
128
|
-
addMany(keysOrNodes, data, isBalanceAdd =
|
|
129
|
+
addMany(keysOrNodes, data, isBalanceAdd = true) {
|
|
130
|
+
// TODO this addMany function is inefficient, it should be optimized
|
|
129
131
|
function hasNoNull(arr) {
|
|
130
132
|
return arr.indexOf(null) === -1;
|
|
131
133
|
}
|
|
@@ -256,8 +258,8 @@ export class BST extends BinaryTree {
|
|
|
256
258
|
_traverse(this.root);
|
|
257
259
|
}
|
|
258
260
|
else {
|
|
259
|
-
const queue = [this.root];
|
|
260
|
-
while (queue.
|
|
261
|
+
const queue = new Queue([this.root]);
|
|
262
|
+
while (queue.size > 0) {
|
|
261
263
|
const cur = queue.shift();
|
|
262
264
|
if (cur) {
|
|
263
265
|
if (this._pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne))
|
|
@@ -279,106 +281,14 @@ export class BST extends BinaryTree {
|
|
|
279
281
|
}
|
|
280
282
|
// --- start additional functions
|
|
281
283
|
/**
|
|
282
|
-
* The `
|
|
283
|
-
* less than a given node.
|
|
284
|
-
* @param {N | BinaryTreeNodeKey | null} beginNode - The `beginNode` parameter can be one of the following:
|
|
285
|
-
* @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
|
|
286
|
-
* specifies the property name to use for calculating the sum. If not provided, it defaults to `'key'`.
|
|
287
|
-
* @returns The function `lesserSum` returns a number, which represents the sum of the values of the nodes in the
|
|
288
|
-
* binary tree that have a lesser value than the specified `beginNode` based on the `propertyName`.
|
|
289
|
-
*/
|
|
290
|
-
lesserSum(beginNode, propertyName = 'key') {
|
|
291
|
-
if (typeof beginNode === 'number')
|
|
292
|
-
beginNode = this.get(beginNode, 'key');
|
|
293
|
-
if (!beginNode)
|
|
294
|
-
return 0;
|
|
295
|
-
if (!this.root)
|
|
296
|
-
return 0;
|
|
297
|
-
const key = beginNode.key;
|
|
298
|
-
const getSumByPropertyName = (cur) => {
|
|
299
|
-
let needSum;
|
|
300
|
-
switch (propertyName) {
|
|
301
|
-
case 'key':
|
|
302
|
-
needSum = cur.key;
|
|
303
|
-
break;
|
|
304
|
-
default:
|
|
305
|
-
needSum = cur.key;
|
|
306
|
-
break;
|
|
307
|
-
}
|
|
308
|
-
return needSum;
|
|
309
|
-
};
|
|
310
|
-
let sum = 0;
|
|
311
|
-
if (this.loopType === LoopType.RECURSIVE) {
|
|
312
|
-
const _traverse = (cur) => {
|
|
313
|
-
const compared = this._compare(cur.key, key);
|
|
314
|
-
if (compared === CP.eq) {
|
|
315
|
-
if (cur.right)
|
|
316
|
-
sum += this.subTreeSum(cur.right, propertyName);
|
|
317
|
-
return;
|
|
318
|
-
}
|
|
319
|
-
else if (compared === CP.lt) {
|
|
320
|
-
if (cur.left)
|
|
321
|
-
sum += this.subTreeSum(cur.left, propertyName);
|
|
322
|
-
sum += getSumByPropertyName(cur);
|
|
323
|
-
if (cur.right)
|
|
324
|
-
_traverse(cur.right);
|
|
325
|
-
else
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
else {
|
|
329
|
-
if (cur.left)
|
|
330
|
-
_traverse(cur.left);
|
|
331
|
-
else
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
};
|
|
335
|
-
_traverse(this.root);
|
|
336
|
-
}
|
|
337
|
-
else {
|
|
338
|
-
const queue = [this.root];
|
|
339
|
-
while (queue.length > 0) {
|
|
340
|
-
const cur = queue.shift();
|
|
341
|
-
if (cur) {
|
|
342
|
-
const compared = this._compare(cur.key, key);
|
|
343
|
-
if (compared === CP.eq) {
|
|
344
|
-
if (cur.right)
|
|
345
|
-
sum += this.subTreeSum(cur.right, propertyName);
|
|
346
|
-
return sum;
|
|
347
|
-
}
|
|
348
|
-
else if (compared === CP.lt) {
|
|
349
|
-
// todo maybe a bug
|
|
350
|
-
if (cur.left)
|
|
351
|
-
sum += this.subTreeSum(cur.left, propertyName);
|
|
352
|
-
sum += getSumByPropertyName(cur);
|
|
353
|
-
if (cur.right)
|
|
354
|
-
queue.push(cur.right);
|
|
355
|
-
else
|
|
356
|
-
return sum;
|
|
357
|
-
}
|
|
358
|
-
else {
|
|
359
|
-
if (cur.left)
|
|
360
|
-
queue.push(cur.left);
|
|
361
|
-
else
|
|
362
|
-
return sum;
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
return sum;
|
|
368
|
-
}
|
|
369
|
-
/**
|
|
370
|
-
* The `allGreaterNodesAdd` function adds a delta value to the specified property of all nodes in a binary tree that
|
|
284
|
+
* The `lesserOrGreaterForeach` function adds a delta value to the specified property of all nodes in a binary tree that
|
|
371
285
|
* have a greater value than a given node.
|
|
372
|
-
* @param {N | BinaryTreeNodeKey | null} node - The `node` parameter can be either of type `N` (a generic type),
|
|
373
|
-
*
|
|
374
|
-
* @param
|
|
375
|
-
*
|
|
376
|
-
* @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
|
|
377
|
-
* specifies the property name of the nodes in the binary tree that you want to update. If not provided, it defaults to
|
|
378
|
-
* 'key'.
|
|
379
|
-
* @returns a boolean value.
|
|
286
|
+
* @param {N | BinaryTreeNodeKey | null} node - The `node` parameter can be either of type `N` (a generic type), `BinaryTreeNodeKey`, or `null`. It
|
|
287
|
+
* represents the node in the binary tree to which the delta value will be added.
|
|
288
|
+
* @param lesserOrGreater - The `lesserOrGreater` parameter is an optional parameter that specifies whether the delta
|
|
289
|
+
* @param callback - The `callback` parameter is a function that takes a node as a parameter and returns a boolean
|
|
380
290
|
*/
|
|
381
|
-
|
|
291
|
+
lesserOrGreaterForeach(node, lesserOrGreater = CP.lt, callback) {
|
|
382
292
|
if (typeof node === 'number')
|
|
383
293
|
node = this.get(node, 'key');
|
|
384
294
|
if (!node)
|
|
@@ -386,42 +296,32 @@ export class BST extends BinaryTree {
|
|
|
386
296
|
const key = node.key;
|
|
387
297
|
if (!this.root)
|
|
388
298
|
return false;
|
|
389
|
-
const _sumByPropertyName = (cur) => {
|
|
390
|
-
switch (propertyName) {
|
|
391
|
-
case 'key':
|
|
392
|
-
cur.key += delta;
|
|
393
|
-
break;
|
|
394
|
-
default:
|
|
395
|
-
cur.key += delta;
|
|
396
|
-
break;
|
|
397
|
-
}
|
|
398
|
-
};
|
|
399
299
|
if (this.loopType === LoopType.RECURSIVE) {
|
|
400
300
|
const _traverse = (cur) => {
|
|
401
301
|
const compared = this._compare(cur.key, key);
|
|
402
|
-
if (compared ===
|
|
403
|
-
|
|
302
|
+
if (compared === lesserOrGreater)
|
|
303
|
+
callback(cur);
|
|
404
304
|
if (!cur.left && !cur.right)
|
|
405
305
|
return;
|
|
406
|
-
if (cur.left && this._compare(cur.left.key, key) ===
|
|
306
|
+
if (cur.left && this._compare(cur.left.key, key) === lesserOrGreater)
|
|
407
307
|
_traverse(cur.left);
|
|
408
|
-
if (cur.right && this._compare(cur.right.key, key) ===
|
|
308
|
+
if (cur.right && this._compare(cur.right.key, key) === lesserOrGreater)
|
|
409
309
|
_traverse(cur.right);
|
|
410
310
|
};
|
|
411
311
|
_traverse(this.root);
|
|
412
312
|
return true;
|
|
413
313
|
}
|
|
414
314
|
else {
|
|
415
|
-
const queue = [this.root];
|
|
416
|
-
while (queue.
|
|
315
|
+
const queue = new Queue([this.root]);
|
|
316
|
+
while (queue.size > 0) {
|
|
417
317
|
const cur = queue.shift();
|
|
418
318
|
if (cur) {
|
|
419
319
|
const compared = this._compare(cur.key, key);
|
|
420
|
-
if (compared ===
|
|
421
|
-
|
|
422
|
-
if (cur.left && this._compare(cur.left.key, key) ===
|
|
320
|
+
if (compared === lesserOrGreater)
|
|
321
|
+
callback(cur);
|
|
322
|
+
if (cur.left && this._compare(cur.left.key, key) === lesserOrGreater)
|
|
423
323
|
queue.push(cur.left);
|
|
424
|
-
if (cur.right && this._compare(cur.right.key, key) ===
|
|
324
|
+
if (cur.right && this._compare(cur.right.key, key) === lesserOrGreater)
|
|
425
325
|
queue.push(cur.right);
|
|
426
326
|
}
|
|
427
327
|
}
|