data-structure-typed 1.43.1 → 1.43.3
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/.eslintrc.js +3 -1
- package/CHANGELOG.md +1 -1
- package/README.md +7 -0
- package/benchmark/report.html +30 -30
- package/benchmark/report.json +201 -147
- package/dist/cjs/src/data-structures/binary-tree/avl-tree.js.map +1 -1
- package/dist/cjs/src/data-structures/binary-tree/binary-tree.d.ts +8 -8
- package/dist/cjs/src/data-structures/binary-tree/binary-tree.js +62 -62
- package/dist/cjs/src/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/src/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/cjs/src/data-structures/binary-tree/rb-tree.d.ts +4 -4
- package/dist/cjs/src/data-structures/binary-tree/rb-tree.js +1 -1
- package/dist/cjs/src/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/cjs/src/data-structures/binary-tree/tree-multimap.d.ts +24 -24
- package/dist/cjs/src/data-structures/binary-tree/tree-multimap.js +50 -50
- package/dist/cjs/src/data-structures/binary-tree/tree-multimap.js.map +1 -1
- package/dist/cjs/src/data-structures/graph/abstract-graph.d.ts +37 -37
- package/dist/cjs/src/data-structures/graph/abstract-graph.js +37 -37
- package/dist/cjs/src/data-structures/graph/abstract-graph.js.map +1 -1
- package/dist/cjs/src/data-structures/graph/directed-graph.js.map +1 -1
- package/dist/cjs/src/data-structures/graph/map-graph.js.map +1 -1
- package/dist/cjs/src/data-structures/graph/undirected-graph.js.map +1 -1
- package/dist/cjs/src/data-structures/heap/heap.js.map +1 -1
- package/dist/cjs/src/interfaces/binary-tree.d.ts +1 -1
- package/dist/mjs/src/data-structures/binary-tree/binary-tree.d.ts +8 -8
- package/dist/mjs/src/data-structures/binary-tree/binary-tree.js +62 -62
- package/dist/mjs/src/data-structures/binary-tree/rb-tree.d.ts +4 -4
- package/dist/mjs/src/data-structures/binary-tree/rb-tree.js +1 -1
- package/dist/mjs/src/data-structures/binary-tree/tree-multimap.d.ts +24 -24
- package/dist/mjs/src/data-structures/binary-tree/tree-multimap.js +50 -50
- package/dist/mjs/src/data-structures/graph/abstract-graph.d.ts +37 -37
- package/dist/mjs/src/data-structures/graph/abstract-graph.js +37 -37
- package/dist/mjs/src/interfaces/binary-tree.d.ts +1 -1
- package/dist/umd/data-structure-typed.js +10497 -0
- package/dist/umd/data-structure-typed.min.js +1 -1
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +1 -1
- package/src/data-structures/binary-tree/avl-tree.ts +2 -3
- package/src/data-structures/binary-tree/binary-tree.ts +85 -92
- package/src/data-structures/binary-tree/bst.ts +14 -22
- package/src/data-structures/binary-tree/rb-tree.ts +11 -20
- package/src/data-structures/binary-tree/tree-multimap.ts +56 -58
- package/src/data-structures/graph/abstract-graph.ts +6 -22
- package/src/data-structures/graph/directed-graph.ts +3 -9
- package/src/data-structures/graph/map-graph.ts +6 -6
- package/src/data-structures/graph/undirected-graph.ts +1 -2
- package/src/data-structures/heap/heap.ts +1 -6
- package/src/data-structures/trie/trie.ts +1 -1
- package/src/interfaces/binary-tree.ts +1 -1
- package/src/types/utils/validate-type.ts +2 -16
- package/test/integration/index.html +50 -4
- package/test/performance/data-structures/binary-tree/rb-tree.test.ts +18 -19
- package/test/performance/data-structures/hash/hash-map.test.ts +10 -13
- package/test/performance/data-structures/linked-list/doubly-linked-list.test.ts +16 -16
- package/test/performance/data-structures/priority-queue/max-priority-queue.test.ts +1 -3
- package/test/performance/data-structures/priority-queue/priority-queue.test.ts +10 -12
- package/test/performance/data-structures/queue/deque.test.ts +18 -19
- package/test/performance/data-structures/queue/queue.test.ts +18 -19
- package/test/performance/data-structures/stack/stack.test.ts +10 -11
- package/test/performance/reportor.ts +4 -5
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +0 -1
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +83 -61
- package/test/unit/data-structures/binary-tree/bst.test.ts +2 -6
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +34 -25
- package/test/unit/data-structures/graph/abstract-graph.test.ts +6 -6
- package/test/unit/data-structures/graph/directed-graph.test.ts +8 -28
- package/test/unit/data-structures/heap/heap.test.ts +1 -8
- package/test/unit/data-structures/priority-queue/priority-queue.test.ts +34 -12
- package/test/utils/json2html.ts +2 -6
- package/tsup.config.js +19 -1
|
@@ -2,30 +2,29 @@ import {Deque} from '../../../../src';
|
|
|
2
2
|
import {Deque as CDeque} from 'js-sdsl';
|
|
3
3
|
import * as Benchmark from 'benchmark';
|
|
4
4
|
import {magnitude} from '../../../utils';
|
|
5
|
-
import {isCompetitor} from
|
|
5
|
+
import {isCompetitor} from '../../../config';
|
|
6
6
|
|
|
7
7
|
export const suite = new Benchmark.Suite();
|
|
8
8
|
const {LINEAR} = magnitude;
|
|
9
9
|
|
|
10
|
-
suite
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
deque.push(i);
|
|
15
|
-
}
|
|
16
|
-
})
|
|
17
|
-
if (isCompetitor) {
|
|
18
|
-
suite.add(`${LINEAR.toLocaleString()} competitor push`, () => {
|
|
19
|
-
const deque = new CDeque<number>();
|
|
20
|
-
for (let i = 0; i < LINEAR; i++) {
|
|
21
|
-
deque.pushBack(i);
|
|
22
|
-
}
|
|
23
|
-
})
|
|
10
|
+
suite.add(`${LINEAR.toLocaleString()} push`, () => {
|
|
11
|
+
const deque = new Deque<number>();
|
|
12
|
+
for (let i = 0; i < LINEAR; i++) {
|
|
13
|
+
deque.push(i);
|
|
24
14
|
}
|
|
25
|
-
|
|
26
|
-
|
|
15
|
+
});
|
|
16
|
+
if (isCompetitor) {
|
|
17
|
+
suite.add(`${LINEAR.toLocaleString()} competitor push`, () => {
|
|
18
|
+
const deque = new CDeque<number>();
|
|
27
19
|
for (let i = 0; i < LINEAR; i++) {
|
|
28
|
-
deque.
|
|
29
|
-
deque.shift();
|
|
20
|
+
deque.pushBack(i);
|
|
30
21
|
}
|
|
31
22
|
});
|
|
23
|
+
}
|
|
24
|
+
suite.add(`${LINEAR.toLocaleString()} shift`, () => {
|
|
25
|
+
const deque = new Deque<number>();
|
|
26
|
+
for (let i = 0; i < LINEAR; i++) {
|
|
27
|
+
deque.push(i);
|
|
28
|
+
deque.shift();
|
|
29
|
+
}
|
|
30
|
+
});
|
|
@@ -2,35 +2,34 @@ import {Queue} from '../../../../src';
|
|
|
2
2
|
import {Queue as CQueue} from 'js-sdsl';
|
|
3
3
|
import * as Benchmark from 'benchmark';
|
|
4
4
|
import {magnitude} from '../../../utils';
|
|
5
|
-
import {isCompetitor} from
|
|
5
|
+
import {isCompetitor} from '../../../config';
|
|
6
6
|
|
|
7
7
|
const suite = new Benchmark.Suite();
|
|
8
8
|
const {LINEAR} = magnitude;
|
|
9
9
|
|
|
10
|
-
suite
|
|
11
|
-
|
|
12
|
-
const queue = new Queue<number>();
|
|
10
|
+
suite.add(`${LINEAR.toLocaleString()} push`, () => {
|
|
11
|
+
const queue = new Queue<number>();
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
})
|
|
18
|
-
if (isCompetitor) {
|
|
19
|
-
suite.add(`${LINEAR.toLocaleString()} competitor push`, () => {
|
|
20
|
-
const queue = new CQueue<number>();
|
|
21
|
-
|
|
22
|
-
for (let i = 0; i < LINEAR; i++) {
|
|
23
|
-
queue.push(i);
|
|
24
|
-
}
|
|
25
|
-
})
|
|
13
|
+
for (let i = 0; i < LINEAR; i++) {
|
|
14
|
+
queue.push(i);
|
|
26
15
|
}
|
|
27
|
-
|
|
28
|
-
|
|
16
|
+
});
|
|
17
|
+
if (isCompetitor) {
|
|
18
|
+
suite.add(`${LINEAR.toLocaleString()} competitor push`, () => {
|
|
19
|
+
const queue = new CQueue<number>();
|
|
29
20
|
|
|
30
21
|
for (let i = 0; i < LINEAR; i++) {
|
|
31
22
|
queue.push(i);
|
|
32
|
-
queue.shift();
|
|
33
23
|
}
|
|
34
24
|
});
|
|
25
|
+
}
|
|
26
|
+
suite.add(`${LINEAR.toLocaleString()} push & shift`, () => {
|
|
27
|
+
const queue = new Queue<number>();
|
|
28
|
+
|
|
29
|
+
for (let i = 0; i < LINEAR; i++) {
|
|
30
|
+
queue.push(i);
|
|
31
|
+
queue.shift();
|
|
32
|
+
}
|
|
33
|
+
});
|
|
35
34
|
|
|
36
35
|
export {suite};
|
|
@@ -2,19 +2,18 @@ import {Stack} from '../../../../src';
|
|
|
2
2
|
import {Stack as CStack} from 'js-sdsl';
|
|
3
3
|
import * as Benchmark from 'benchmark';
|
|
4
4
|
import {magnitude} from '../../../utils';
|
|
5
|
-
import {isCompetitor} from
|
|
5
|
+
import {isCompetitor} from '../../../config';
|
|
6
6
|
|
|
7
7
|
const suite = new Benchmark.Suite();
|
|
8
8
|
const {LINEAR} = magnitude;
|
|
9
9
|
|
|
10
|
-
suite
|
|
11
|
-
|
|
12
|
-
const stack = new Stack<number>();
|
|
10
|
+
suite.add(`${LINEAR.toLocaleString()} push`, () => {
|
|
11
|
+
const stack = new Stack<number>();
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
for (let i = 0; i < LINEAR; i++) {
|
|
14
|
+
stack.push(i);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
18
17
|
if (isCompetitor) {
|
|
19
18
|
suite.add(`${LINEAR.toLocaleString()} competitor push`, () => {
|
|
20
19
|
const queue = new CStack<number>();
|
|
@@ -22,7 +21,7 @@ if (isCompetitor) {
|
|
|
22
21
|
for (let i = 0; i < LINEAR; i++) {
|
|
23
22
|
queue.push(i);
|
|
24
23
|
}
|
|
25
|
-
})
|
|
24
|
+
});
|
|
26
25
|
}
|
|
27
26
|
suite.add(`${LINEAR.toLocaleString()} push & pop`, () => {
|
|
28
27
|
const queue = new Stack<number>();
|
|
@@ -33,7 +32,7 @@ suite.add(`${LINEAR.toLocaleString()} push & pop`, () => {
|
|
|
33
32
|
for (let i = 0; i < LINEAR; i++) {
|
|
34
33
|
queue.pop();
|
|
35
34
|
}
|
|
36
|
-
})
|
|
35
|
+
});
|
|
37
36
|
if (isCompetitor) {
|
|
38
37
|
suite.add(`${LINEAR.toLocaleString()} competitor push & pop`, () => {
|
|
39
38
|
const queue = new CStack<number>();
|
|
@@ -44,7 +43,7 @@ if (isCompetitor) {
|
|
|
44
43
|
for (let i = 0; i < LINEAR; i++) {
|
|
45
44
|
queue.pop();
|
|
46
45
|
}
|
|
47
|
-
})
|
|
46
|
+
});
|
|
48
47
|
}
|
|
49
48
|
|
|
50
49
|
export {suite};
|
|
@@ -5,7 +5,9 @@ import * as fastGlob from 'fast-glob';
|
|
|
5
5
|
import {Color, numberFix, render} from '../utils';
|
|
6
6
|
import {PerformanceTest} from './types';
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const parentDirectory = path.resolve(__dirname, '../..');
|
|
9
|
+
const reportDistPath = path.join(parentDirectory, 'benchmark');
|
|
10
|
+
|
|
9
11
|
const testDir = path.join(__dirname, 'data-structures');
|
|
10
12
|
const testFiles = fastGlob.sync(path.join(testDir, '**', '*.test.ts'));
|
|
11
13
|
|
|
@@ -109,7 +111,6 @@ const composeReport = () => {
|
|
|
109
111
|
};
|
|
110
112
|
|
|
111
113
|
function replaceMarkdownContent(startMarker: string, endMarker: string, newText: string) {
|
|
112
|
-
const parentDirectory = path.resolve(__dirname, '../..'); // The path to the parent directory
|
|
113
114
|
const filePath = path.join(parentDirectory, 'README.md'); // Path to README.md file
|
|
114
115
|
fs.readFile(filePath, 'utf8', (err, data) => {
|
|
115
116
|
if (err) {
|
|
@@ -172,9 +173,7 @@ performanceTests.forEach(item => {
|
|
|
172
173
|
console.log(
|
|
173
174
|
// `Files: ${GREEN}${testFileCount}${END} `,
|
|
174
175
|
// `Suites: ${GREEN}${performanceTests.length}${END} `,
|
|
175
|
-
`Suites Progress: ${isDone ? GREEN : YELLOW}${completedCount}${END}/${isDone ? GREEN : YELLOW}${
|
|
176
|
-
performanceTests.length
|
|
177
|
-
}${END}`,
|
|
176
|
+
`Suites Progress: ${isDone ? GREEN : YELLOW}${completedCount}${END}/${isDone ? GREEN : YELLOW}${performanceTests.length}${END}`,
|
|
178
177
|
`Time: ${isTimeWarn ? YELLOW : GREEN}${runTime}s${END}`
|
|
179
178
|
);
|
|
180
179
|
if (isDone) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {BinaryTree, BinaryTreeNode, IterationType} from '../../../../src';
|
|
2
|
-
import {getRandomIntArray} from
|
|
3
|
-
import {FamilyPosition} from
|
|
2
|
+
import {getRandomIntArray} from '../../../utils';
|
|
3
|
+
import {FamilyPosition} from 'binary-tree-typed';
|
|
4
4
|
// import {isDebugTest} from '../../../config';
|
|
5
5
|
|
|
6
6
|
// const isDebug = isDebugTest;
|
|
@@ -72,7 +72,6 @@ describe('BinaryTreeNode', () => {
|
|
|
72
72
|
expect(leftChild.familyPosition).toBe('ROOT_LEFT');
|
|
73
73
|
rightChild.left = new BinaryTreeNode<number>(5);
|
|
74
74
|
expect(rightChild.familyPosition).toBe('ROOT_RIGHT');
|
|
75
|
-
|
|
76
75
|
});
|
|
77
76
|
|
|
78
77
|
it('should determine only right child family position correctly', () => {
|
|
@@ -106,8 +105,8 @@ describe('BinaryTree', () => {
|
|
|
106
105
|
});
|
|
107
106
|
|
|
108
107
|
it('should delete nodes', () => {
|
|
109
|
-
expect(tree.getHeight(tree.root, IterationType.ITERATIVE)).toBe(-1)
|
|
110
|
-
expect(tree.getMinHeight()).toBe(-1)
|
|
108
|
+
expect(tree.getHeight(tree.root, IterationType.ITERATIVE)).toBe(-1);
|
|
109
|
+
expect(tree.getMinHeight()).toBe(-1);
|
|
111
110
|
const node = tree.add(1);
|
|
112
111
|
expect(tree.size).toBe(1);
|
|
113
112
|
|
|
@@ -117,7 +116,6 @@ describe('BinaryTree', () => {
|
|
|
117
116
|
tree.add(rightChild);
|
|
118
117
|
const root = tree.root;
|
|
119
118
|
|
|
120
|
-
|
|
121
119
|
expect(leftChild.familyPosition).toBe('LEFT');
|
|
122
120
|
tree.add(null);
|
|
123
121
|
tree.add(new BinaryTreeNode<number>(4));
|
|
@@ -128,15 +126,14 @@ describe('BinaryTree', () => {
|
|
|
128
126
|
expect(rightChild.familyPosition).toBe('ROOT_RIGHT');
|
|
129
127
|
|
|
130
128
|
tree.delete(new BinaryTreeNode<number>(200));
|
|
131
|
-
tree.delete(rightChild)
|
|
129
|
+
tree.delete(rightChild);
|
|
132
130
|
|
|
133
131
|
if (node) {
|
|
134
132
|
const result = tree.delete(node);
|
|
135
133
|
expect(result).toHaveLength(1);
|
|
136
134
|
expect(tree.size).toBe(3);
|
|
137
|
-
expect(tree.getMinHeight(tree.root, IterationType.RECURSIVE)).toBe(1)
|
|
135
|
+
expect(tree.getMinHeight(tree.root, IterationType.RECURSIVE)).toBe(1);
|
|
138
136
|
}
|
|
139
|
-
|
|
140
137
|
});
|
|
141
138
|
|
|
142
139
|
it('should add and find nodes', () => {
|
|
@@ -155,11 +152,10 @@ describe('BinaryTree', () => {
|
|
|
155
152
|
expect(tree.has('3', node => node.value?.toString())).toBe(true);
|
|
156
153
|
});
|
|
157
154
|
|
|
158
|
-
|
|
159
155
|
it('should be a balance tree after malicious manipulation', () => {
|
|
160
156
|
tree.add(3);
|
|
161
157
|
tree.add(12);
|
|
162
|
-
tree.addMany(getRandomIntArray(100, 1, 100))
|
|
158
|
+
tree.addMany(getRandomIntArray(100, 1, 100));
|
|
163
159
|
tree.add(10);
|
|
164
160
|
|
|
165
161
|
expect(tree.isPerfectlyBalanced()).toBe(true);
|
|
@@ -238,20 +234,16 @@ describe('BinaryTree', () => {
|
|
|
238
234
|
|
|
239
235
|
expect(tree.isSubtreeBST(tree.getNode(4), IterationType.RECURSIVE)).toBe(true);
|
|
240
236
|
expect(tree.isSubtreeBST(tree.getNode(4), IterationType.ITERATIVE)).toBe(true);
|
|
241
|
-
expect(tree.getNodes(2, undefined, false, null)).toEqual([])
|
|
242
|
-
expect(tree.getNodes(tree.getNodeByKey(2), undefined, false, tree.root)).toEqual([tree.getNodeByKey(2)])
|
|
237
|
+
expect(tree.getNodes(2, undefined, false, null)).toEqual([]);
|
|
238
|
+
expect(tree.getNodes(tree.getNodeByKey(2), undefined, false, tree.root)).toEqual([tree.getNodeByKey(2)]);
|
|
243
239
|
});
|
|
244
240
|
|
|
245
241
|
it('should subTreeTraverse', () => {
|
|
246
242
|
tree.addMany([4, 2, 6, null, 1, 3, null, 5, null, 7]);
|
|
247
243
|
expect(tree.subTreeTraverse(node => node.key, tree.getNode(6), IterationType.ITERATIVE)).toEqual([6, 3, 7]);
|
|
248
244
|
expect(tree.subTreeTraverse(node => node.key, tree.getNode(6), IterationType.RECURSIVE)).toEqual([6, 3, 7]);
|
|
249
|
-
expect(
|
|
250
|
-
|
|
251
|
-
).toEqual([6, 3, 7, null]);
|
|
252
|
-
expect(
|
|
253
|
-
tree.subTreeTraverse(node => (node ? node.key : null ), tree.getNode(6), IterationType.RECURSIVE, true)
|
|
254
|
-
).toEqual([6, 3, 7, null]);
|
|
245
|
+
expect(tree.subTreeTraverse(node => (node ? node.key : null), tree.getNode(6), IterationType.ITERATIVE, true)).toEqual([6, 3, 7, null]);
|
|
246
|
+
expect(tree.subTreeTraverse(node => (node ? node.key : null), tree.getNode(6), IterationType.RECURSIVE, true)).toEqual([6, 3, 7, null]);
|
|
255
247
|
});
|
|
256
248
|
|
|
257
249
|
it('should clear the tree', () => {
|
|
@@ -323,46 +315,82 @@ describe('BinaryTree traversals', () => {
|
|
|
323
315
|
|
|
324
316
|
const arr = [35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55];
|
|
325
317
|
tree.refill(arr);
|
|
326
|
-
expect(
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
expect(tree.dfs(node => node.key, 'pre', tree.root, IterationType.RECURSIVE)).toEqual([
|
|
341
|
-
35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55
|
|
318
|
+
expect(tree.bfs(node => node, tree.root, IterationType.ITERATIVE, true).map(node => (node ? node.key : null))).toEqual([
|
|
319
|
+
35,
|
|
320
|
+
20,
|
|
321
|
+
40,
|
|
322
|
+
15,
|
|
323
|
+
29,
|
|
324
|
+
null,
|
|
325
|
+
50,
|
|
326
|
+
null,
|
|
327
|
+
16,
|
|
328
|
+
28,
|
|
329
|
+
30,
|
|
330
|
+
45,
|
|
331
|
+
55
|
|
342
332
|
]);
|
|
343
|
-
expect(
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35
|
|
333
|
+
expect(tree.bfs(node => node, tree.root, IterationType.RECURSIVE, true).map(node => (node ? node.key : null))).toEqual([
|
|
334
|
+
35,
|
|
335
|
+
20,
|
|
336
|
+
40,
|
|
337
|
+
15,
|
|
338
|
+
29,
|
|
339
|
+
null,
|
|
340
|
+
50,
|
|
341
|
+
null,
|
|
342
|
+
16,
|
|
343
|
+
28,
|
|
344
|
+
30,
|
|
345
|
+
45,
|
|
346
|
+
55
|
|
358
347
|
]);
|
|
359
|
-
expect(tree.bfs(node => node
|
|
348
|
+
expect(tree.bfs(node => node, tree.root, IterationType.ITERATIVE).map(node => (node === null ? null : node.key))).toEqual([
|
|
360
349
|
35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55
|
|
361
350
|
]);
|
|
362
|
-
expect(tree.bfs(node => node
|
|
351
|
+
expect(tree.bfs(node => node, tree.root, IterationType.RECURSIVE).map(node => (node === null ? null : node.key))).toEqual([
|
|
363
352
|
35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55
|
|
364
353
|
]);
|
|
365
354
|
|
|
355
|
+
expect(tree.dfs(node => node.key, 'pre')).toEqual([35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55]);
|
|
356
|
+
expect(tree.dfs(node => node.key, 'pre', tree.root, IterationType.RECURSIVE)).toEqual([35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55]);
|
|
357
|
+
expect(tree.dfs(node => node, 'pre', tree.root, IterationType.ITERATIVE, true).map(node => (node ? node.key : null))).toEqual([
|
|
358
|
+
35,
|
|
359
|
+
20,
|
|
360
|
+
15,
|
|
361
|
+
null,
|
|
362
|
+
16,
|
|
363
|
+
29,
|
|
364
|
+
28,
|
|
365
|
+
30,
|
|
366
|
+
40,
|
|
367
|
+
null,
|
|
368
|
+
50,
|
|
369
|
+
45,
|
|
370
|
+
55
|
|
371
|
+
]);
|
|
372
|
+
expect(tree.dfs(node => node, 'pre', tree.root, IterationType.RECURSIVE, true).map(node => (node ? node.key : null))).toEqual([
|
|
373
|
+
35,
|
|
374
|
+
20,
|
|
375
|
+
15,
|
|
376
|
+
null,
|
|
377
|
+
16,
|
|
378
|
+
29,
|
|
379
|
+
28,
|
|
380
|
+
30,
|
|
381
|
+
40,
|
|
382
|
+
null,
|
|
383
|
+
50,
|
|
384
|
+
45,
|
|
385
|
+
55
|
|
386
|
+
]);
|
|
387
|
+
|
|
388
|
+
expect(tree.dfs(node => node.key, 'in')).toEqual([15, 16, 20, 28, 29, 30, 35, 40, 45, 50, 55]);
|
|
389
|
+
expect(tree.dfs(node => node.key, 'post')).toEqual([16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35]);
|
|
390
|
+
expect(tree.dfs(node => node.key, 'post', tree.root, IterationType.RECURSIVE)).toEqual([16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35]);
|
|
391
|
+
expect(tree.bfs(node => node.key, tree.root, IterationType.RECURSIVE)).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
|
|
392
|
+
expect(tree.bfs(node => node.key, tree.root, IterationType.ITERATIVE)).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
|
|
393
|
+
|
|
366
394
|
expect(tree.listLevels(node => node.key)).toEqual([[35], [20, 40], [15, 29, 50], [16, 28, 30, 45, 55]]);
|
|
367
395
|
|
|
368
396
|
expect(tree.listLevels(node => node.key, tree.root, IterationType.RECURSIVE)).toEqual([
|
|
@@ -371,13 +399,13 @@ describe('BinaryTree traversals', () => {
|
|
|
371
399
|
[15, 29, 50],
|
|
372
400
|
[16, 28, 30, 45, 55]
|
|
373
401
|
]);
|
|
374
|
-
expect(tree.listLevels(node => (node ? node.key : null
|
|
402
|
+
expect(tree.listLevels(node => (node ? node.key : null), tree.root, IterationType.ITERATIVE, true)).toEqual([
|
|
375
403
|
[35],
|
|
376
404
|
[20, 40],
|
|
377
405
|
[15, 29, null, 50],
|
|
378
406
|
[null, 16, 28, 30, 45, 55]
|
|
379
407
|
]);
|
|
380
|
-
expect(tree.listLevels(node => (
|
|
408
|
+
expect(tree.listLevels(node => (node ? node.key : null), tree.root, IterationType.RECURSIVE, true)).toEqual([
|
|
381
409
|
[35],
|
|
382
410
|
[20, 40],
|
|
383
411
|
[15, 29, null, 50],
|
|
@@ -532,13 +560,7 @@ describe('BinaryTree', () => {
|
|
|
532
560
|
expect(nodes.length).toBe(1);
|
|
533
561
|
expect(nodes[0].key).toBe(3);
|
|
534
562
|
|
|
535
|
-
const nodesRec = tree.getNodes(
|
|
536
|
-
'B',
|
|
537
|
-
(node: BinaryTreeNode<string>) => node.value,
|
|
538
|
-
false,
|
|
539
|
-
tree.root,
|
|
540
|
-
IterationType.RECURSIVE
|
|
541
|
-
);
|
|
563
|
+
const nodesRec = tree.getNodes('B', (node: BinaryTreeNode<string>) => node.value, false, tree.root, IterationType.RECURSIVE);
|
|
542
564
|
|
|
543
565
|
expect(nodesRec.length).toBe(1);
|
|
544
566
|
expect(nodesRec[0].key).toBe(3);
|
|
@@ -843,11 +843,7 @@ describe('BST Performance test', function () {
|
|
|
843
843
|
bst.addMany([4, 2, 6, 1, 3, 5, 7]);
|
|
844
844
|
expect(bst.subTreeTraverse(node => node.key, bst.getNode(6), IterationType.ITERATIVE)).toEqual([6, 5, 7]);
|
|
845
845
|
expect(bst.subTreeTraverse(node => node.key, bst.getNode(6), IterationType.RECURSIVE)).toEqual([6, 5, 7]);
|
|
846
|
-
expect(
|
|
847
|
-
|
|
848
|
-
).toEqual([6, 5, 7]);
|
|
849
|
-
expect(
|
|
850
|
-
bst.subTreeTraverse(node => (node?.key ?? undefined), bst.getNode(6), IterationType.RECURSIVE, true)
|
|
851
|
-
).toEqual([6, 5, 7]);
|
|
846
|
+
expect(bst.subTreeTraverse(node => node?.key ?? undefined, bst.getNode(6), IterationType.ITERATIVE, true)).toEqual([6, 5, 7]);
|
|
847
|
+
expect(bst.subTreeTraverse(node => node?.key ?? undefined, bst.getNode(6), IterationType.RECURSIVE, true)).toEqual([6, 5, 7]);
|
|
852
848
|
});
|
|
853
849
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {IterationType, RBTNColor,
|
|
2
|
-
import {getRandomInt} from '../../../utils';
|
|
1
|
+
import {IterationType, RBTNColor, RedBlackTree, RedBlackTreeNode} from '../../../../src';
|
|
2
|
+
import {getRandomInt, getRandomIntArray, magnitude} from '../../../utils';
|
|
3
3
|
import {isDebugTest} from '../../../config';
|
|
4
|
+
import {OrderedMap} from 'js-sdsl';
|
|
4
5
|
|
|
5
6
|
const isDebug = isDebugTest;
|
|
6
7
|
|
|
@@ -420,14 +421,10 @@ describe('RedBlackTree', () => {
|
|
|
420
421
|
isDebug && tree.print();
|
|
421
422
|
|
|
422
423
|
expect(tree.dfs()).toEqual([
|
|
423
|
-
1,
|
|
424
|
-
|
|
425
|
-
19, 22, 23, 25, 28, 33, 50, 110, 111,
|
|
426
|
-
155, 225
|
|
427
|
-
])
|
|
424
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 23, 25, 28, 33, 50, 110, 111, 155, 225
|
|
425
|
+
]);
|
|
428
426
|
|
|
429
427
|
expect(tree.isBST()).toBe(true);
|
|
430
|
-
|
|
431
428
|
});
|
|
432
429
|
|
|
433
430
|
it('should fix the tree after insertion and deletion', () => {
|
|
@@ -440,20 +437,14 @@ describe('RedBlackTree', () => {
|
|
|
440
437
|
|
|
441
438
|
expect(tree.size).toBe(51);
|
|
442
439
|
expect(tree.isBST()).toBe(true);
|
|
443
|
-
expect(tree.dfs(
|
|
444
|
-
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
|
452
|
-
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
|
|
453
|
-
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
|
|
454
|
-
82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
|
|
455
|
-
93, 94, 95, 96, 97, 98, 99
|
|
456
|
-
])
|
|
440
|
+
expect(tree.dfs(n => n.key, 'in', tree.root, IterationType.ITERATIVE)).toEqual([
|
|
441
|
+
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
|
|
442
|
+
82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
|
|
443
|
+
]);
|
|
444
|
+
expect(tree.dfs(n => n.key, 'in', tree.root, IterationType.RECURSIVE)).toEqual([
|
|
445
|
+
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
|
|
446
|
+
82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
|
|
447
|
+
]);
|
|
457
448
|
});
|
|
458
449
|
|
|
459
450
|
it('should fix the tree after large scale insertion and deletion', () => {
|
|
@@ -466,16 +457,34 @@ describe('RedBlackTree', () => {
|
|
|
466
457
|
|
|
467
458
|
expect(tree.size).toBe(0);
|
|
468
459
|
expect(tree.isBST()).toBe(true);
|
|
469
|
-
expect(tree.dfs(
|
|
460
|
+
expect(tree.dfs(n => n.key, 'in', tree.root, IterationType.ITERATIVE)).toEqual([]);
|
|
470
461
|
|
|
471
462
|
tree.clear();
|
|
472
463
|
for (let i = 0; i < 1000; i++) {
|
|
473
|
-
tree.add(getRandomInt(-100, 1000))
|
|
474
|
-
tree.delete(getRandomInt(-100, 1000))
|
|
464
|
+
tree.add(getRandomInt(-100, 1000));
|
|
465
|
+
tree.delete(getRandomInt(-100, 1000));
|
|
475
466
|
}
|
|
476
467
|
|
|
477
468
|
// TODO there is a bug when dfs the tree with NIL node
|
|
478
469
|
// expect(tree.isBST()).toBe(true);
|
|
479
470
|
});
|
|
471
|
+
const {HUNDRED_THOUSAND} = magnitude;
|
|
472
|
+
const arr = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND, true);
|
|
473
|
+
const competitor = new OrderedMap<number, number>();
|
|
474
|
+
|
|
475
|
+
it('should fix the tree after large scale insertion and deletion', () => {
|
|
476
|
+
tree.clear();
|
|
477
|
+
const tS = performance.now();
|
|
478
|
+
for (let i = 0; i < arr.length; i++) {
|
|
479
|
+
tree.add(arr[i]);
|
|
480
|
+
}
|
|
481
|
+
console.log(performance.now() - tS);
|
|
482
|
+
|
|
483
|
+
const cS = performance.now();
|
|
480
484
|
|
|
485
|
+
for (let i = 0; i < arr.length; i++) {
|
|
486
|
+
competitor.setElement(arr[i], arr[i]);
|
|
487
|
+
}
|
|
488
|
+
console.log(performance.now() - cS);
|
|
489
|
+
});
|
|
481
490
|
});
|
|
@@ -22,12 +22,12 @@ class MyEdge<E = any> extends AbstractEdge<E> {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
class MyGraph<
|
|
26
|
-
V
|
|
27
|
-
E
|
|
28
|
-
VO
|
|
29
|
-
EO
|
|
30
|
-
>
|
|
25
|
+
class MyGraph<V = any, E = any, VO extends MyVertex<V> = MyVertex<V>, EO extends MyEdge<E> = MyEdge<E>> extends AbstractGraph<
|
|
26
|
+
V,
|
|
27
|
+
E,
|
|
28
|
+
VO,
|
|
29
|
+
EO
|
|
30
|
+
> {
|
|
31
31
|
createVertex(key: VertexKey, value?: V): VO {
|
|
32
32
|
return new MyVertex(key, value) as VO;
|
|
33
33
|
}
|
|
@@ -126,12 +126,12 @@ class MyEdge<E = any> extends DirectedEdge<E> {
|
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
class MyDirectedGraph<
|
|
130
|
-
V
|
|
131
|
-
E
|
|
132
|
-
VO
|
|
133
|
-
EO
|
|
134
|
-
>
|
|
129
|
+
class MyDirectedGraph<V = any, E = any, VO extends MyVertex<V> = MyVertex<V>, EO extends MyEdge<E> = MyEdge<E>> extends DirectedGraph<
|
|
130
|
+
V,
|
|
131
|
+
E,
|
|
132
|
+
VO,
|
|
133
|
+
EO
|
|
134
|
+
> {
|
|
135
135
|
createVertex(key: VertexKey, value: V): VO {
|
|
136
136
|
return new MyVertex(key, value) as VO;
|
|
137
137
|
}
|
|
@@ -351,29 +351,9 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => {
|
|
|
351
351
|
expect(costs[2]).toEqual([3, 15, 38, 17, 35, Infinity, 64, Infinity, 22]);
|
|
352
352
|
expect(costs[3]).toEqual([123, 135, 120, 137, 155, Infinity, 47, Infinity, 126]);
|
|
353
353
|
expect(costs[4]).toEqual([133, 145, 130, 147, 165, Infinity, 57, Infinity, 136]);
|
|
354
|
-
expect(costs[5]).toEqual([
|
|
355
|
-
Infinity,
|
|
356
|
-
Infinity,
|
|
357
|
-
Infinity,
|
|
358
|
-
Infinity,
|
|
359
|
-
Infinity,
|
|
360
|
-
Infinity,
|
|
361
|
-
Infinity,
|
|
362
|
-
Infinity,
|
|
363
|
-
Infinity
|
|
364
|
-
]);
|
|
354
|
+
expect(costs[5]).toEqual([Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity]);
|
|
365
355
|
expect(costs[6]).toEqual([76, 88, 73, 90, 108, Infinity, 137, Infinity, 79]);
|
|
366
|
-
expect(costs[7]).toEqual([
|
|
367
|
-
Infinity,
|
|
368
|
-
Infinity,
|
|
369
|
-
Infinity,
|
|
370
|
-
Infinity,
|
|
371
|
-
Infinity,
|
|
372
|
-
Infinity,
|
|
373
|
-
Infinity,
|
|
374
|
-
Infinity,
|
|
375
|
-
Infinity
|
|
376
|
-
]);
|
|
356
|
+
expect(costs[7]).toEqual([Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity]);
|
|
377
357
|
expect(costs[8]).toEqual([173, 185, 170, 187, 205, Infinity, 97, Infinity, 176]);
|
|
378
358
|
|
|
379
359
|
expect(predecessor).toBeInstanceOf(Array);
|
|
@@ -45,14 +45,7 @@ describe('Heap Operation Test', () => {
|
|
|
45
45
|
maxHeap.add({key: 0, a: 'a0'});
|
|
46
46
|
maxHeap.add({key: 9, a: 'a9'});
|
|
47
47
|
expect(maxHeap.peek()).toEqual({a: 'a9', key: 9});
|
|
48
|
-
expect(maxHeap.toArray().map(item => ({a: item.a}))).toEqual([
|
|
49
|
-
{a: 'a9'},
|
|
50
|
-
{a: 'a2'},
|
|
51
|
-
{a: 'a6'},
|
|
52
|
-
{a: 'a1'},
|
|
53
|
-
{a: 'a0'},
|
|
54
|
-
{a: 'a5'}
|
|
55
|
-
]);
|
|
48
|
+
expect(maxHeap.toArray().map(item => ({a: item.a}))).toEqual([{a: 'a9'}, {a: 'a2'}, {a: 'a6'}, {a: 'a1'}, {a: 'a0'}, {a: 'a5'}]);
|
|
56
49
|
const maxExpectPolled = [{a: 'a9'}, {a: 'a6'}, {a: 'a5'}, {a: 'a2'}, {a: 'a1'}, {a: 'a0'}];
|
|
57
50
|
let maxI = 0;
|
|
58
51
|
while (maxHeap.size > 0) {
|