data-structure-typed 1.50.8 → 1.50.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/README.md +73 -75
- package/benchmark/report.html +2 -2
- package/benchmark/report.json +15 -15
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +15 -3
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js +14 -2
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +2 -2
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +11 -11
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/bst.d.ts +19 -2
- package/dist/cjs/data-structures/binary-tree/bst.js +20 -2
- package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +5 -5
- package/dist/cjs/data-structures/binary-tree/rb-tree.js +42 -44
- package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +40 -22
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +43 -27
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
- package/dist/cjs/data-structures/heap/heap.d.ts +1 -1
- package/dist/cjs/data-structures/heap/heap.js +5 -5
- package/dist/cjs/types/common.d.ts +1 -1
- package/dist/cjs/types/data-structures/binary-tree/rb-tree.d.ts +1 -4
- package/dist/cjs/types/data-structures/binary-tree/rb-tree.js +0 -6
- package/dist/cjs/types/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +15 -3
- package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.js +14 -2
- package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +2 -2
- package/dist/mjs/data-structures/binary-tree/binary-tree.js +11 -11
- package/dist/mjs/data-structures/binary-tree/bst.d.ts +19 -2
- package/dist/mjs/data-structures/binary-tree/bst.js +20 -2
- package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +5 -5
- package/dist/mjs/data-structures/binary-tree/rb-tree.js +42 -44
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.d.ts +40 -22
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.js +43 -27
- package/dist/mjs/data-structures/heap/heap.d.ts +1 -1
- package/dist/mjs/data-structures/heap/heap.js +5 -5
- package/dist/mjs/types/common.d.ts +1 -1
- package/dist/mjs/types/data-structures/binary-tree/rb-tree.d.ts +1 -4
- package/dist/mjs/types/data-structures/binary-tree/rb-tree.js +1 -5
- package/dist/umd/data-structure-typed.js +135 -97
- package/dist/umd/data-structure-typed.min.js +2 -2
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +1 -1
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +17 -3
- package/src/data-structures/binary-tree/binary-tree.ts +36 -24
- package/src/data-structures/binary-tree/bst.ts +32 -11
- package/src/data-structures/binary-tree/rb-tree.ts +44 -44
- package/src/data-structures/binary-tree/tree-multi-map.ts +46 -27
- package/src/data-structures/heap/heap.ts +5 -5
- package/src/types/common.ts +1 -1
- package/src/types/data-structures/binary-tree/rb-tree.ts +1 -1
- package/test/integration/all-in-one.test.ts +2 -2
- package/test/performance/data-structures/binary-tree/avl-tree.test.ts +20 -15
- package/test/performance/data-structures/binary-tree/binary-tree.test.ts +1 -1
- package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +7 -7
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +4 -4
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +24 -24
- package/test/unit/data-structures/binary-tree/bst.test.ts +12 -12
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +25 -25
- package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +19 -19
- package/test/unit/data-structures/priority-queue/priority-queue.test.ts +3 -3
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
BinaryTreeDeleteResult,
|
|
10
10
|
BSTNKeyOrNode,
|
|
11
11
|
BTNCallback,
|
|
12
|
+
IterationType,
|
|
12
13
|
KeyOrNodeOrEntry,
|
|
13
14
|
TreeMultiMapNested,
|
|
14
15
|
TreeMultiMapNodeNested,
|
|
@@ -24,17 +25,19 @@ export class TreeMultiMapNode<
|
|
|
24
25
|
NODE extends TreeMultiMapNode<K, V, NODE> = TreeMultiMapNodeNested<K, V>
|
|
25
26
|
> extends RedBlackTreeNode<K, V, NODE> {
|
|
26
27
|
/**
|
|
27
|
-
* The constructor function initializes
|
|
28
|
-
* @param {K} key - The key parameter
|
|
29
|
-
*
|
|
30
|
-
* @param {V} [value] - The `value` parameter is an optional parameter
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* 1.
|
|
28
|
+
* The constructor function initializes a Red-Black Tree node with a key, value, count, and color.
|
|
29
|
+
* @param {K} key - The key parameter represents the key of the node in the Red-Black Tree. It is
|
|
30
|
+
* used to identify and locate the node within the tree.
|
|
31
|
+
* @param {V} [value] - The `value` parameter is an optional parameter that represents the value
|
|
32
|
+
* associated with the key in the Red-Black Tree node. It is not required and can be omitted when
|
|
33
|
+
* creating a new node.
|
|
34
|
+
* @param [count=1] - The `count` parameter represents the number of occurrences of a particular key
|
|
35
|
+
* in the Red-Black Tree. It is an optional parameter with a default value of 1.
|
|
36
|
+
* @param {RBTNColor} [color=BLACK] - The `color` parameter is used to specify the color of the node
|
|
37
|
+
* in a Red-Black Tree. It is optional and has a default value of `'BLACK'`.
|
|
35
38
|
*/
|
|
36
|
-
constructor(key: K, value?: V, count = 1) {
|
|
37
|
-
super(key, value);
|
|
39
|
+
constructor(key: K, value?: V, count = 1, color: RBTNColor = 'BLACK') {
|
|
40
|
+
super(key, value, color);
|
|
38
41
|
this.count = count;
|
|
39
42
|
}
|
|
40
43
|
|
|
@@ -91,25 +94,41 @@ export class TreeMultiMap<
|
|
|
91
94
|
return this._count;
|
|
92
95
|
}
|
|
93
96
|
|
|
94
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Time Complexity: O(n)
|
|
99
|
+
* Space Complexity: O(1)
|
|
100
|
+
*/
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Time Complexity: O(n)
|
|
104
|
+
* Space Complexity: O(1)
|
|
105
|
+
*
|
|
106
|
+
* The function calculates the sum of the count property of all nodes in a tree using depth-first
|
|
107
|
+
* search.
|
|
108
|
+
* @returns the sum of the count property of all nodes in the tree.
|
|
109
|
+
*/
|
|
110
|
+
getComputedCount(): number {
|
|
95
111
|
let sum = 0;
|
|
96
112
|
this.dfs(node => (sum += node.count));
|
|
97
113
|
return sum;
|
|
98
114
|
}
|
|
99
115
|
|
|
100
116
|
/**
|
|
101
|
-
* The function creates a new TreeMultiMapNode
|
|
117
|
+
* The function creates a new TreeMultiMapNode with the specified key, value, color, and count.
|
|
102
118
|
* @param {K} key - The key parameter represents the key of the node being created. It is of type K,
|
|
103
|
-
* which is a generic type
|
|
104
|
-
* @param {V} [value] - The `value` parameter
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
* default
|
|
109
|
-
* @
|
|
119
|
+
* which is a generic type representing the key type of the node.
|
|
120
|
+
* @param {V} [value] - The `value` parameter represents the value associated with the key in the
|
|
121
|
+
* node. It is an optional parameter, which means it can be omitted when calling the `createNode`
|
|
122
|
+
* function. If provided, it should be of type `V`.
|
|
123
|
+
* @param {RBTNColor} [color=BLACK] - The color parameter is used to specify the color of the node in
|
|
124
|
+
* a Red-Black Tree. It can have two possible values: 'RED' or 'BLACK'. The default value is 'BLACK'.
|
|
125
|
+
* @param {number} [count] - The `count` parameter represents the number of occurrences of a key in
|
|
126
|
+
* the tree. It is an optional parameter and is used to keep track of the number of values associated
|
|
127
|
+
* with a key in the tree.
|
|
128
|
+
* @returns A new instance of the TreeMultiMapNode class is being returned.
|
|
110
129
|
*/
|
|
111
|
-
override createNode(key: K, value?: V, count?: number): NODE {
|
|
112
|
-
return new TreeMultiMapNode(key, value, count) as NODE;
|
|
130
|
+
override createNode(key: K, value?: V, color: RBTNColor = 'BLACK', count?: number): NODE {
|
|
131
|
+
return new TreeMultiMapNode(key, value, count, color) as NODE;
|
|
113
132
|
}
|
|
114
133
|
|
|
115
134
|
/**
|
|
@@ -153,10 +172,10 @@ export class TreeMultiMap<
|
|
|
153
172
|
if (key === undefined || key === null) {
|
|
154
173
|
return;
|
|
155
174
|
} else {
|
|
156
|
-
node = this.createNode(key, value, count);
|
|
175
|
+
node = this.createNode(key, value, 'BLACK', count);
|
|
157
176
|
}
|
|
158
177
|
} else if (!this.isNode(keyOrNodeOrEntry)) {
|
|
159
|
-
node = this.createNode(keyOrNodeOrEntry, value, count);
|
|
178
|
+
node = this.createNode(keyOrNodeOrEntry, value, 'BLACK', count);
|
|
160
179
|
} else {
|
|
161
180
|
return;
|
|
162
181
|
}
|
|
@@ -314,7 +333,7 @@ export class TreeMultiMap<
|
|
|
314
333
|
this._size--;
|
|
315
334
|
|
|
316
335
|
// If the original color was black, fix the tree
|
|
317
|
-
if (originalColor ===
|
|
336
|
+
if (originalColor === 'BLACK') {
|
|
318
337
|
this._deleteFixup(replacementNode);
|
|
319
338
|
}
|
|
320
339
|
|
|
@@ -356,8 +375,8 @@ export class TreeMultiMap<
|
|
|
356
375
|
* values:
|
|
357
376
|
* @returns a boolean value.
|
|
358
377
|
*/
|
|
359
|
-
override perfectlyBalance(iterationType = this.iterationType): boolean {
|
|
360
|
-
const sorted = this.dfs(node => node, '
|
|
378
|
+
override perfectlyBalance(iterationType: IterationType = this.iterationType): boolean {
|
|
379
|
+
const sorted = this.dfs(node => node, 'IN'),
|
|
361
380
|
n = sorted.length;
|
|
362
381
|
if (sorted.length < 1) return false;
|
|
363
382
|
|
|
@@ -431,7 +450,7 @@ export class TreeMultiMap<
|
|
|
431
450
|
destNode = this.ensureNode(destNode);
|
|
432
451
|
if (srcNode && destNode) {
|
|
433
452
|
const { key, value, count, color } = destNode;
|
|
434
|
-
const tempNode = this.createNode(key, value, count);
|
|
453
|
+
const tempNode = this.createNode(key, value, color, count);
|
|
435
454
|
if (tempNode) {
|
|
436
455
|
tempNode.color = color;
|
|
437
456
|
|
|
@@ -247,10 +247,10 @@ export class Heap<E = any> extends IterableElementBase<E> {
|
|
|
247
247
|
* Space Complexity: O(log n)
|
|
248
248
|
*
|
|
249
249
|
* Depth-first search (DFS) method, different traversal orders can be selected。
|
|
250
|
-
* @param order - Traverse order parameter: '
|
|
250
|
+
* @param order - Traverse order parameter: 'IN' (in-order), 'PRE' (pre-order) or 'POST' (post-order).
|
|
251
251
|
* @returns An array containing elements traversed in the specified order.
|
|
252
252
|
*/
|
|
253
|
-
dfs(order: DFSOrderPattern = '
|
|
253
|
+
dfs(order: DFSOrderPattern = 'PRE'): E[] {
|
|
254
254
|
const result: E[] = [];
|
|
255
255
|
|
|
256
256
|
// Auxiliary recursive function, traverses the binary heap according to the traversal order
|
|
@@ -258,15 +258,15 @@ export class Heap<E = any> extends IterableElementBase<E> {
|
|
|
258
258
|
const left = 2 * index + 1,
|
|
259
259
|
right = left + 1;
|
|
260
260
|
if (index < this.size) {
|
|
261
|
-
if (order === '
|
|
261
|
+
if (order === 'IN') {
|
|
262
262
|
_dfs(left);
|
|
263
263
|
result.push(this.elements[index]);
|
|
264
264
|
_dfs(right);
|
|
265
|
-
} else if (order === '
|
|
265
|
+
} else if (order === 'PRE') {
|
|
266
266
|
result.push(this.elements[index]);
|
|
267
267
|
_dfs(left);
|
|
268
268
|
_dfs(right);
|
|
269
|
-
} else if (order === '
|
|
269
|
+
} else if (order === 'POST') {
|
|
270
270
|
_dfs(left);
|
|
271
271
|
_dfs(right);
|
|
272
272
|
result.push(this.elements[index]);
|
package/src/types/common.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type FamilyPosition = 'ROOT' | 'LEFT' | 'RIGHT' | 'ROOT_LEFT' | 'ROOT_RIG
|
|
|
13
13
|
|
|
14
14
|
export type Comparator<K> = (a: K, b: K) => number;
|
|
15
15
|
|
|
16
|
-
export type DFSOrderPattern = '
|
|
16
|
+
export type DFSOrderPattern = 'PRE' | 'IN' | 'POST';
|
|
17
17
|
|
|
18
18
|
export type NodeDisplayLayout = [string[], number, number, number];
|
|
19
19
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RedBlackTree, RedBlackTreeNode } from '../../../data-structures';
|
|
2
2
|
import type { BSTOptions } from "./bst";
|
|
3
3
|
|
|
4
|
-
export
|
|
4
|
+
export type RBTNColor = 'RED' | 'BLACK';
|
|
5
5
|
|
|
6
6
|
export type RedBlackTreeNodeNested<K, V> = RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
7
7
|
|
|
@@ -23,7 +23,7 @@ describe('AVL Tree Test from data-structure-typed', () => {
|
|
|
23
23
|
expect(getMinNodeBySpecificNode?.key).toBe(12);
|
|
24
24
|
|
|
25
25
|
let subTreeSum = 0;
|
|
26
|
-
node15 && tree.dfs(node => (subTreeSum += node.key), '
|
|
26
|
+
node15 && tree.dfs(node => (subTreeSum += node.key), 'PRE', 15);
|
|
27
27
|
expect(subTreeSum).toBe(70);
|
|
28
28
|
|
|
29
29
|
let lesserSum = 0;
|
|
@@ -33,7 +33,7 @@ describe('AVL Tree Test from data-structure-typed', () => {
|
|
|
33
33
|
// node15 has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class.
|
|
34
34
|
expect(node15?.value).toBe(15);
|
|
35
35
|
|
|
36
|
-
const dfs = tree.dfs(node => node, '
|
|
36
|
+
const dfs = tree.dfs(node => node, 'IN');
|
|
37
37
|
expect(dfs[0].key).toBe(1);
|
|
38
38
|
expect(dfs[dfs.length - 1].key).toBe(16);
|
|
39
39
|
|
|
@@ -3,26 +3,31 @@ import * as Benchmark from 'benchmark';
|
|
|
3
3
|
import { getRandomIntArray, magnitude } from '../../../utils';
|
|
4
4
|
|
|
5
5
|
const suite = new Benchmark.Suite();
|
|
6
|
-
const
|
|
7
|
-
const {
|
|
8
|
-
const
|
|
6
|
+
const avlTree = new AVLTree<number>();
|
|
7
|
+
const { HUNDRED_THOUSAND } = magnitude;
|
|
8
|
+
const randomArray = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND - 1, true);
|
|
9
9
|
|
|
10
10
|
suite
|
|
11
|
-
.add(`${
|
|
12
|
-
|
|
13
|
-
for (let i = 0; i <
|
|
11
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add`, () => {
|
|
12
|
+
avlTree.clear();
|
|
13
|
+
for (let i = 0; i < randomArray.length; i++) avlTree.add(i);
|
|
14
14
|
})
|
|
15
|
-
.add(`${
|
|
16
|
-
for (let i = 0; i <
|
|
15
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} get`, () => {
|
|
16
|
+
for (let i = 0; i < randomArray.length; i++) avlTree.get(randomArray[i]);
|
|
17
17
|
})
|
|
18
|
-
.add(`${
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
for (let i = 0; i < arr.length; i++) avl.delete(arr[i]);
|
|
18
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} iterator`, () => {
|
|
19
|
+
const entries = [...avlTree];
|
|
20
|
+
return entries.length === HUNDRED_THOUSAND;
|
|
22
21
|
})
|
|
23
|
-
.add(`${
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & delete orderly`, () => {
|
|
23
|
+
avlTree.clear();
|
|
24
|
+
for (let i = 0; i < randomArray.length; i++) avlTree.add(i);
|
|
25
|
+
for (let i = 0; i < randomArray.length; i++) avlTree.delete(i);
|
|
26
|
+
})
|
|
27
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & delete randomly`, () => {
|
|
28
|
+
avlTree.clear();
|
|
29
|
+
for (let i = 0; i < randomArray.length; i++) avlTree.add(randomArray[i]);
|
|
30
|
+
for (let i = 0; i < randomArray.length; i++) avlTree.delete(randomArray[i]);
|
|
26
31
|
});
|
|
27
32
|
|
|
28
33
|
export { suite };
|
|
@@ -34,7 +34,7 @@ suite
|
|
|
34
34
|
for (let i = 0; i < THOUSAND; i++) biTree.bfs();
|
|
35
35
|
})
|
|
36
36
|
.add(`${THOUSAND.toLocaleString()} morris`, () => {
|
|
37
|
-
for (let i = 0; i < THOUSAND; i++) biTree.morris(n => n, '
|
|
37
|
+
for (let i = 0; i < THOUSAND; i++) biTree.morris(n => n, 'PRE');
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
// export { suite };
|
|
@@ -31,7 +31,7 @@ describe('AVLTreeMultiMap count', () => {
|
|
|
31
31
|
tm.lesserOrGreaterTraverse(node => (node.count += 2), 'GT', 1);
|
|
32
32
|
tm.delete(2);
|
|
33
33
|
expect(tm.count).toBe(12);
|
|
34
|
-
expect(tm.
|
|
34
|
+
expect(tm.getComputedCount()).toBe(16);
|
|
35
35
|
});
|
|
36
36
|
});
|
|
37
37
|
|
|
@@ -91,7 +91,7 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|
|
91
91
|
expect(minNodeBySpecificNode?.key).toBe(15);
|
|
92
92
|
|
|
93
93
|
let subTreeSum = 0;
|
|
94
|
-
node15 && treeMultimap.dfs(node => (subTreeSum += node.key), '
|
|
94
|
+
node15 && treeMultimap.dfs(node => (subTreeSum += node.key), 'PRE', 15);
|
|
95
95
|
expect(subTreeSum).toBe(31);
|
|
96
96
|
let lesserSum = 0;
|
|
97
97
|
treeMultimap.lesserOrGreaterTraverse((node: AVLTreeMultiMapNode<number>) => (lesserSum += node.key), 'LT', 10);
|
|
@@ -99,7 +99,7 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|
|
99
99
|
|
|
100
100
|
expect(node15 instanceof AVLTreeMultiMapNode);
|
|
101
101
|
if (node15 instanceof AVLTreeMultiMapNode) {
|
|
102
|
-
const subTreeAdd = treeMultimap.dfs(node => (node.count += 1), '
|
|
102
|
+
const subTreeAdd = treeMultimap.dfs(node => (node.count += 1), 'PRE', 15);
|
|
103
103
|
expect(subTreeAdd);
|
|
104
104
|
}
|
|
105
105
|
const node11 = treeMultimap.getNode(11);
|
|
@@ -109,7 +109,7 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|
|
109
109
|
expect(allGreaterNodesAdded);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
const dfsInorderNodes = treeMultimap.dfs(node => node, '
|
|
112
|
+
const dfsInorderNodes = treeMultimap.dfs(node => node, 'IN');
|
|
113
113
|
expect(dfsInorderNodes[0].key).toBe(1);
|
|
114
114
|
expect(dfsInorderNodes[dfsInorderNodes.length - 1].key).toBe(16);
|
|
115
115
|
expect(treeMultimap.isPerfectlyBalanced()).toBe(false);
|
|
@@ -345,7 +345,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|
|
345
345
|
expect(minNodeBySpecificNode?.key).toBe(15);
|
|
346
346
|
|
|
347
347
|
let subTreeSum = 0;
|
|
348
|
-
node15 && treeMultimap.dfs(node => (subTreeSum += node.key), '
|
|
348
|
+
node15 && treeMultimap.dfs(node => (subTreeSum += node.key), 'PRE', 15);
|
|
349
349
|
expect(subTreeSum).toBe(31);
|
|
350
350
|
let lesserSum = 0;
|
|
351
351
|
treeMultimap.lesserOrGreaterTraverse((node: AVLTreeMultiMapNode<number>) => (lesserSum += node.key), 'LT', 10);
|
|
@@ -353,7 +353,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|
|
353
353
|
|
|
354
354
|
expect(node15 instanceof AVLTreeMultiMapNode);
|
|
355
355
|
if (node15 instanceof AVLTreeMultiMapNode) {
|
|
356
|
-
const subTreeAdd = treeMultimap.dfs(node => (node.count += 1), '
|
|
356
|
+
const subTreeAdd = treeMultimap.dfs(node => (node.count += 1), 'PRE', 15);
|
|
357
357
|
expect(subTreeAdd);
|
|
358
358
|
}
|
|
359
359
|
const node11 = treeMultimap.getNode(11);
|
|
@@ -363,7 +363,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|
|
363
363
|
expect(allGreaterNodesAdded);
|
|
364
364
|
}
|
|
365
365
|
|
|
366
|
-
const dfsInorderNodes = treeMultimap.dfs(node => node, '
|
|
366
|
+
const dfsInorderNodes = treeMultimap.dfs(node => node, 'IN');
|
|
367
367
|
expect(dfsInorderNodes[0].key).toBe(1);
|
|
368
368
|
expect(dfsInorderNodes[dfsInorderNodes.length - 1].key).toBe(16);
|
|
369
369
|
expect(treeMultimap.isPerfectlyBalanced()).toBe(true);
|
|
@@ -24,7 +24,7 @@ describe('AVL Tree Test', () => {
|
|
|
24
24
|
expect(getMinNodeBySpecificNode?.key).toBe(12);
|
|
25
25
|
|
|
26
26
|
let subTreeSum = 0;
|
|
27
|
-
node15 && tree.dfs(node => (subTreeSum += node.key), '
|
|
27
|
+
node15 && tree.dfs(node => (subTreeSum += node.key), 'PRE', node15);
|
|
28
28
|
expect(subTreeSum).toBe(70);
|
|
29
29
|
|
|
30
30
|
let lesserSum = 0;
|
|
@@ -34,7 +34,7 @@ describe('AVL Tree Test', () => {
|
|
|
34
34
|
// node15 has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class.
|
|
35
35
|
expect(node15?.value).toBe(15);
|
|
36
36
|
|
|
37
|
-
const dfs = tree.dfs(node => node, '
|
|
37
|
+
const dfs = tree.dfs(node => node, 'IN');
|
|
38
38
|
expect(dfs[0].key).toBe(1);
|
|
39
39
|
expect(dfs[dfs.length - 1].key).toBe(16);
|
|
40
40
|
tree.perfectlyBalance();
|
|
@@ -132,7 +132,7 @@ describe('AVL Tree Test recursively', () => {
|
|
|
132
132
|
expect(getMinNodeBySpecificNode?.key).toBe(12);
|
|
133
133
|
|
|
134
134
|
let subTreeSum = 0;
|
|
135
|
-
node15 && tree.dfs(node => (subTreeSum += node.key), '
|
|
135
|
+
node15 && tree.dfs(node => (subTreeSum += node.key), 'PRE', node15);
|
|
136
136
|
expect(subTreeSum).toBe(70);
|
|
137
137
|
|
|
138
138
|
let lesserSum = 0;
|
|
@@ -142,7 +142,7 @@ describe('AVL Tree Test recursively', () => {
|
|
|
142
142
|
// node15 has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class.
|
|
143
143
|
expect(node15?.value).toBe(15);
|
|
144
144
|
|
|
145
|
-
const dfs = tree.dfs(node => node, '
|
|
145
|
+
const dfs = tree.dfs(node => node, 'IN');
|
|
146
146
|
expect(dfs[0].key).toBe(1);
|
|
147
147
|
expect(dfs[dfs.length - 1].key).toBe(16);
|
|
148
148
|
|
|
@@ -171,20 +171,20 @@ describe('BinaryTree', () => {
|
|
|
171
171
|
expect(cloned.root?.right?.key).toBe(6);
|
|
172
172
|
expect(cloned.root?.right?.left?.key).toBe(3);
|
|
173
173
|
expect(cloned.root?.right?.right).toBe(null);
|
|
174
|
-
expect(cloned.dfs(node => node.key, '
|
|
175
|
-
expect(cloned.dfs(node => (node ? node.key : null), '
|
|
174
|
+
expect(cloned.dfs(node => node.key, 'PRE', cloned.getNode(6), 'ITERATIVE')).toEqual([6, 3, 7]);
|
|
175
|
+
expect(cloned.dfs(node => (node ? node.key : null), 'PRE', cloned.getNode(6), 'ITERATIVE', true)).toEqual([
|
|
176
176
|
6,
|
|
177
177
|
3,
|
|
178
178
|
7,
|
|
179
179
|
null
|
|
180
180
|
]);
|
|
181
|
-
expect(cloned.dfs(node => (node ? node.key : node), '
|
|
181
|
+
expect(cloned.dfs(node => (node ? node.key : node), 'PRE', cloned.getNode(6), 'ITERATIVE', true)).toEqual([
|
|
182
182
|
6,
|
|
183
183
|
3,
|
|
184
184
|
7,
|
|
185
185
|
null
|
|
186
186
|
]);
|
|
187
|
-
expect(cloned.dfs(node => (node ? node.key : null), '
|
|
187
|
+
expect(cloned.dfs(node => (node ? node.key : null), 'PRE', cloned.getNode(6), 'RECURSIVE', true)).toEqual([
|
|
188
188
|
6,
|
|
189
189
|
3,
|
|
190
190
|
7,
|
|
@@ -294,22 +294,22 @@ describe('BinaryTree', () => {
|
|
|
294
294
|
|
|
295
295
|
it('should sub tree traverse', () => {
|
|
296
296
|
tree.addMany([4, 2, 6, null, 1, 3, null, 5, null, 7]);
|
|
297
|
-
expect(tree.dfs(node => node.key, '
|
|
298
|
-
expect(tree.dfs(node => node.key, '
|
|
299
|
-
expect(tree.dfs(node => node.key, '
|
|
300
|
-
expect(tree.dfs(node => (node ? node.key : null), '
|
|
297
|
+
expect(tree.dfs(node => node.key, 'PRE', tree.getNode(6), 'ITERATIVE')).toEqual([6, 3, 7]);
|
|
298
|
+
expect(tree.dfs(node => node.key, 'PRE', tree.getNode(6), 'ITERATIVE', false)).toEqual([6, 3, 7]);
|
|
299
|
+
expect(tree.dfs(node => node.key, 'PRE', tree.getNode(6), 'RECURSIVE')).toEqual([6, 3, 7]);
|
|
300
|
+
expect(tree.dfs(node => (node ? node.key : null), 'PRE', tree.getNode(6), 'ITERATIVE', true)).toEqual([
|
|
301
301
|
6,
|
|
302
302
|
3,
|
|
303
303
|
7,
|
|
304
304
|
null
|
|
305
305
|
]);
|
|
306
|
-
expect(tree.dfs(node => (node ? node.key : node), '
|
|
306
|
+
expect(tree.dfs(node => (node ? node.key : node), 'PRE', tree.getNode(6), 'ITERATIVE', true)).toEqual([
|
|
307
307
|
6,
|
|
308
308
|
3,
|
|
309
309
|
7,
|
|
310
310
|
null
|
|
311
311
|
]);
|
|
312
|
-
expect(tree.dfs(node => (node ? node.key : null), '
|
|
312
|
+
expect(tree.dfs(node => (node ? node.key : null), 'PRE', tree.getNode(6), 'RECURSIVE', true)).toEqual([
|
|
313
313
|
6,
|
|
314
314
|
3,
|
|
315
315
|
7,
|
|
@@ -362,36 +362,36 @@ describe('BinaryTree Morris Traversal', () => {
|
|
|
362
362
|
tree.add(5);
|
|
363
363
|
it('should perform in-order Morris traversal correctly as dfs traversal', () => {
|
|
364
364
|
// Perform in-order Morris traversal
|
|
365
|
-
const result = tree.morris(node => node.key, '
|
|
365
|
+
const result = tree.morris(node => node.key, 'IN');
|
|
366
366
|
|
|
367
367
|
// Expected in-order traversal result
|
|
368
368
|
const expected = [4, 2, 5, 1, 3];
|
|
369
369
|
|
|
370
370
|
expect(result).toEqual(expected);
|
|
371
|
-
expect(tree.dfs(node => node.key, '
|
|
372
|
-
expect(tree.dfs(node => node.key, '
|
|
371
|
+
expect(tree.dfs(node => node.key, 'IN')).toEqual(expected);
|
|
372
|
+
expect(tree.dfs(node => node.key, 'IN', tree.root, 'RECURSIVE')).toEqual(expected);
|
|
373
373
|
});
|
|
374
374
|
|
|
375
375
|
it('should perform pre-order Morris traversal correctly as dfs traversal', () => {
|
|
376
376
|
// Perform pre-order Morris traversal
|
|
377
|
-
const result = tree.morris(node => node.key, '
|
|
377
|
+
const result = tree.morris(node => node.key, 'PRE');
|
|
378
378
|
|
|
379
379
|
// Expected pre-order traversal result
|
|
380
380
|
const expected = [1, 2, 4, 5, 3];
|
|
381
381
|
|
|
382
382
|
expect(result).toEqual(expected);
|
|
383
|
-
expect(tree.dfs(node => node.key, '
|
|
383
|
+
expect(tree.dfs(node => node.key, 'PRE')).toEqual(expected);
|
|
384
384
|
});
|
|
385
385
|
|
|
386
386
|
it('should perform post-order Morris traversal correctly as dfs traversal', () => {
|
|
387
387
|
// Perform post-order Morris traversal
|
|
388
|
-
const result = tree.morris(node => node.key, '
|
|
388
|
+
const result = tree.morris(node => node.key, 'POST');
|
|
389
389
|
|
|
390
390
|
// Expected post-order traversal result
|
|
391
391
|
const expected = [4, 5, 2, 3, 1];
|
|
392
392
|
|
|
393
393
|
expect(result).toEqual([4, 5, 2, 3, 1]);
|
|
394
|
-
expect(tree.dfs(node => node.key, '
|
|
394
|
+
expect(tree.dfs(node => node.key, 'POST')).toEqual(expected);
|
|
395
395
|
});
|
|
396
396
|
|
|
397
397
|
it('after morris traversals should the structure of the tree be correct', () => {
|
|
@@ -445,11 +445,11 @@ describe('BinaryTree traversals', () => {
|
|
|
445
445
|
35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55
|
|
446
446
|
]);
|
|
447
447
|
|
|
448
|
-
expect(tree.dfs(node => node.key, '
|
|
449
|
-
expect(tree.dfs(node => node.key, '
|
|
448
|
+
expect(tree.dfs(node => node.key, 'PRE')).toEqual([35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55]);
|
|
449
|
+
expect(tree.dfs(node => node.key, 'PRE', tree.root, 'RECURSIVE')).toEqual([
|
|
450
450
|
35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55
|
|
451
451
|
]);
|
|
452
|
-
expect(tree.dfs(node => node, '
|
|
452
|
+
expect(tree.dfs(node => node, 'PRE', tree.root, 'ITERATIVE', true).map(node => (node ? node.key : null))).toEqual([
|
|
453
453
|
35,
|
|
454
454
|
20,
|
|
455
455
|
15,
|
|
@@ -464,7 +464,7 @@ describe('BinaryTree traversals', () => {
|
|
|
464
464
|
45,
|
|
465
465
|
55
|
|
466
466
|
]);
|
|
467
|
-
expect(tree.dfs(node => node, '
|
|
467
|
+
expect(tree.dfs(node => node, 'PRE', tree.root, 'RECURSIVE', true).map(node => (node ? node.key : null))).toEqual([
|
|
468
468
|
35,
|
|
469
469
|
20,
|
|
470
470
|
15,
|
|
@@ -480,9 +480,9 @@ describe('BinaryTree traversals', () => {
|
|
|
480
480
|
55
|
|
481
481
|
]);
|
|
482
482
|
|
|
483
|
-
expect(tree.dfs(node => node.key, '
|
|
484
|
-
expect(tree.dfs(node => node.key, '
|
|
485
|
-
expect(tree.dfs(node => node.key, '
|
|
483
|
+
expect(tree.dfs(node => node.key, 'IN')).toEqual([15, 16, 20, 28, 29, 30, 35, 40, 45, 50, 55]);
|
|
484
|
+
expect(tree.dfs(node => node.key, 'POST')).toEqual([16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35]);
|
|
485
|
+
expect(tree.dfs(node => node.key, 'POST', tree.root, 'RECURSIVE')).toEqual([
|
|
486
486
|
16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35
|
|
487
487
|
]);
|
|
488
488
|
expect(tree.bfs(node => node.key, tree.root, 'RECURSIVE')).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
|
|
@@ -54,7 +54,7 @@ describe('BST operations test', () => {
|
|
|
54
54
|
expect(minNodeBySpecificNode?.key).toBe(12);
|
|
55
55
|
|
|
56
56
|
let subTreeSum = 0;
|
|
57
|
-
node15 && bst.dfs(node => (subTreeSum += node.key), '
|
|
57
|
+
node15 && bst.dfs(node => (subTreeSum += node.key), 'PRE', 15);
|
|
58
58
|
expect(subTreeSum).toBe(70);
|
|
59
59
|
|
|
60
60
|
let lesserSum = 0;
|
|
@@ -66,7 +66,7 @@ describe('BST operations test', () => {
|
|
|
66
66
|
const node11 = bst.getNode(11);
|
|
67
67
|
expect(node11).toBeInstanceOf(BSTNode);
|
|
68
68
|
|
|
69
|
-
const dfsInorderNodes = bst.dfs(node => node, '
|
|
69
|
+
const dfsInorderNodes = bst.dfs(node => node, 'IN');
|
|
70
70
|
expect(dfsInorderNodes[0].key).toBe(1);
|
|
71
71
|
expect(dfsInorderNodes[dfsInorderNodes.length - 1].key).toBe(16);
|
|
72
72
|
|
|
@@ -257,7 +257,7 @@ describe('BST operations test', () => {
|
|
|
257
257
|
expect(minNodeBySpecificNode?.key).toBe(12);
|
|
258
258
|
|
|
259
259
|
let subTreeSum = 0;
|
|
260
|
-
node15 && objBST.dfs(node => (subTreeSum += node.key), '
|
|
260
|
+
node15 && objBST.dfs(node => (subTreeSum += node.key), 'PRE', node15);
|
|
261
261
|
expect(subTreeSum).toBe(70);
|
|
262
262
|
|
|
263
263
|
let lesserSum = 0;
|
|
@@ -269,7 +269,7 @@ describe('BST operations test', () => {
|
|
|
269
269
|
const node11 = objBST.getNode(11);
|
|
270
270
|
expect(node11).toBeInstanceOf(BSTNode);
|
|
271
271
|
|
|
272
|
-
const dfsInorderNodes = objBST.dfs(node => node, '
|
|
272
|
+
const dfsInorderNodes = objBST.dfs(node => node, 'IN');
|
|
273
273
|
expect(dfsInorderNodes[0].key).toBe(1);
|
|
274
274
|
expect(dfsInorderNodes[dfsInorderNodes.length - 1].key).toBe(16);
|
|
275
275
|
|
|
@@ -444,7 +444,7 @@ describe('BST operations test recursively', () => {
|
|
|
444
444
|
expect(minNodeBySpecificNode?.key).toBe(12);
|
|
445
445
|
|
|
446
446
|
let subTreeSum = 0;
|
|
447
|
-
node15 && bst.dfs(node => (subTreeSum += node.key), '
|
|
447
|
+
node15 && bst.dfs(node => (subTreeSum += node.key), 'PRE', 15);
|
|
448
448
|
expect(subTreeSum).toBe(70);
|
|
449
449
|
|
|
450
450
|
let lesserSum = 0;
|
|
@@ -456,7 +456,7 @@ describe('BST operations test recursively', () => {
|
|
|
456
456
|
const node11 = bst.getNode(11);
|
|
457
457
|
expect(node11).toBeInstanceOf(BSTNode);
|
|
458
458
|
|
|
459
|
-
const dfsInorderNodes = bst.dfs(node => node, '
|
|
459
|
+
const dfsInorderNodes = bst.dfs(node => node, 'IN');
|
|
460
460
|
expect(dfsInorderNodes[0].key).toBe(1);
|
|
461
461
|
expect(dfsInorderNodes[dfsInorderNodes.length - 1].key).toBe(16);
|
|
462
462
|
|
|
@@ -645,7 +645,7 @@ describe('BST operations test recursively', () => {
|
|
|
645
645
|
expect(minNodeBySpecificNode?.key).toBe(12);
|
|
646
646
|
|
|
647
647
|
let subTreeSum = 0;
|
|
648
|
-
node15 && objBST.dfs(node => (subTreeSum += node.key), '
|
|
648
|
+
node15 && objBST.dfs(node => (subTreeSum += node.key), 'PRE', node15);
|
|
649
649
|
expect(subTreeSum).toBe(70);
|
|
650
650
|
|
|
651
651
|
let lesserSum = 0;
|
|
@@ -657,7 +657,7 @@ describe('BST operations test recursively', () => {
|
|
|
657
657
|
const node11 = objBST.getNode(11);
|
|
658
658
|
expect(node11).toBeInstanceOf(BSTNode);
|
|
659
659
|
|
|
660
|
-
const dfsInorderNodes = objBST.dfs(node => node, '
|
|
660
|
+
const dfsInorderNodes = objBST.dfs(node => node, 'IN');
|
|
661
661
|
expect(dfsInorderNodes[0].key).toBe(1);
|
|
662
662
|
expect(dfsInorderNodes[dfsInorderNodes.length - 1].key).toBe(16);
|
|
663
663
|
|
|
@@ -932,10 +932,10 @@ describe('BST Performance test', function () {
|
|
|
932
932
|
it('should dfs as sub tree traversal, null should be ignored', () => {
|
|
933
933
|
const bst = new BST();
|
|
934
934
|
bst.addMany([4, 2, 6, 1, 3, 5, 7]);
|
|
935
|
-
expect(bst.dfs(node => node.key, '
|
|
936
|
-
expect(bst.dfs(node => node.key, '
|
|
937
|
-
expect(bst.dfs(node => node?.key ?? undefined, '
|
|
938
|
-
expect(bst.dfs(node => node?.key ?? undefined, '
|
|
935
|
+
expect(bst.dfs(node => node.key, 'PRE', bst.getNode(6), 'ITERATIVE')).toEqual([6, 5, 7]);
|
|
936
|
+
expect(bst.dfs(node => node.key, 'PRE', bst.getNode(6), 'RECURSIVE')).toEqual([6, 5, 7]);
|
|
937
|
+
expect(bst.dfs(node => node?.key ?? undefined, 'PRE', bst.getNode(6), 'ITERATIVE')).toEqual([6, 5, 7]);
|
|
938
|
+
expect(bst.dfs(node => node?.key ?? undefined, 'PRE', bst.getNode(6), 'RECURSIVE')).toEqual([6, 5, 7]);
|
|
939
939
|
});
|
|
940
940
|
});
|
|
941
941
|
|