data-structure-typed 1.50.7 → 1.50.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/README.md +73 -67
- package/benchmark/report.html +1 -37
- package/benchmark/report.json +15 -393
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +14 -3
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js +17 -6
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +33 -34
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/bst.d.ts +22 -3
- package/dist/cjs/data-structures/binary-tree/bst.js +78 -39
- package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +5 -5
- package/dist/cjs/data-structures/binary-tree/rb-tree.js +47 -50
- package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +40 -23
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +44 -28
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
- package/dist/cjs/data-structures/heap/heap.d.ts +1 -1
- package/dist/cjs/data-structures/heap/heap.js +5 -5
- package/dist/cjs/types/common.d.ts +6 -29
- package/dist/cjs/types/common.js +0 -40
- package/dist/cjs/types/common.js.map +1 -1
- package/dist/cjs/types/data-structures/binary-tree/rb-tree.d.ts +1 -4
- package/dist/cjs/types/data-structures/binary-tree/rb-tree.js +0 -6
- package/dist/cjs/types/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +14 -3
- package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.js +17 -6
- package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/mjs/data-structures/binary-tree/binary-tree.js +33 -34
- package/dist/mjs/data-structures/binary-tree/bst.d.ts +22 -3
- package/dist/mjs/data-structures/binary-tree/bst.js +78 -39
- package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +5 -5
- package/dist/mjs/data-structures/binary-tree/rb-tree.js +47 -50
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.d.ts +40 -23
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.js +44 -28
- package/dist/mjs/data-structures/heap/heap.d.ts +1 -1
- package/dist/mjs/data-structures/heap/heap.js +5 -5
- package/dist/mjs/types/common.d.ts +6 -29
- package/dist/mjs/types/common.js +1 -39
- package/dist/mjs/types/data-structures/binary-tree/rb-tree.d.ts +1 -4
- package/dist/mjs/types/data-structures/binary-tree/rb-tree.js +1 -5
- package/dist/umd/data-structure-typed.js +212 -206
- package/dist/umd/data-structure-typed.min.js +2 -2
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +6 -6
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +20 -7
- package/src/data-structures/binary-tree/binary-tree.ts +54 -45
- package/src/data-structures/binary-tree/bst.ts +86 -42
- package/src/data-structures/binary-tree/rb-tree.ts +49 -49
- package/src/data-structures/binary-tree/tree-multi-map.ts +48 -29
- package/src/data-structures/heap/heap.ts +5 -5
- package/src/types/common.ts +6 -30
- package/src/types/data-structures/binary-tree/rb-tree.ts +1 -1
- package/test/integration/all-in-one.test.ts +4 -4
- package/test/integration/avl-tree.test.ts +1 -1
- package/test/integration/bst.test.ts +2 -2
- package/test/performance/data-structures/binary-tree/avl-tree.test.ts +20 -15
- package/test/performance/data-structures/binary-tree/binary-tree.test.ts +1 -1
- package/test/performance/data-structures/binary-tree/rb-tree.test.ts +13 -22
- package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +15 -23
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +8 -8
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +127 -74
- package/test/unit/data-structures/binary-tree/bst.test.ts +20 -20
- package/test/unit/data-structures/binary-tree/overall.test.ts +7 -7
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +31 -26
- package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +26 -34
- package/test/unit/data-structures/priority-queue/priority-queue.test.ts +3 -3
|
@@ -9,12 +9,13 @@ import type {
|
|
|
9
9
|
BinaryTreeDeleteResult,
|
|
10
10
|
BSTNKeyOrNode,
|
|
11
11
|
BTNCallback,
|
|
12
|
+
IterationType,
|
|
12
13
|
KeyOrNodeOrEntry,
|
|
13
14
|
TreeMultiMapNested,
|
|
14
15
|
TreeMultiMapNodeNested,
|
|
15
16
|
TreeMultiMapOptions
|
|
16
17
|
} from '../../types';
|
|
17
|
-
import {
|
|
18
|
+
import { RBTNColor } from '../../types';
|
|
18
19
|
import { IBinaryTree } from '../../interfaces';
|
|
19
20
|
import { RedBlackTree, RedBlackTreeNode } from './rb-tree';
|
|
20
21
|
|
|
@@ -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,14 +375,14 @@ 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
|
|
|
364
383
|
this.clear();
|
|
365
384
|
|
|
366
|
-
if (iterationType ===
|
|
385
|
+
if (iterationType === 'RECURSIVE') {
|
|
367
386
|
const buildBalanceBST = (l: number, r: number) => {
|
|
368
387
|
if (l > r) return;
|
|
369
388
|
const m = l + Math.floor((r - l) / 2);
|
|
@@ -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
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
INVERSE = 'INVERSE'
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export enum CP {
|
|
7
|
-
lt = 'lt',
|
|
8
|
-
eq = 'eq',
|
|
9
|
-
gt = 'gt'
|
|
10
|
-
}
|
|
1
|
+
export type BSTVariant = 'STANDARD' | 'INVERSE';
|
|
2
|
+
export type CP = 'LT' | 'EQ' | 'GT';
|
|
11
3
|
|
|
12
4
|
/**
|
|
13
5
|
* Enum representing different loop types.
|
|
@@ -15,24 +7,13 @@ export enum CP {
|
|
|
15
7
|
* - `iterative`: Indicates the iterative loop type (with loops that use iterations).
|
|
16
8
|
* - `recursive`: Indicates the recursive loop type (with loops that call themselves).
|
|
17
9
|
*/
|
|
18
|
-
export
|
|
19
|
-
ITERATIVE = 'ITERATIVE',
|
|
20
|
-
RECURSIVE = 'RECURSIVE'
|
|
21
|
-
}
|
|
10
|
+
export type IterationType = 'ITERATIVE' | 'RECURSIVE';
|
|
22
11
|
|
|
23
|
-
export
|
|
24
|
-
ROOT = 'ROOT',
|
|
25
|
-
LEFT = 'LEFT',
|
|
26
|
-
RIGHT = 'RIGHT',
|
|
27
|
-
ROOT_LEFT = 'ROOT_LEFT',
|
|
28
|
-
ROOT_RIGHT = 'ROOT_RIGHT',
|
|
29
|
-
ISOLATED = 'ISOLATED',
|
|
30
|
-
MAL_NODE = 'MAL_NODE'
|
|
31
|
-
}
|
|
12
|
+
export type FamilyPosition = 'ROOT' | 'LEFT' | 'RIGHT' | 'ROOT_LEFT' | 'ROOT_RIGHT' | 'ISOLATED' | 'MAL_NODE';
|
|
32
13
|
|
|
33
14
|
export type Comparator<K> = (a: K, b: K) => number;
|
|
34
15
|
|
|
35
|
-
export type DFSOrderPattern = '
|
|
16
|
+
export type DFSOrderPattern = 'PRE' | 'IN' | 'POST';
|
|
36
17
|
|
|
37
18
|
export type NodeDisplayLayout = [string[], number, number, number];
|
|
38
19
|
|
|
@@ -64,9 +45,4 @@ export type BSTNKeyOrNode<K, N> = K | undefined | N;
|
|
|
64
45
|
|
|
65
46
|
export type BinaryTreeDeleteResult<N> = { deleted: N | null | undefined; needBalanced: N | null | undefined };
|
|
66
47
|
|
|
67
|
-
export
|
|
68
|
-
CREATED = 'CREATED',
|
|
69
|
-
READ = 'READ',
|
|
70
|
-
UPDATED = 'UPDATED',
|
|
71
|
-
DELETED = 'DELETED'
|
|
72
|
-
}
|
|
48
|
+
export type CRUD = 'CREATED' | 'READ' | 'UPDATED' | 'DELETED';
|
|
@@ -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
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AVLTree
|
|
1
|
+
import { AVLTree } from 'data-structure-typed';
|
|
2
2
|
|
|
3
3
|
describe('AVL Tree Test from data-structure-typed', () => {
|
|
4
4
|
it('should perform various operations on a AVL Tree from data-structure-typed', () => {
|
|
@@ -23,17 +23,17 @@ 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;
|
|
30
|
-
tree.lesserOrGreaterTraverse(node => (lesserSum += node.key),
|
|
30
|
+
tree.lesserOrGreaterTraverse(node => (lesserSum += node.key), 'LT', 10);
|
|
31
31
|
expect(lesserSum).toBe(45);
|
|
32
32
|
|
|
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
|
|
|
@@ -40,7 +40,7 @@ describe('AVL Tree Test', () => {
|
|
|
40
40
|
expect(getMinNodeBySpecificNode?.key).toBe(12);
|
|
41
41
|
|
|
42
42
|
let subTreeSum = 0;
|
|
43
|
-
node15 && tree.
|
|
43
|
+
node15 && tree.dfs(node => (subTreeSum += node.key), 'in', 15);
|
|
44
44
|
expect(subTreeSum).toBe(70);
|
|
45
45
|
|
|
46
46
|
let lesserSum = 0;
|
|
@@ -34,7 +34,7 @@ describe('Individual package BST operations test', () => {
|
|
|
34
34
|
expect(minNodeBySpecificNode?.key).toBe(12);
|
|
35
35
|
|
|
36
36
|
let subTreeSum = 0;
|
|
37
|
-
node15 && bst.
|
|
37
|
+
node15 && bst.dfs(node => (subTreeSum += node.key), 'in', 15);
|
|
38
38
|
expect(subTreeSum).toBe(70);
|
|
39
39
|
|
|
40
40
|
let lesserSum = 0;
|
|
@@ -231,7 +231,7 @@ describe('Individual package BST operations test', () => {
|
|
|
231
231
|
expect(minNodeBySpecificNode?.key).toBe(12);
|
|
232
232
|
|
|
233
233
|
let subTreeSum = 0;
|
|
234
|
-
node15 && objBST.
|
|
234
|
+
node15 && objBST.dfs(node => (subTreeSum += node.key), 'in', node15);
|
|
235
235
|
expect(subTreeSum).toBe(70);
|
|
236
236
|
|
|
237
237
|
let lesserSum = 0;
|
|
@@ -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 };
|
|
@@ -11,23 +11,25 @@ const randomArray = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND - 1,
|
|
|
11
11
|
const cOrderedMap = new OrderedMap<number, number>();
|
|
12
12
|
|
|
13
13
|
suite
|
|
14
|
-
.add(`${HUNDRED_THOUSAND.toLocaleString()} add
|
|
14
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add`, () => {
|
|
15
|
+
rbTree.clear();
|
|
15
16
|
for (let i = 0; i < randomArray.length; i++) rbTree.add(i);
|
|
16
17
|
})
|
|
17
|
-
.add(`${HUNDRED_THOUSAND.toLocaleString()}
|
|
18
|
-
for (let i = 0; i < randomArray.length; i++) rbTree.
|
|
19
|
-
})
|
|
20
|
-
.add(`${HUNDRED_THOUSAND.toLocaleString()} add randomly`, () => {
|
|
21
|
-
rbTree.clear();
|
|
22
|
-
for (let i = 0; i < randomArray.length; i++) rbTree.add(randomArray[i]);
|
|
18
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} get`, () => {
|
|
19
|
+
for (let i = 0; i < randomArray.length; i++) rbTree.get(randomArray[i]);
|
|
23
20
|
})
|
|
24
|
-
.add(`${HUNDRED_THOUSAND.toLocaleString()}
|
|
25
|
-
|
|
21
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} iterator`, () => {
|
|
22
|
+
const entries = [...rbTree];
|
|
23
|
+
return entries.length === HUNDRED_THOUSAND;
|
|
26
24
|
})
|
|
27
|
-
.add(`${HUNDRED_THOUSAND.toLocaleString()} add orderly`, () => {
|
|
25
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & delete orderly`, () => {
|
|
26
|
+
rbTree.clear();
|
|
28
27
|
for (let i = 0; i < randomArray.length; i++) rbTree.add(i);
|
|
28
|
+
for (let i = 0; i < randomArray.length; i++) rbTree.delete(i);
|
|
29
29
|
})
|
|
30
|
-
.add(`${HUNDRED_THOUSAND.toLocaleString()} delete randomly`, () => {
|
|
30
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & delete randomly`, () => {
|
|
31
|
+
rbTree.clear();
|
|
32
|
+
for (let i = 0; i < randomArray.length; i++) rbTree.add(randomArray[i]);
|
|
31
33
|
for (let i = 0; i < randomArray.length; i++) rbTree.delete(randomArray[i]);
|
|
32
34
|
});
|
|
33
35
|
|
|
@@ -37,15 +39,4 @@ if (isCompetitor) {
|
|
|
37
39
|
});
|
|
38
40
|
}
|
|
39
41
|
|
|
40
|
-
suite.add(`${HUNDRED_THOUSAND.toLocaleString()} getNode randomly`, () => {
|
|
41
|
-
for (let i = 0; i < randomArray.length; i++) rbTree.getNode(randomArray[i]);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add & iterator`, () => {
|
|
45
|
-
rbTree.clear();
|
|
46
|
-
for (let i = 0; i < randomArray.length; i++) rbTree.add(randomArray[i]);
|
|
47
|
-
const entries = [...rbTree];
|
|
48
|
-
return entries.length === HUNDRED_THOUSAND;
|
|
49
|
-
});
|
|
50
|
-
|
|
51
42
|
export { suite };
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AVLTreeMultiMap,
|
|
3
|
-
AVLTreeMultiMapNode,
|
|
4
|
-
AVLTreeNode,
|
|
5
|
-
BinaryTreeNode,
|
|
6
|
-
BSTNode,
|
|
7
|
-
CP,
|
|
8
|
-
IterationType
|
|
9
|
-
} from '../../../../src';
|
|
1
|
+
import { AVLTreeMultiMap, AVLTreeMultiMapNode, AVLTreeNode, BinaryTreeNode, BSTNode } from '../../../../src';
|
|
10
2
|
import { isDebugTest } from '../../../config';
|
|
11
3
|
|
|
12
4
|
const isDebug = isDebugTest;
|
|
@@ -36,10 +28,10 @@ describe('AVLTreeMultiMap count', () => {
|
|
|
36
28
|
[3, 3]
|
|
37
29
|
]);
|
|
38
30
|
tm.add([2, 2], undefined, 10);
|
|
39
|
-
tm.lesserOrGreaterTraverse(node => (node.count += 2),
|
|
31
|
+
tm.lesserOrGreaterTraverse(node => (node.count += 2), 'GT', 1);
|
|
40
32
|
tm.delete(2);
|
|
41
33
|
expect(tm.count).toBe(12);
|
|
42
|
-
expect(tm.
|
|
34
|
+
expect(tm.getComputedCount()).toBe(16);
|
|
43
35
|
});
|
|
44
36
|
});
|
|
45
37
|
|
|
@@ -99,25 +91,25 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|
|
99
91
|
expect(minNodeBySpecificNode?.key).toBe(15);
|
|
100
92
|
|
|
101
93
|
let subTreeSum = 0;
|
|
102
|
-
node15 && treeMultimap.dfs(node => (subTreeSum += node.key), '
|
|
94
|
+
node15 && treeMultimap.dfs(node => (subTreeSum += node.key), 'PRE', 15);
|
|
103
95
|
expect(subTreeSum).toBe(31);
|
|
104
96
|
let lesserSum = 0;
|
|
105
|
-
treeMultimap.lesserOrGreaterTraverse((node: AVLTreeMultiMapNode<number>) => (lesserSum += node.key),
|
|
97
|
+
treeMultimap.lesserOrGreaterTraverse((node: AVLTreeMultiMapNode<number>) => (lesserSum += node.key), 'LT', 10);
|
|
106
98
|
expect(lesserSum).toBe(45);
|
|
107
99
|
|
|
108
100
|
expect(node15 instanceof AVLTreeMultiMapNode);
|
|
109
101
|
if (node15 instanceof AVLTreeMultiMapNode) {
|
|
110
|
-
const subTreeAdd = treeMultimap.dfs(node => (node.count += 1), '
|
|
102
|
+
const subTreeAdd = treeMultimap.dfs(node => (node.count += 1), 'PRE', 15);
|
|
111
103
|
expect(subTreeAdd);
|
|
112
104
|
}
|
|
113
105
|
const node11 = treeMultimap.getNode(11);
|
|
114
106
|
expect(node11 instanceof AVLTreeMultiMapNode);
|
|
115
107
|
if (node11 instanceof AVLTreeMultiMapNode) {
|
|
116
|
-
const allGreaterNodesAdded = treeMultimap.lesserOrGreaterTraverse(node => (node.count += 2),
|
|
108
|
+
const allGreaterNodesAdded = treeMultimap.lesserOrGreaterTraverse(node => (node.count += 2), 'GT', 11);
|
|
117
109
|
expect(allGreaterNodesAdded);
|
|
118
110
|
}
|
|
119
111
|
|
|
120
|
-
const dfsInorderNodes = treeMultimap.dfs(node => node, '
|
|
112
|
+
const dfsInorderNodes = treeMultimap.dfs(node => node, 'IN');
|
|
121
113
|
expect(dfsInorderNodes[0].key).toBe(1);
|
|
122
114
|
expect(dfsInorderNodes[dfsInorderNodes.length - 1].key).toBe(16);
|
|
123
115
|
expect(treeMultimap.isPerfectlyBalanced()).toBe(false);
|
|
@@ -299,7 +291,7 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|
|
299
291
|
|
|
300
292
|
describe('AVLTreeMultiMap operations test recursively1', () => {
|
|
301
293
|
it('should perform various operations on a Binary Search Tree with numeric values1', () => {
|
|
302
|
-
const treeMultimap = new AVLTreeMultiMap<number>([], { iterationType:
|
|
294
|
+
const treeMultimap = new AVLTreeMultiMap<number>([], { iterationType: 'RECURSIVE' });
|
|
303
295
|
|
|
304
296
|
expect(treeMultimap instanceof AVLTreeMultiMap);
|
|
305
297
|
treeMultimap.add([11, 11]);
|
|
@@ -353,25 +345,25 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|
|
353
345
|
expect(minNodeBySpecificNode?.key).toBe(15);
|
|
354
346
|
|
|
355
347
|
let subTreeSum = 0;
|
|
356
|
-
node15 && treeMultimap.dfs(node => (subTreeSum += node.key), '
|
|
348
|
+
node15 && treeMultimap.dfs(node => (subTreeSum += node.key), 'PRE', 15);
|
|
357
349
|
expect(subTreeSum).toBe(31);
|
|
358
350
|
let lesserSum = 0;
|
|
359
|
-
treeMultimap.lesserOrGreaterTraverse((node: AVLTreeMultiMapNode<number>) => (lesserSum += node.key),
|
|
351
|
+
treeMultimap.lesserOrGreaterTraverse((node: AVLTreeMultiMapNode<number>) => (lesserSum += node.key), 'LT', 10);
|
|
360
352
|
expect(lesserSum).toBe(45);
|
|
361
353
|
|
|
362
354
|
expect(node15 instanceof AVLTreeMultiMapNode);
|
|
363
355
|
if (node15 instanceof AVLTreeMultiMapNode) {
|
|
364
|
-
const subTreeAdd = treeMultimap.dfs(node => (node.count += 1), '
|
|
356
|
+
const subTreeAdd = treeMultimap.dfs(node => (node.count += 1), 'PRE', 15);
|
|
365
357
|
expect(subTreeAdd);
|
|
366
358
|
}
|
|
367
359
|
const node11 = treeMultimap.getNode(11);
|
|
368
360
|
expect(node11 instanceof AVLTreeMultiMapNode);
|
|
369
361
|
if (node11 instanceof AVLTreeMultiMapNode) {
|
|
370
|
-
const allGreaterNodesAdded = treeMultimap.lesserOrGreaterTraverse(node => (node.count += 2),
|
|
362
|
+
const allGreaterNodesAdded = treeMultimap.lesserOrGreaterTraverse(node => (node.count += 2), 'GT', 11);
|
|
371
363
|
expect(allGreaterNodesAdded);
|
|
372
364
|
}
|
|
373
365
|
|
|
374
|
-
const dfsInorderNodes = treeMultimap.dfs(node => node, '
|
|
366
|
+
const dfsInorderNodes = treeMultimap.dfs(node => node, 'IN');
|
|
375
367
|
expect(dfsInorderNodes[0].key).toBe(1);
|
|
376
368
|
expect(dfsInorderNodes[dfsInorderNodes.length - 1].key).toBe(16);
|
|
377
369
|
expect(treeMultimap.isPerfectlyBalanced()).toBe(true);
|
|
@@ -572,7 +564,7 @@ describe('AVLTreeMultiMap Performance test', function () {
|
|
|
572
564
|
}
|
|
573
565
|
isDebug && console.log('---add', performance.now() - start);
|
|
574
566
|
const startL = performance.now();
|
|
575
|
-
treeMS.lesserOrGreaterTraverse(node => (node.count += 1),
|
|
567
|
+
treeMS.lesserOrGreaterTraverse(node => (node.count += 1), 'LT', inputSize / 2);
|
|
576
568
|
isDebug && console.log('---lesserOrGreaterTraverse', performance.now() - startL);
|
|
577
569
|
});
|
|
578
570
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AVLTree, AVLTreeNode, BinaryTreeNode, BSTNode
|
|
1
|
+
import { AVLTree, AVLTreeNode, BinaryTreeNode, BSTNode } from '../../../../src';
|
|
2
2
|
|
|
3
3
|
describe('AVL Tree Test', () => {
|
|
4
4
|
it('should perform various operations on a AVL Tree', () => {
|
|
@@ -24,17 +24,17 @@ 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;
|
|
31
|
-
tree.lesserOrGreaterTraverse(node => (lesserSum += node.key),
|
|
31
|
+
tree.lesserOrGreaterTraverse(node => (lesserSum += node.key), 'LT', 10);
|
|
32
32
|
expect(lesserSum).toBe(45);
|
|
33
33
|
|
|
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();
|
|
@@ -112,7 +112,7 @@ describe('AVL Tree Test', () => {
|
|
|
112
112
|
describe('AVL Tree Test recursively', () => {
|
|
113
113
|
it('should perform various operations on a AVL Tree', () => {
|
|
114
114
|
const arr = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
|
|
115
|
-
const tree = new AVLTree<number>([], { iterationType:
|
|
115
|
+
const tree = new AVLTree<number>([], { iterationType: 'RECURSIVE' });
|
|
116
116
|
|
|
117
117
|
for (const i of arr) tree.add([i, i]);
|
|
118
118
|
|
|
@@ -132,17 +132,17 @@ 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;
|
|
139
|
-
tree.lesserOrGreaterTraverse(node => (lesserSum += node.key),
|
|
139
|
+
tree.lesserOrGreaterTraverse(node => (lesserSum += node.key), 'LT', 10);
|
|
140
140
|
expect(lesserSum).toBe(45);
|
|
141
141
|
|
|
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
|
|