data-structure-typed 1.50.4 → 1.50.6
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 +116 -55
- package/SPECIFICATION.md +2 -2
- package/SPECIFICATION_zh-CN.md +81 -0
- package/{SPONSOR-zh-CN.md → SPONSOR_zh-CN.md} +1 -1
- package/benchmark/report.html +24 -24
- package/benchmark/report.json +261 -237
- package/dist/cjs/data-structures/base/iterable-base.d.ts +10 -8
- package/dist/cjs/data-structures/base/iterable-base.js +8 -12
- package/dist/cjs/data-structures/base/iterable-base.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +19 -19
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +158 -135
- package/dist/cjs/data-structures/binary-tree/rb-tree.js +415 -386
- 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 +1 -0
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +84 -76
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
- package/dist/cjs/data-structures/graph/abstract-graph.d.ts +1 -0
- package/dist/cjs/data-structures/graph/abstract-graph.js +3 -0
- package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
- package/dist/cjs/data-structures/heap/heap.js.map +1 -1
- package/dist/cjs/data-structures/linked-list/doubly-linked-list.d.ts +14 -76
- package/dist/cjs/data-structures/linked-list/doubly-linked-list.js +16 -86
- package/dist/cjs/data-structures/linked-list/doubly-linked-list.js.map +1 -1
- package/dist/cjs/data-structures/linked-list/singly-linked-list.d.ts +27 -69
- package/dist/cjs/data-structures/linked-list/singly-linked-list.js +35 -79
- package/dist/cjs/data-structures/linked-list/singly-linked-list.js.map +1 -1
- package/dist/cjs/data-structures/queue/deque.d.ts +0 -53
- package/dist/cjs/data-structures/queue/deque.js +0 -61
- package/dist/cjs/data-structures/queue/deque.js.map +1 -1
- package/dist/cjs/data-structures/queue/queue.d.ts +0 -70
- package/dist/cjs/data-structures/queue/queue.js +0 -87
- package/dist/cjs/data-structures/queue/queue.js.map +1 -1
- package/dist/mjs/data-structures/base/iterable-base.d.ts +10 -8
- package/dist/mjs/data-structures/base/iterable-base.js +8 -12
- package/dist/mjs/data-structures/binary-tree/binary-tree.js +19 -19
- package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +158 -135
- package/dist/mjs/data-structures/binary-tree/rb-tree.js +412 -386
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.d.ts +1 -0
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.js +84 -76
- package/dist/mjs/data-structures/graph/abstract-graph.d.ts +1 -0
- package/dist/mjs/data-structures/graph/abstract-graph.js +3 -0
- package/dist/mjs/data-structures/linked-list/doubly-linked-list.d.ts +14 -76
- package/dist/mjs/data-structures/linked-list/doubly-linked-list.js +16 -86
- package/dist/mjs/data-structures/linked-list/singly-linked-list.d.ts +27 -69
- package/dist/mjs/data-structures/linked-list/singly-linked-list.js +33 -79
- package/dist/mjs/data-structures/queue/deque.d.ts +0 -53
- package/dist/mjs/data-structures/queue/deque.js +0 -61
- package/dist/mjs/data-structures/queue/queue.d.ts +0 -70
- package/dist/mjs/data-structures/queue/queue.js +0 -86
- package/dist/umd/data-structure-typed.js +539 -756
- 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/base/iterable-base.ts +14 -10
- package/src/data-structures/binary-tree/binary-tree.ts +19 -19
- package/src/data-structures/binary-tree/rb-tree.ts +437 -395
- package/src/data-structures/binary-tree/tree-multi-map.ts +85 -82
- package/src/data-structures/graph/abstract-graph.ts +4 -0
- package/src/data-structures/heap/heap.ts +1 -1
- package/src/data-structures/linked-list/doubly-linked-list.ts +16 -94
- package/src/data-structures/linked-list/singly-linked-list.ts +35 -87
- package/src/data-structures/queue/deque.ts +0 -67
- package/src/data-structures/queue/queue.ts +0 -98
- package/test/performance/data-structures/binary-tree/avl-tree.test.ts +3 -3
- package/test/performance/data-structures/binary-tree/binary-tree-overall.test.ts +3 -3
- package/test/performance/data-structures/binary-tree/rb-tree.test.ts +26 -16
- package/test/performance/data-structures/hash/hash-map.test.ts +6 -6
- package/test/performance/data-structures/heap/heap.test.ts +14 -14
- package/test/performance/data-structures/priority-queue/priority-queue.test.ts +11 -6
- package/test/performance/data-structures/queue/deque.test.ts +8 -8
- package/test/performance/data-structures/queue/queue.test.ts +5 -12
- package/test/performance/reportor.ts +43 -1
- package/test/unit/data-structures/binary-tree/overall.test.ts +23 -21
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +168 -105
- package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +311 -192
- package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +6 -6
- package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +10 -10
- package/test/unit/data-structures/linked-list/skip-list.test.ts +4 -4
- package/test/unit/data-structures/queue/deque.test.ts +26 -26
- package/test/unit/data-structures/queue/queue.test.ts +20 -20
|
@@ -178,72 +178,6 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|
|
178
178
|
return spliced.length === 1;
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
/**
|
|
182
|
-
* Time Complexity: O(1)
|
|
183
|
-
* Space Complexity: O(1)
|
|
184
|
-
*/
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Time Complexity: O(1)
|
|
188
|
-
* Space Complexity: O(1)
|
|
189
|
-
*
|
|
190
|
-
* The `peek` function returns the first element of the array `_elements` if it exists, otherwise it returns `undefined`.
|
|
191
|
-
* @returns The `peek()` method returns the first element of the data structure, represented by the `_elements` array at
|
|
192
|
-
* the `_offset` index. If the data structure is empty (size is 0), it returns `undefined`.
|
|
193
|
-
*/
|
|
194
|
-
peek(): E | undefined {
|
|
195
|
-
return this.first;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Time Complexity: O(1)
|
|
200
|
-
* Space Complexity: O(1)
|
|
201
|
-
*/
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Time Complexity: O(1)
|
|
205
|
-
* Space Complexity: O(1)
|
|
206
|
-
*
|
|
207
|
-
* The `peekLast` function returns the last element in an array-like data structure, or undefined if the structure is empty.
|
|
208
|
-
* @returns The method `peekLast()` returns the last element of the `_elements` array if the array is not empty. If the
|
|
209
|
-
* array is empty, it returns `undefined`.
|
|
210
|
-
*/
|
|
211
|
-
peekLast(): E | undefined {
|
|
212
|
-
return this.last;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Time Complexity: O(1)
|
|
217
|
-
* Space Complexity: O(1)
|
|
218
|
-
*/
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Time Complexity: O(1)
|
|
222
|
-
* Space Complexity: O(1)
|
|
223
|
-
*
|
|
224
|
-
* The enqueue function adds a value to the end of a queue.
|
|
225
|
-
* @param {E} value - The value parameter represents the value that you want to add to the queue.
|
|
226
|
-
*/
|
|
227
|
-
enqueue(value: E): boolean {
|
|
228
|
-
return this.push(value);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Time Complexity: O(1)
|
|
233
|
-
* Space Complexity: O(1)
|
|
234
|
-
*/
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Time Complexity: O(1)
|
|
238
|
-
* Space Complexity: O(1)
|
|
239
|
-
*
|
|
240
|
-
* The `dequeue` function removes and returns the first element from a queue, or returns undefined if the queue is empty.
|
|
241
|
-
* @returns The method is returning a value of type E or undefined.
|
|
242
|
-
*/
|
|
243
|
-
dequeue(): E | undefined {
|
|
244
|
-
return this.shift();
|
|
245
|
-
}
|
|
246
|
-
|
|
247
181
|
/**
|
|
248
182
|
* Time Complexity: O(1)
|
|
249
183
|
* Space Complexity: O(1)
|
|
@@ -411,38 +345,6 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|
|
411
345
|
* 4. Frequent Enqueuing and Dequeuing Operations: If your application involves frequent enqueuing and dequeuing operations and is less concerned with random access, then LinkedListQueue is a good choice.
|
|
412
346
|
*/
|
|
413
347
|
export class LinkedListQueue<E = any> extends SinglyLinkedList<E> {
|
|
414
|
-
/**
|
|
415
|
-
* The `get first` function returns the value of the head node in a linked list, or `undefined` if the list is empty.
|
|
416
|
-
* @returns The `get first()` method is returning the value of the `head` node if it exists, otherwise it returns `undefined`.
|
|
417
|
-
*/
|
|
418
|
-
get first(): E | undefined {
|
|
419
|
-
return this.head?.value;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
/**
|
|
423
|
-
* The enqueue function adds a value to the end of an array.
|
|
424
|
-
* @param {E} value - The value parameter represents the value that you want to add to the queue.
|
|
425
|
-
*/
|
|
426
|
-
enqueue(value: E): boolean {
|
|
427
|
-
return this.push(value);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
/**
|
|
431
|
-
* The `dequeue` function removes and returns the first element from a queue, or returns undefined if the queue is empty.
|
|
432
|
-
* @returns The method is returning the element at the front of the queue, or undefined if the queue is empty.
|
|
433
|
-
*/
|
|
434
|
-
dequeue(): E | undefined {
|
|
435
|
-
return this.shift();
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
/**
|
|
439
|
-
* The `peek` function returns the value of the head node in a linked list, or `undefined` if the list is empty.
|
|
440
|
-
* @returns The `peek()` method is returning the value of the `head` node if it exists, otherwise it returns `undefined`.
|
|
441
|
-
*/
|
|
442
|
-
peek(): E | undefined {
|
|
443
|
-
return this.first;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
348
|
/**
|
|
447
349
|
* Time Complexity: O(n)
|
|
448
350
|
* Space Complexity: O(n)
|
|
@@ -12,6 +12,9 @@ suite
|
|
|
12
12
|
avl.clear();
|
|
13
13
|
for (let i = 0; i < arr.length; i++) avl.add(arr[i]);
|
|
14
14
|
})
|
|
15
|
+
.add(`${TEN_THOUSAND.toLocaleString()} get`, () => {
|
|
16
|
+
for (let i = 0; i < arr.length; i++) avl.get(arr[i]);
|
|
17
|
+
})
|
|
15
18
|
.add(`${TEN_THOUSAND.toLocaleString()} add & delete randomly`, () => {
|
|
16
19
|
avl.clear();
|
|
17
20
|
for (let i = 0; i < arr.length; i++) avl.add(arr[i]);
|
|
@@ -20,9 +23,6 @@ suite
|
|
|
20
23
|
.add(`${TEN_THOUSAND.toLocaleString()} addMany`, () => {
|
|
21
24
|
avl.clear();
|
|
22
25
|
avl.addMany(arr);
|
|
23
|
-
})
|
|
24
|
-
.add(`${TEN_THOUSAND.toLocaleString()} get`, () => {
|
|
25
|
-
for (let i = 0; i < arr.length; i++) avl.get(arr[i]);
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
export { suite };
|
|
@@ -25,13 +25,13 @@ suite
|
|
|
25
25
|
avlTree.clear();
|
|
26
26
|
for (let i = 0; i < arr.length; i++) avlTree.add(arr[i]);
|
|
27
27
|
})
|
|
28
|
+
.add(`${TEN_THOUSAND.toLocaleString()} AVLTree get`, () => {
|
|
29
|
+
for (let i = 0; i < arr.length; i++) avlTree.get(arr[i]);
|
|
30
|
+
})
|
|
28
31
|
.add(`${TEN_THOUSAND.toLocaleString()} AVLTree add & delete randomly`, () => {
|
|
29
32
|
avlTree.clear();
|
|
30
33
|
for (let i = 0; i < arr.length; i++) avlTree.add(arr[i]);
|
|
31
34
|
for (let i = 0; i < arr.length; i++) avlTree.delete(arr[i]);
|
|
32
|
-
})
|
|
33
|
-
.add(`${TEN_THOUSAND.toLocaleString()} AVLTree get`, () => {
|
|
34
|
-
for (let i = 0; i < arr.length; i++) avlTree.get(arr[i]);
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
export { suite };
|
|
@@ -7,33 +7,43 @@ import { isCompetitor } from '../../../config';
|
|
|
7
7
|
const suite = new Benchmark.Suite();
|
|
8
8
|
const rbTree = new RedBlackTree();
|
|
9
9
|
const { HUNDRED_THOUSAND } = magnitude;
|
|
10
|
-
const
|
|
10
|
+
const randomArray = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND - 1, true);
|
|
11
11
|
const cOrderedMap = new OrderedMap<number, number>();
|
|
12
12
|
|
|
13
|
-
suite
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
})
|
|
13
|
+
suite
|
|
14
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add orderly`, () => {
|
|
15
|
+
for (let i = 0; i < randomArray.length; i++) rbTree.add(i);
|
|
16
|
+
})
|
|
17
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} delete orderly`, () => {
|
|
18
|
+
for (let i = 0; i < randomArray.length; i++) rbTree.delete(i);
|
|
19
|
+
})
|
|
20
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add randomly`, () => {
|
|
21
|
+
rbTree.clear();
|
|
22
|
+
for (let i = 0; i < randomArray.length; i++) rbTree.add(randomArray[i]);
|
|
23
|
+
})
|
|
24
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} delete randomly`, () => {
|
|
25
|
+
for (let i = 0; i < randomArray.length; i++) rbTree.delete(randomArray[i]);
|
|
26
|
+
})
|
|
27
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add orderly`, () => {
|
|
28
|
+
for (let i = 0; i < randomArray.length; i++) rbTree.add(i);
|
|
29
|
+
})
|
|
30
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} delete randomly`, () => {
|
|
31
|
+
for (let i = 0; i < randomArray.length; i++) rbTree.delete(randomArray[i]);
|
|
32
|
+
});
|
|
17
33
|
|
|
18
34
|
if (isCompetitor) {
|
|
19
35
|
suite.add(`CPT ${HUNDRED_THOUSAND.toLocaleString()} add`, () => {
|
|
20
|
-
for (let i = 0; i <
|
|
36
|
+
for (let i = 0; i < randomArray.length; i++) cOrderedMap.setElement(randomArray[i], randomArray[i]);
|
|
21
37
|
});
|
|
22
38
|
}
|
|
23
39
|
|
|
24
|
-
suite
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
for (let i = 0; i < arr.length; i++) rbTree.add(arr[i]);
|
|
28
|
-
for (let i = 0; i < arr.length; i++) rbTree.delete(arr[i]);
|
|
29
|
-
})
|
|
30
|
-
.add(`${HUNDRED_THOUSAND.toLocaleString()} getNode`, () => {
|
|
31
|
-
for (let i = 0; i < arr.length; i++) rbTree.getNode(arr[i]);
|
|
32
|
-
});
|
|
40
|
+
suite.add(`${HUNDRED_THOUSAND.toLocaleString()} getNode randomly`, () => {
|
|
41
|
+
for (let i = 0; i < randomArray.length; i++) rbTree.getNode(randomArray[i]);
|
|
42
|
+
});
|
|
33
43
|
|
|
34
44
|
suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add & iterator`, () => {
|
|
35
45
|
rbTree.clear();
|
|
36
|
-
for (let i = 0; i <
|
|
46
|
+
for (let i = 0; i < randomArray.length; i++) rbTree.add(randomArray[i]);
|
|
37
47
|
const entries = [...rbTree];
|
|
38
48
|
return entries.length === HUNDRED_THOUSAND;
|
|
39
49
|
});
|
|
@@ -21,13 +21,13 @@ if (isCompetitor) {
|
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
suite.add(`Native Map ${MILLION.toLocaleString()} set`, () => {
|
|
24
|
+
suite.add(`Native JS Map ${MILLION.toLocaleString()} set`, () => {
|
|
25
25
|
const hm = new Map<number, number>();
|
|
26
26
|
|
|
27
27
|
for (let i = 0; i < MILLION; i++) hm.set(i, i);
|
|
28
28
|
});
|
|
29
29
|
|
|
30
|
-
suite.add(`Native Set ${MILLION.toLocaleString()} add`, () => {
|
|
30
|
+
suite.add(`Native JS Set ${MILLION.toLocaleString()} add`, () => {
|
|
31
31
|
const hs = new Set<number>();
|
|
32
32
|
|
|
33
33
|
for (let i = 0; i < MILLION; i++) hs.add(i);
|
|
@@ -49,14 +49,14 @@ if (isCompetitor) {
|
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
suite.add(`Native Map ${MILLION.toLocaleString()} set & get`, () => {
|
|
52
|
+
suite.add(`Native JS Map ${MILLION.toLocaleString()} set & get`, () => {
|
|
53
53
|
const hm = new Map<number, number>();
|
|
54
54
|
|
|
55
55
|
for (let i = 0; i < MILLION; i++) hm.set(i, i);
|
|
56
56
|
for (let i = 0; i < MILLION; i++) hm.get(i);
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
suite.add(`Native Set ${MILLION.toLocaleString()} add & has`, () => {
|
|
59
|
+
suite.add(`Native JS Set ${MILLION.toLocaleString()} add & has`, () => {
|
|
60
60
|
const hs = new Set<number>();
|
|
61
61
|
|
|
62
62
|
for (let i = 0; i < MILLION; i++) hs.add(i);
|
|
@@ -74,7 +74,7 @@ suite.add(`${MILLION.toLocaleString()} ObjKey set & get`, () => {
|
|
|
74
74
|
for (let i = 0; i < MILLION; i++) hm.get(objKeys[i]);
|
|
75
75
|
});
|
|
76
76
|
|
|
77
|
-
suite.add(`Native Map ${MILLION.toLocaleString()} ObjKey set & get`, () => {
|
|
77
|
+
suite.add(`Native JS Map ${MILLION.toLocaleString()} ObjKey set & get`, () => {
|
|
78
78
|
const hm = new Map<[number, number], number>();
|
|
79
79
|
const objs: [number, number][] = [];
|
|
80
80
|
for (let i = 0; i < MILLION; i++) {
|
|
@@ -85,7 +85,7 @@ suite.add(`Native Map ${MILLION.toLocaleString()} ObjKey set & get`, () => {
|
|
|
85
85
|
for (let i = 0; i < MILLION; i++) hm.get(objs[i]);
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
-
suite.add(`Native Set ${MILLION.toLocaleString()} ObjKey add & has`, () => {
|
|
88
|
+
suite.add(`Native JS Set ${MILLION.toLocaleString()} ObjKey add & has`, () => {
|
|
89
89
|
const hs = new Set<[number, number]>();
|
|
90
90
|
const objs: [number, number][] = [];
|
|
91
91
|
for (let i = 0; i < MILLION; i++) {
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Heap } from '../../../../src';
|
|
2
2
|
import * as Benchmark from 'benchmark';
|
|
3
|
-
import { magnitude } from '../../../utils';
|
|
3
|
+
import { getRandomInt, magnitude } from '../../../utils';
|
|
4
4
|
|
|
5
5
|
const suite = new Benchmark.Suite();
|
|
6
|
-
const { HUNDRED_THOUSAND
|
|
6
|
+
const { HUNDRED_THOUSAND } = magnitude;
|
|
7
|
+
const indicesHT = new Array(HUNDRED_THOUSAND).fill(0).map(() => getRandomInt(0, HUNDRED_THOUSAND - 1));
|
|
7
8
|
|
|
8
9
|
suite
|
|
10
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add`, () => {
|
|
11
|
+
const heap = new Heap<number>([], { comparator: (a, b) => b - a });
|
|
12
|
+
for (let i = 0; i < HUNDRED_THOUSAND; i++) heap.add(indicesHT[i]);
|
|
13
|
+
})
|
|
9
14
|
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & poll`, () => {
|
|
10
15
|
const heap = new Heap<number>([], { comparator: (a, b) => b - a });
|
|
11
16
|
|
|
12
|
-
for (let i = 0; i < HUNDRED_THOUSAND; i++) heap.add(i);
|
|
17
|
+
for (let i = 0; i < HUNDRED_THOUSAND; i++) heap.add(indicesHT[i]);
|
|
13
18
|
for (let i = 0; i < HUNDRED_THOUSAND; i++) heap.poll();
|
|
14
|
-
})
|
|
15
|
-
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & dfs`, () => {
|
|
16
|
-
const heap = new Heap<number>([], { comparator: (a, b) => b - a });
|
|
17
|
-
for (let i = 0; i < HUNDRED_THOUSAND; i++) heap.add(i);
|
|
18
|
-
heap.dfs();
|
|
19
|
-
})
|
|
20
|
-
.add(`${TEN_THOUSAND.toLocaleString()} fib add & pop`, () => {
|
|
21
|
-
const fbHeap = new FibonacciHeap<number>();
|
|
22
|
-
for (let i = 1; i <= TEN_THOUSAND; i++) fbHeap.push(i);
|
|
23
|
-
for (let i = 1; i <= TEN_THOUSAND; i++) fbHeap.pop();
|
|
24
19
|
});
|
|
20
|
+
// .add(`${TEN_THOUSAND.toLocaleString()} fib add & pop`, () => {
|
|
21
|
+
// const fbHeap = new FibonacciHeap<number>();
|
|
22
|
+
// for (let i = 1; i <= TEN_THOUSAND; i++) fbHeap.push(i);
|
|
23
|
+
// for (let i = 1; i <= TEN_THOUSAND; i++) fbHeap.pop();
|
|
24
|
+
// });
|
|
25
25
|
|
|
26
26
|
export { suite };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PriorityQueue as CPriorityQueue } from 'js-sdsl';
|
|
2
1
|
import { PriorityQueue } from '../../../../src';
|
|
2
|
+
import { PriorityQueue as CPriorityQueue } from 'js-sdsl';
|
|
3
3
|
import * as Benchmark from 'benchmark';
|
|
4
4
|
import { magnitude } from '../../../utils';
|
|
5
5
|
import { isCompetitor } from '../../../config';
|
|
@@ -7,12 +7,17 @@ import { isCompetitor } from '../../../config';
|
|
|
7
7
|
const suite = new Benchmark.Suite();
|
|
8
8
|
const { HUNDRED_THOUSAND } = magnitude;
|
|
9
9
|
|
|
10
|
-
suite
|
|
11
|
-
|
|
10
|
+
suite
|
|
11
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add`, () => {
|
|
12
|
+
const heap = new PriorityQueue<number>([], { comparator: (a, b) => b - a });
|
|
13
|
+
for (let i = 0; i < HUNDRED_THOUSAND; i++) heap.add(i);
|
|
14
|
+
})
|
|
15
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & poll`, () => {
|
|
16
|
+
const heap = new PriorityQueue<number>([], { comparator: (a, b) => b - a });
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
});
|
|
18
|
+
for (let i = 0; i < HUNDRED_THOUSAND; i++) heap.add(i);
|
|
19
|
+
for (let i = 0; i < HUNDRED_THOUSAND; i++) heap.poll();
|
|
20
|
+
});
|
|
16
21
|
if (isCompetitor) {
|
|
17
22
|
suite.add(`CPT ${HUNDRED_THOUSAND.toLocaleString()} add & pop`, () => {
|
|
18
23
|
const pq = new CPriorityQueue<number>();
|
|
@@ -21,25 +21,25 @@ if (isCompetitor) {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
suite
|
|
24
|
-
// .add(`${TEN_THOUSAND.toLocaleString()} push & delete`, () => {
|
|
25
|
-
// const deque = new Deque<number>();
|
|
26
|
-
//
|
|
27
|
-
// for (let i = 0; i < TEN_THOUSAND; i++) deque.push(i);
|
|
28
|
-
// for (let i = 0; i < TEN_THOUSAND; i++) deque.delete(randomIndicesTenThousand[i]);
|
|
29
|
-
// })
|
|
30
24
|
.add(`${MILLION.toLocaleString()} push & pop`, () => {
|
|
31
25
|
const deque = new Deque<number>();
|
|
32
26
|
|
|
33
27
|
for (let i = 0; i < MILLION; i++) deque.push(i);
|
|
34
28
|
for (let i = 0; i < MILLION; i++) deque.pop();
|
|
35
29
|
})
|
|
30
|
+
.add(`${MILLION.toLocaleString()} push & shift`, () => {
|
|
31
|
+
const deque = new Deque<number>();
|
|
32
|
+
|
|
33
|
+
for (let i = 0; i < MILLION; i++) deque.push(i);
|
|
34
|
+
for (let i = 0; i < MILLION; i++) deque.shift();
|
|
35
|
+
})
|
|
36
36
|
.add(`${HUNDRED_THOUSAND.toLocaleString()} push & shift`, () => {
|
|
37
37
|
const deque = new Deque<number>();
|
|
38
38
|
|
|
39
39
|
for (let i = 0; i < HUNDRED_THOUSAND; i++) deque.push(i);
|
|
40
40
|
for (let i = 0; i < HUNDRED_THOUSAND; i++) deque.shift();
|
|
41
41
|
})
|
|
42
|
-
.add(`Native Array ${HUNDRED_THOUSAND.toLocaleString()} push & shift`, () => {
|
|
42
|
+
.add(`Native JS Array ${HUNDRED_THOUSAND.toLocaleString()} push & shift`, () => {
|
|
43
43
|
const array = new Array<number>();
|
|
44
44
|
|
|
45
45
|
for (let i = 0; i < HUNDRED_THOUSAND; i++) array.push(i);
|
|
@@ -51,7 +51,7 @@ suite
|
|
|
51
51
|
for (let i = 0; i < HUNDRED_THOUSAND; i++) deque.unshift(i);
|
|
52
52
|
for (let i = 0; i < HUNDRED_THOUSAND; i++) deque.shift();
|
|
53
53
|
})
|
|
54
|
-
.add(`Native Array ${HUNDRED_THOUSAND.toLocaleString()} unshift & shift`, () => {
|
|
54
|
+
.add(`Native JS Array ${HUNDRED_THOUSAND.toLocaleString()} unshift & shift`, () => {
|
|
55
55
|
const array = new Array<number>();
|
|
56
56
|
|
|
57
57
|
for (let i = 0; i < HUNDRED_THOUSAND; i++) array.unshift(i);
|
|
@@ -25,18 +25,11 @@ suite.add(`${HUNDRED_THOUSAND.toLocaleString()} push & shift`, () => {
|
|
|
25
25
|
for (let i = 0; i < HUNDRED_THOUSAND; i++) queue.push(i);
|
|
26
26
|
for (let i = 0; i < HUNDRED_THOUSAND; i++) queue.shift();
|
|
27
27
|
});
|
|
28
|
-
suite
|
|
29
|
-
|
|
30
|
-
const arr = new Array<number>();
|
|
28
|
+
suite.add(`Native JS Array ${HUNDRED_THOUSAND.toLocaleString()} push & shift`, () => {
|
|
29
|
+
const arr = new Array<number>();
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
.add(`Native Array ${HUNDRED_THOUSAND.toLocaleString()} push & pop`, () => {
|
|
36
|
-
const arr = new Array<number>();
|
|
37
|
-
|
|
38
|
-
for (let i = 0; i < HUNDRED_THOUSAND; i++) arr.push(i);
|
|
39
|
-
for (let i = 0; i < HUNDRED_THOUSAND; i++) arr.pop();
|
|
40
|
-
});
|
|
31
|
+
for (let i = 0; i < HUNDRED_THOUSAND; i++) arr.push(i);
|
|
32
|
+
for (let i = 0; i < HUNDRED_THOUSAND; i++) arr.shift();
|
|
33
|
+
});
|
|
41
34
|
|
|
42
35
|
export { suite };
|
|
@@ -4,6 +4,7 @@ import * as fs from 'fs';
|
|
|
4
4
|
import * as fastGlob from 'fast-glob';
|
|
5
5
|
import { Color, numberFix, render } from '../utils';
|
|
6
6
|
import { PerformanceTest } from './types';
|
|
7
|
+
import * as console from 'console';
|
|
7
8
|
|
|
8
9
|
const args = process.argv.slice(2);
|
|
9
10
|
|
|
@@ -171,7 +172,48 @@ function replaceMarkdownContent(startMarker: string, endMarker: string, newText:
|
|
|
171
172
|
});
|
|
172
173
|
}
|
|
173
174
|
|
|
174
|
-
|
|
175
|
+
const order = [
|
|
176
|
+
'heap',
|
|
177
|
+
'rb-tree',
|
|
178
|
+
'queue',
|
|
179
|
+
'deque',
|
|
180
|
+
'hash-map',
|
|
181
|
+
'trie',
|
|
182
|
+
'avl-tree',
|
|
183
|
+
'binary-tree-overall',
|
|
184
|
+
'directed-graph',
|
|
185
|
+
'doubly-linked-list',
|
|
186
|
+
'singly-linked-list',
|
|
187
|
+
'priority-queue',
|
|
188
|
+
'stack'
|
|
189
|
+
];
|
|
190
|
+
|
|
191
|
+
const sortedPerformanceTests = [...performanceTests].sort((a, b) => {
|
|
192
|
+
const indexA = order.indexOf(a.testName);
|
|
193
|
+
const indexB = order.indexOf(b.testName);
|
|
194
|
+
|
|
195
|
+
// If both a and b are in the order, sort them according to their indices in the order.
|
|
196
|
+
if (indexA !== -1 && indexB !== -1) {
|
|
197
|
+
return indexA - indexB;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// If there is only 'a' in the order, then place 'b' in front.
|
|
201
|
+
if (indexA !== -1) {
|
|
202
|
+
return 1;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// If only b is in the order, then a should be placed before it.
|
|
206
|
+
if (indexB !== -1) {
|
|
207
|
+
return -1;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// If neither a nor b are in order, keep their original order
|
|
211
|
+
return 0;
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
console.log(`${GREEN} Found tests${END}: ${sortedPerformanceTests.map(test => test.testName)}`);
|
|
215
|
+
|
|
216
|
+
sortedPerformanceTests.forEach(item => {
|
|
175
217
|
const { suite, testName, file } = item;
|
|
176
218
|
|
|
177
219
|
console.log(coloredLabeled('Running', file));
|
|
@@ -158,40 +158,41 @@ describe('Overall BinaryTree Test', () => {
|
|
|
158
158
|
tmm.add(5);
|
|
159
159
|
tmm.add(4);
|
|
160
160
|
expect(tmm.count).toBe(10);
|
|
161
|
-
expect(tmm.root?.key).toBe(
|
|
161
|
+
expect(tmm.root?.key).toBe(3);
|
|
162
162
|
expect(tmm.root?.left?.key).toBe(1);
|
|
163
163
|
expect(tmm.root?.left?.left?.key).toBe(NaN);
|
|
164
164
|
expect(tmm.root?.right?.key).toBe(7);
|
|
165
|
-
expect(tmm.root?.right?.left?.key).toBe(
|
|
166
|
-
expect(tmm.getNodeByKey(7)?.left?.key).toBe(
|
|
167
|
-
expect(tmm.getHeight()).toBe(
|
|
165
|
+
expect(tmm.root?.right?.left?.key).toBe(5);
|
|
166
|
+
expect(tmm.getNodeByKey(7)?.left?.key).toBe(5);
|
|
167
|
+
expect(tmm.getHeight()).toBe(3);
|
|
168
168
|
expect(tmm.has(9)).toBe(true);
|
|
169
169
|
expect(tmm.has(7)).toBe(true);
|
|
170
170
|
expect(tmm.delete(7)[0].deleted?.key).toBe(7);
|
|
171
171
|
expect(tmm.has(7)).toBe(false);
|
|
172
172
|
expect(tmm.size).toBe(7);
|
|
173
173
|
expect(tmm.count).toBe(9);
|
|
174
|
-
expect(tmm.root?.key).toBe(
|
|
174
|
+
expect(tmm.root?.key).toBe(3);
|
|
175
175
|
expect(tmm.root?.left?.key).toBe(1);
|
|
176
176
|
expect(tmm.root?.right?.key).toBe(9);
|
|
177
|
-
expect(tmm.root?.right?.left?.key).toBe(
|
|
178
|
-
expect(tmm.getNodeByKey(6)?.left?.key).toBe(
|
|
179
|
-
expect(tmm.getHeight()).toBe(
|
|
177
|
+
expect(tmm.root?.right?.left?.key).toBe(5);
|
|
178
|
+
expect(tmm.getNodeByKey(6)?.left?.key).toBe(NaN);
|
|
179
|
+
expect(tmm.getHeight()).toBe(3);
|
|
180
180
|
expect(tmm.has(9)).toBe(true);
|
|
181
181
|
expect(tmm.has(7)).toBe(false);
|
|
182
|
-
expect(tmm.bfs()).toEqual([
|
|
182
|
+
expect(tmm.bfs()).toEqual([3, 1, 9, 2, 5, 4, 6]);
|
|
183
|
+
// expect(tmm.bfs()).toEqual([6, 1, 9, 3, 2, 5, 4]);
|
|
183
184
|
const clonedTMM = tmm.clone();
|
|
184
185
|
expect(clonedTMM.size).toBe(7);
|
|
185
186
|
expect(clonedTMM.count).toBe(9);
|
|
186
|
-
expect(clonedTMM.root?.key).toBe(
|
|
187
|
+
expect(clonedTMM.root?.key).toBe(3);
|
|
187
188
|
expect(clonedTMM.root?.left?.key).toBe(1);
|
|
188
|
-
expect(clonedTMM.root?.right?.key).toBe(
|
|
189
|
-
expect(clonedTMM.root?.right?.left?.key).toBe(
|
|
190
|
-
expect(clonedTMM.getNodeByKey(6)?.left?.key).toBe(
|
|
191
|
-
expect(clonedTMM.getHeight()).toBe(
|
|
189
|
+
expect(clonedTMM.root?.right?.key).toBe(5);
|
|
190
|
+
expect(clonedTMM.root?.right?.left?.key).toBe(4);
|
|
191
|
+
expect(clonedTMM.getNodeByKey(6)?.left?.key).toBe(NaN);
|
|
192
|
+
expect(clonedTMM.getHeight()).toBe(3);
|
|
192
193
|
expect(clonedTMM.has(9)).toBe(true);
|
|
193
194
|
expect(clonedTMM.has(7)).toBe(false);
|
|
194
|
-
expect(clonedTMM.bfs()).toEqual([
|
|
195
|
+
expect(clonedTMM.bfs()).toEqual([3, 1, 5, 2, 4, 9, 6]);
|
|
195
196
|
});
|
|
196
197
|
|
|
197
198
|
it('Should clone a RedBlackTree works fine', () => {
|
|
@@ -211,7 +212,7 @@ describe('Overall BinaryTree Test', () => {
|
|
|
211
212
|
expect(rbTree.root?.right?.key).toBe(7);
|
|
212
213
|
expect(rbTree.root?.right?.left?.key).toBe(5);
|
|
213
214
|
expect(rbTree.getNodeByKey(7)?.left?.key).toBe(5);
|
|
214
|
-
expect(rbTree.getHeight()).toBe(
|
|
215
|
+
expect(rbTree.getHeight()).toBe(3);
|
|
215
216
|
expect(rbTree.has(9)).toBe(true);
|
|
216
217
|
expect(rbTree.has(7)).toBe(true);
|
|
217
218
|
expect(rbTree.delete(7)?.[0]?.deleted?.key).toBe(7);
|
|
@@ -219,13 +220,14 @@ describe('Overall BinaryTree Test', () => {
|
|
|
219
220
|
expect(rbTree.size).toBe(7);
|
|
220
221
|
expect(rbTree.root?.key).toBe(3);
|
|
221
222
|
expect(rbTree.root?.left?.key).toBe(1);
|
|
222
|
-
expect(rbTree.root?.right?.key).toBe(
|
|
223
|
-
expect(rbTree.root?.right?.left?.key).toBe(
|
|
223
|
+
expect(rbTree.root?.right?.key).toBe(9);
|
|
224
|
+
expect(rbTree.root?.right?.left?.key).toBe(5);
|
|
224
225
|
expect(rbTree.getNodeByKey(6)?.left?.key).toBe(NaN);
|
|
225
|
-
expect(rbTree.getHeight()).toBe(
|
|
226
|
+
expect(rbTree.getHeight()).toBe(3);
|
|
226
227
|
expect(rbTree.has(9)).toBe(true);
|
|
227
228
|
expect(rbTree.has(7)).toBe(false);
|
|
228
|
-
expect(rbTree.bfs()).toEqual([3, 1, 5, 2, 4, 9, 6]);
|
|
229
|
+
// expect(rbTree.bfs()).toEqual([3, 1, 5, 2, 4, 9, 6]);
|
|
230
|
+
expect(rbTree.bfs()).toEqual([3, 1, 9, 2, 5, 4, 6]);
|
|
229
231
|
const clonedRbTree = rbTree.clone();
|
|
230
232
|
expect(clonedRbTree.size).toBe(7);
|
|
231
233
|
expect(clonedRbTree.root?.key).toBe(3);
|
|
@@ -233,7 +235,7 @@ describe('Overall BinaryTree Test', () => {
|
|
|
233
235
|
expect(clonedRbTree.root?.right?.key).toBe(5);
|
|
234
236
|
expect(clonedRbTree.root?.right?.left?.key).toBe(4);
|
|
235
237
|
expect(clonedRbTree.getNodeByKey(6)?.left?.key).toBe(NaN);
|
|
236
|
-
expect(clonedRbTree.getHeight()).toBe(
|
|
238
|
+
expect(clonedRbTree.getHeight()).toBe(3);
|
|
237
239
|
expect(clonedRbTree.has(9)).toBe(true);
|
|
238
240
|
expect(clonedRbTree.has(7)).toBe(false);
|
|
239
241
|
expect(clonedRbTree.bfs()).toEqual([3, 1, 5, 2, 4, 9, 6]);
|