data-structure-typed 2.1.2 → 2.2.1
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/CONTRIBUTING.md +4 -0
- package/README.md +66 -21
- package/benchmark/report.html +1 -1
- package/benchmark/report.json +145 -169
- package/dist/cjs/index.cjs +1173 -583
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +13623 -0
- package/dist/cjs-legacy/index.cjs.map +1 -0
- package/dist/esm/index.mjs +1173 -583
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +13545 -0
- package/dist/esm-legacy/index.mjs.map +1 -0
- package/dist/types/data-structures/binary-tree/avl-tree-counter.d.ts +57 -3
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +65 -3
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +61 -5
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -0
- package/dist/types/data-structures/binary-tree/bst.d.ts +58 -3
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +59 -4
- package/dist/types/data-structures/binary-tree/tree-counter.d.ts +57 -3
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +66 -3
- package/dist/types/types/data-structures/base/base.d.ts +1 -1
- package/dist/umd/data-structure-typed.js +614 -53
- package/dist/umd/data-structure-typed.js.map +1 -1
- package/dist/umd/data-structure-typed.min.js +3 -3
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +20 -2
- package/src/data-structures/base/iterable-entry-base.ts +4 -4
- package/src/data-structures/binary-tree/avl-tree-counter.ts +103 -12
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +116 -12
- package/src/data-structures/binary-tree/avl-tree.ts +109 -16
- package/src/data-structures/binary-tree/binary-tree.ts +3 -2
- package/src/data-structures/binary-tree/bst.ts +104 -12
- package/src/data-structures/binary-tree/red-black-tree.ts +110 -19
- package/src/data-structures/binary-tree/tree-counter.ts +102 -11
- package/src/data-structures/binary-tree/tree-multi-map.ts +124 -12
- package/src/data-structures/graph/abstract-graph.ts +8 -8
- package/src/data-structures/graph/directed-graph.ts +5 -5
- package/src/data-structures/graph/undirected-graph.ts +5 -5
- package/src/data-structures/hash/hash-map.ts +4 -4
- package/src/types/data-structures/base/base.ts +1 -1
- package/test/performance/data-structures/binary-tree/red-black-tree.test.ts +39 -36
- package/test/performance/runner-config.json +4 -4
- package/test/unit/data-structures/binary-tree/avl-tree-counter.test.ts +8 -7
- package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +3 -3
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +6 -6
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +4 -4
- package/test/unit/data-structures/binary-tree/bst.test.ts +5 -5
- package/test/unit/data-structures/binary-tree/red-black-tree.test.ts +6 -6
- package/test/unit/data-structures/binary-tree/tree-counter.test.ts +8 -7
- package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +7 -7
- package/test/unit/data-structures/graph/directed-graph.test.ts +3 -3
- package/test/unit/data-structures/hash/hash-map.test.ts +14 -14
- package/tsup.node.config.js +40 -6
- package/test/performance/reportor.mjs +0 -505
|
@@ -6,7 +6,15 @@
|
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type {
|
|
9
|
+
import type {
|
|
10
|
+
BTNOptKeyOrNull,
|
|
11
|
+
ElemOf,
|
|
12
|
+
EntryCallback,
|
|
13
|
+
FamilyPosition,
|
|
14
|
+
RBTNColor,
|
|
15
|
+
RedBlackTreeOptions,
|
|
16
|
+
TreeMultiMapOptions
|
|
17
|
+
} from '../../types';
|
|
10
18
|
import { RedBlackTree, RedBlackTreeNode } from './red-black-tree';
|
|
11
19
|
import { IBinaryTree } from '../../interfaces';
|
|
12
20
|
|
|
@@ -16,8 +24,10 @@ import { IBinaryTree } from '../../interfaces';
|
|
|
16
24
|
* @template K
|
|
17
25
|
* @template V
|
|
18
26
|
*/
|
|
19
|
-
export class TreeMultiMapNode<K = any, V = any>
|
|
20
|
-
|
|
27
|
+
export class TreeMultiMapNode<K = any, V = any> {
|
|
28
|
+
key: K;
|
|
29
|
+
value?: V[];
|
|
30
|
+
parent?: TreeMultiMapNode<K, V> = undefined;
|
|
21
31
|
|
|
22
32
|
/**
|
|
23
33
|
* Create a TreeMultiMap node with an optional value bucket.
|
|
@@ -26,18 +36,20 @@ export class TreeMultiMapNode<K = any, V = any> extends RedBlackTreeNode<K, V[]>
|
|
|
26
36
|
* @param [value] - Initial array of values.
|
|
27
37
|
* @returns New TreeMultiMapNode instance.
|
|
28
38
|
*/
|
|
29
|
-
constructor(key: K, value
|
|
30
|
-
|
|
39
|
+
constructor(key: K, value: V[] = [], color: RBTNColor = 'BLACK') {
|
|
40
|
+
this.key = key;
|
|
41
|
+
this.value = value;
|
|
42
|
+
this.color = color;
|
|
31
43
|
}
|
|
32
44
|
|
|
33
|
-
|
|
45
|
+
_left?: TreeMultiMapNode<K, V> | null | undefined = undefined;
|
|
34
46
|
|
|
35
47
|
/**
|
|
36
48
|
* Get the left child pointer.
|
|
37
49
|
* @remarks Time O(1), Space O(1)
|
|
38
50
|
* @returns Left child node, or null/undefined.
|
|
39
51
|
*/
|
|
40
|
-
|
|
52
|
+
get left(): TreeMultiMapNode<K, V> | null | undefined {
|
|
41
53
|
return this._left;
|
|
42
54
|
}
|
|
43
55
|
|
|
@@ -47,21 +59,21 @@ export class TreeMultiMapNode<K = any, V = any> extends RedBlackTreeNode<K, V[]>
|
|
|
47
59
|
* @param v - New left child node, or null/undefined.
|
|
48
60
|
* @returns void
|
|
49
61
|
*/
|
|
50
|
-
|
|
62
|
+
set left(v: TreeMultiMapNode<K, V> | null | undefined) {
|
|
51
63
|
if (v) {
|
|
52
64
|
v.parent = this;
|
|
53
65
|
}
|
|
54
66
|
this._left = v;
|
|
55
67
|
}
|
|
56
68
|
|
|
57
|
-
|
|
69
|
+
_right?: TreeMultiMapNode<K, V> | null | undefined = undefined;
|
|
58
70
|
|
|
59
71
|
/**
|
|
60
72
|
* Get the right child pointer.
|
|
61
73
|
* @remarks Time O(1), Space O(1)
|
|
62
74
|
* @returns Right child node, or null/undefined.
|
|
63
75
|
*/
|
|
64
|
-
|
|
76
|
+
get right(): TreeMultiMapNode<K, V> | null | undefined {
|
|
65
77
|
return this._right;
|
|
66
78
|
}
|
|
67
79
|
|
|
@@ -71,12 +83,98 @@ export class TreeMultiMapNode<K = any, V = any> extends RedBlackTreeNode<K, V[]>
|
|
|
71
83
|
* @param v - New right child node, or null/undefined.
|
|
72
84
|
* @returns void
|
|
73
85
|
*/
|
|
74
|
-
|
|
86
|
+
set right(v: TreeMultiMapNode<K, V> | null | undefined) {
|
|
75
87
|
if (v) {
|
|
76
88
|
v.parent = this;
|
|
77
89
|
}
|
|
78
90
|
this._right = v;
|
|
79
91
|
}
|
|
92
|
+
|
|
93
|
+
_height: number = 0;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Gets the height of the node (used in self-balancing trees).
|
|
97
|
+
* @remarks Time O(1), Space O(1)
|
|
98
|
+
*
|
|
99
|
+
* @returns The height.
|
|
100
|
+
*/
|
|
101
|
+
get height(): number {
|
|
102
|
+
return this._height;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Sets the height of the node.
|
|
107
|
+
* @remarks Time O(1), Space O(1)
|
|
108
|
+
*
|
|
109
|
+
* @param value - The new height.
|
|
110
|
+
*/
|
|
111
|
+
set height(value: number) {
|
|
112
|
+
this._height = value;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
_color: RBTNColor = 'BLACK';
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Gets the color of the node (used in Red-Black trees).
|
|
119
|
+
* @remarks Time O(1), Space O(1)
|
|
120
|
+
*
|
|
121
|
+
* @returns The node's color.
|
|
122
|
+
*/
|
|
123
|
+
get color(): RBTNColor {
|
|
124
|
+
return this._color;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Sets the color of the node.
|
|
129
|
+
* @remarks Time O(1), Space O(1)
|
|
130
|
+
*
|
|
131
|
+
* @param value - The new color.
|
|
132
|
+
*/
|
|
133
|
+
set color(value: RBTNColor) {
|
|
134
|
+
this._color = value;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
_count: number = 1;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Gets the count of nodes in the subtree rooted at this node (used in order-statistic trees).
|
|
141
|
+
* @remarks Time O(1), Space O(1)
|
|
142
|
+
*
|
|
143
|
+
* @returns The subtree node count.
|
|
144
|
+
*/
|
|
145
|
+
get count(): number {
|
|
146
|
+
return this._count;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Sets the count of nodes in the subtree.
|
|
151
|
+
* @remarks Time O(1), Space O(1)
|
|
152
|
+
*
|
|
153
|
+
* @param value - The new count.
|
|
154
|
+
*/
|
|
155
|
+
set count(value: number) {
|
|
156
|
+
this._count = value;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Gets the position of the node relative to its parent.
|
|
161
|
+
* @remarks Time O(1), Space O(1)
|
|
162
|
+
*
|
|
163
|
+
* @returns The family position (e.g., 'ROOT', 'LEFT', 'RIGHT').
|
|
164
|
+
*/
|
|
165
|
+
get familyPosition(): FamilyPosition {
|
|
166
|
+
if (!this.parent) {
|
|
167
|
+
return this.left || this.right ? 'ROOT' : 'ISOLATED';
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (this.parent.left === this) {
|
|
171
|
+
return this.left || this.right ? 'ROOT_LEFT' : 'LEFT';
|
|
172
|
+
} else if (this.parent.right === this) {
|
|
173
|
+
return this.left || this.right ? 'ROOT_RIGHT' : 'RIGHT';
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return 'MAL_NODE';
|
|
177
|
+
}
|
|
80
178
|
}
|
|
81
179
|
|
|
82
180
|
/**
|
|
@@ -85,6 +183,7 @@ export class TreeMultiMapNode<K = any, V = any> extends RedBlackTreeNode<K, V[]>
|
|
|
85
183
|
* @template K
|
|
86
184
|
* @template V
|
|
87
185
|
* @template R
|
|
186
|
+
*
|
|
88
187
|
* @example
|
|
89
188
|
* // players ranked by score with their equipment
|
|
90
189
|
* type Equipment = {
|
|
@@ -274,6 +373,19 @@ export class TreeMultiMap<K = any, V = any, R = any> extends RedBlackTree<K, V[]
|
|
|
274
373
|
return new TreeMultiMapNode<K, V>(key, this._isMapMode ? [] : value);
|
|
275
374
|
}
|
|
276
375
|
|
|
376
|
+
/**
|
|
377
|
+
* Checks if the given item is a `TreeMultiMapNode` instance.
|
|
378
|
+
* @remarks Time O(1), Space O(1)
|
|
379
|
+
*
|
|
380
|
+
* @param keyNodeOrEntry - The item to check.
|
|
381
|
+
* @returns True if it's a TreeMultiMapNode, false otherwise.
|
|
382
|
+
*/
|
|
383
|
+
override isNode(
|
|
384
|
+
keyNodeOrEntry: K | TreeMultiMapNode<K, V> | [K | null | undefined, V[] | undefined] | null | undefined
|
|
385
|
+
): keyNodeOrEntry is TreeMultiMapNode<K, V> {
|
|
386
|
+
return keyNodeOrEntry instanceof TreeMultiMapNode;
|
|
387
|
+
}
|
|
388
|
+
|
|
277
389
|
override add(
|
|
278
390
|
keyNodeOrEntry: K | TreeMultiMapNode<K, V> | [K | null | undefined, V[] | undefined] | null | undefined
|
|
279
391
|
): boolean;
|
|
@@ -392,7 +504,7 @@ export class TreeMultiMap<K = any, V = any, R = any> extends RedBlackTree<K, V[]
|
|
|
392
504
|
): RedBlackTree<MK, MV, MR> {
|
|
393
505
|
const out = this._createLike<MK, MV, MR>([], options);
|
|
394
506
|
let i = 0;
|
|
395
|
-
for (const [k, v] of this) out.add(callback.call(thisArg,
|
|
507
|
+
for (const [k, v] of this) out.add(callback.call(thisArg, v, k, i++, this));
|
|
396
508
|
return out;
|
|
397
509
|
}
|
|
398
510
|
|
|
@@ -50,11 +50,11 @@ export abstract class AbstractEdge<E = any> {
|
|
|
50
50
|
* @example examples will be generated by unit test
|
|
51
51
|
*/
|
|
52
52
|
export abstract class AbstractGraph<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
V = any,
|
|
54
|
+
E = any,
|
|
55
|
+
VO extends AbstractVertex<V> = AbstractVertex<V>,
|
|
56
|
+
EO extends AbstractEdge<E> = AbstractEdge<E>
|
|
57
|
+
>
|
|
58
58
|
extends IterableEntryBase<VertexKey, V | undefined>
|
|
59
59
|
implements IGraph<V, E, VO, EO>
|
|
60
60
|
{
|
|
@@ -897,7 +897,7 @@ export abstract class AbstractGraph<
|
|
|
897
897
|
const filtered: [VertexKey, V | undefined][] = [];
|
|
898
898
|
let index = 0;
|
|
899
899
|
for (const [key, value] of this) {
|
|
900
|
-
if (predicate.call(thisArg,
|
|
900
|
+
if (predicate.call(thisArg, value, key, index, this)) {
|
|
901
901
|
filtered.push([key, value]);
|
|
902
902
|
}
|
|
903
903
|
index++;
|
|
@@ -916,7 +916,7 @@ export abstract class AbstractGraph<
|
|
|
916
916
|
const filtered: [VertexKey, V | undefined][] = [];
|
|
917
917
|
let index = 0;
|
|
918
918
|
for (const [key, value] of this) {
|
|
919
|
-
if (predicate.call(thisArg,
|
|
919
|
+
if (predicate.call(thisArg, value, key, index, this)) {
|
|
920
920
|
filtered.push([key, value]);
|
|
921
921
|
}
|
|
922
922
|
index++;
|
|
@@ -928,7 +928,7 @@ export abstract class AbstractGraph<
|
|
|
928
928
|
const mapped: T[] = [];
|
|
929
929
|
let index = 0;
|
|
930
930
|
for (const [key, value] of this) {
|
|
931
|
-
mapped.push(callback.call(thisArg,
|
|
931
|
+
mapped.push(callback.call(thisArg, value, key, index, this));
|
|
932
932
|
index++;
|
|
933
933
|
}
|
|
934
934
|
return mapped;
|
|
@@ -38,11 +38,11 @@ export class DirectedEdge<E = any> extends AbstractEdge<E> {
|
|
|
38
38
|
* @example examples will be generated by unit test
|
|
39
39
|
*/
|
|
40
40
|
export class DirectedGraph<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
V = any,
|
|
42
|
+
E = any,
|
|
43
|
+
VO extends DirectedVertex<V> = DirectedVertex<V>,
|
|
44
|
+
EO extends DirectedEdge<E> = DirectedEdge<E>
|
|
45
|
+
>
|
|
46
46
|
extends AbstractGraph<V, E, VO, EO>
|
|
47
47
|
implements IGraph<V, E, VO, EO>
|
|
48
48
|
{
|
|
@@ -36,11 +36,11 @@ export class UndirectedEdge<E = number> extends AbstractEdge<E> {
|
|
|
36
36
|
* @example examples will be generated by unit test
|
|
37
37
|
*/
|
|
38
38
|
export class UndirectedGraph<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
V = any,
|
|
40
|
+
E = any,
|
|
41
|
+
VO extends UndirectedVertex<V> = UndirectedVertex<V>,
|
|
42
|
+
EO extends UndirectedEdge<E> = UndirectedEdge<E>
|
|
43
|
+
>
|
|
44
44
|
extends AbstractGraph<V, E, VO, EO>
|
|
45
45
|
implements IGraph<V, E, VO, EO>
|
|
46
46
|
{
|
|
@@ -290,7 +290,7 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
290
290
|
map<VM>(callbackfn: EntryCallback<K, V, VM>, thisArg?: any): any {
|
|
291
291
|
const out = this._createLike<K, VM, [K, VM]>();
|
|
292
292
|
let index = 0;
|
|
293
|
-
for (const [key, value] of this) out.set(key, callbackfn.call(thisArg,
|
|
293
|
+
for (const [key, value] of this) out.set(key, callbackfn.call(thisArg, value, key, index++, this));
|
|
294
294
|
return out;
|
|
295
295
|
}
|
|
296
296
|
|
|
@@ -305,7 +305,7 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
305
305
|
filter(predicate: EntryCallback<K, V, boolean>, thisArg?: any): any {
|
|
306
306
|
const out = this._createLike<K, V, [K, V]>();
|
|
307
307
|
let index = 0;
|
|
308
|
-
for (const [key, value] of this) if (predicate.call(thisArg,
|
|
308
|
+
for (const [key, value] of this) if (predicate.call(thisArg, value, key, index++, this)) out.set(key, value);
|
|
309
309
|
return out;
|
|
310
310
|
}
|
|
311
311
|
|
|
@@ -677,7 +677,7 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
677
677
|
const out = this._createLike<K, V, [K, V]>();
|
|
678
678
|
let index = 0;
|
|
679
679
|
for (const [key, value] of this) {
|
|
680
|
-
if (predicate.call(thisArg,
|
|
680
|
+
if (predicate.call(thisArg, value, key, index, this)) out.set(key, value);
|
|
681
681
|
index++;
|
|
682
682
|
}
|
|
683
683
|
return out;
|
|
@@ -696,7 +696,7 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
696
696
|
const out = this._createLike<MK, MV, [MK, MV]>();
|
|
697
697
|
let index = 0;
|
|
698
698
|
for (const [key, value] of this) {
|
|
699
|
-
const [newKey, newValue] = callback.call(thisArg,
|
|
699
|
+
const [newKey, newValue] = callback.call(thisArg, value, key, index, this);
|
|
700
700
|
out.set(newKey, newValue);
|
|
701
701
|
index++;
|
|
702
702
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IterableElementBase, IterableEntryBase } from '../../../data-structures';
|
|
2
2
|
import { LinearBase } from '../../../data-structures/base/linear-base';
|
|
3
3
|
|
|
4
|
-
export type EntryCallback<K, V, R> = (
|
|
4
|
+
export type EntryCallback<K, V, R> = (value: V, key: K, index: number, original: IterableEntryBase<K, V>) => R;
|
|
5
5
|
export type ElementCallback<E, R, RT> = (element: E, index: number, original: IterableElementBase<E, R>) => RT;
|
|
6
6
|
export type ReduceEntryCallback<K, V, R> = (
|
|
7
7
|
accumulator: R,
|
|
@@ -2,57 +2,60 @@ import { RedBlackTree } from '../../../../src';
|
|
|
2
2
|
import * as Benchmark from 'benchmark';
|
|
3
3
|
import { getRandomIntArray, magnitude } from '../../../utils';
|
|
4
4
|
import { OrderedMap } from 'js-sdsl';
|
|
5
|
-
import { isCompetitor } from '../../../config';
|
|
6
5
|
|
|
7
6
|
const suite = new Benchmark.Suite();
|
|
8
7
|
const rbTree = new RedBlackTree<number>();
|
|
9
|
-
const rbTreeNodeMode = new RedBlackTree<number>([], { isMapMode: false });
|
|
8
|
+
// const rbTreeNodeMode = new RedBlackTree<number>([], { isMapMode: false });
|
|
10
9
|
|
|
11
|
-
const {
|
|
12
|
-
const randomArray = getRandomIntArray(
|
|
10
|
+
const { MILLION } = magnitude;
|
|
11
|
+
const randomArray = getRandomIntArray(MILLION, 0, MILLION - 1, true);
|
|
13
12
|
const cOrderedMap = new OrderedMap<number, number>();
|
|
14
13
|
|
|
15
14
|
suite
|
|
16
|
-
.add(`${
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
})
|
|
20
|
-
.add(`${
|
|
15
|
+
// .add(`${MILLION.toLocaleString()} add randomly`, () => {
|
|
16
|
+
// rbTree.clear();
|
|
17
|
+
// for (let i = 0; i < randomArray.length; i++) rbTree.add(randomArray[i]);
|
|
18
|
+
// })
|
|
19
|
+
.add(`${MILLION.toLocaleString()} add`, () => {
|
|
21
20
|
rbTree.clear();
|
|
22
21
|
for (let i = 0; i < randomArray.length; i++) rbTree.add(i);
|
|
23
22
|
})
|
|
24
|
-
.add(`${
|
|
23
|
+
.add(`${MILLION.toLocaleString()} get`, () => {
|
|
25
24
|
for (let i = 0; i < randomArray.length; i++) rbTree.get(randomArray[i]);
|
|
26
25
|
})
|
|
27
|
-
.add(`${
|
|
28
|
-
|
|
29
|
-
})
|
|
30
|
-
.add(`${
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
})
|
|
34
|
-
.add(`${
|
|
35
|
-
|
|
36
|
-
})
|
|
37
|
-
.add(`${
|
|
26
|
+
// .add(`${MILLION.toLocaleString()} getNode`, () => {
|
|
27
|
+
// for (let i = 0; i < randomArray.length; i++) rbTree.getNode(randomArray[i]);
|
|
28
|
+
// })
|
|
29
|
+
// .add(`${MILLION.toLocaleString()} node mode add randomly`, () => {
|
|
30
|
+
// rbTreeNodeMode.clear();
|
|
31
|
+
// for (let i = 0; i < randomArray.length; i++) rbTreeNodeMode.add(randomArray[i]);
|
|
32
|
+
// })
|
|
33
|
+
// .add(`${MILLION.toLocaleString()} node mode get`, () => {
|
|
34
|
+
// for (let i = 0; i < randomArray.length; i++) rbTreeNodeMode.get(randomArray[i]);
|
|
35
|
+
// })
|
|
36
|
+
.add(`${MILLION.toLocaleString()} iterator`, () => {
|
|
38
37
|
const entries = [...rbTree];
|
|
39
|
-
return entries.length ===
|
|
40
|
-
})
|
|
41
|
-
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & delete orderly`, () => {
|
|
42
|
-
rbTree.clear();
|
|
43
|
-
for (let i = 0; i < randomArray.length; i++) rbTree.add(i);
|
|
44
|
-
for (let i = 0; i < randomArray.length; i++) rbTree.delete(i);
|
|
45
|
-
})
|
|
46
|
-
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & delete randomly`, () => {
|
|
47
|
-
rbTree.clear();
|
|
48
|
-
for (let i = 0; i < randomArray.length; i++) rbTree.add(randomArray[i]);
|
|
49
|
-
for (let i = 0; i < randomArray.length; i++) rbTree.delete(randomArray[i]);
|
|
38
|
+
return entries.length === MILLION;
|
|
50
39
|
});
|
|
40
|
+
// .add(`${MILLION.toLocaleString()} add & delete orderly`, () => {
|
|
41
|
+
// rbTree.clear();
|
|
42
|
+
// for (let i = 0; i < randomArray.length; i++) rbTree.add(i);
|
|
43
|
+
// for (let i = 0; i < randomArray.length; i++) rbTree.delete(i);
|
|
44
|
+
// })
|
|
45
|
+
// .add(`${MILLION.toLocaleString()} add & delete randomly`, () => {
|
|
46
|
+
// rbTree.clear();
|
|
47
|
+
// for (let i = 0; i < randomArray.length; i++) rbTree.add(randomArray[i]);
|
|
48
|
+
// for (let i = 0; i < randomArray.length; i++) rbTree.delete(randomArray[i]);
|
|
49
|
+
// });
|
|
51
50
|
|
|
52
|
-
if (
|
|
53
|
-
suite
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
if (true) {
|
|
52
|
+
suite
|
|
53
|
+
.add(`CPT ${MILLION.toLocaleString()} add`, () => {
|
|
54
|
+
for (let i = 0; i < randomArray.length; i++) cOrderedMap.setElement(randomArray[i], randomArray[i]);
|
|
55
|
+
})
|
|
56
|
+
.add(`CPT ${MILLION.toLocaleString()} add`, () => {
|
|
57
|
+
for (let i = 0; i < randomArray.length; i++) cOrderedMap.getElementByKey(randomArray[i]);
|
|
58
|
+
});
|
|
56
59
|
}
|
|
57
60
|
|
|
58
61
|
export { suite };
|
|
@@ -17,20 +17,20 @@
|
|
|
17
17
|
"**/experimental/**"
|
|
18
18
|
],
|
|
19
19
|
"order": [
|
|
20
|
+
"red-black-tree",
|
|
21
|
+
"queue",
|
|
22
|
+
"deque",
|
|
20
23
|
"heap",
|
|
21
24
|
"avl-tree",
|
|
22
|
-
"red-black-tree",
|
|
23
25
|
"doubly-linked-list",
|
|
26
|
+
"singly-linked-list",
|
|
24
27
|
"linked-hash-map",
|
|
25
28
|
"hash-map",
|
|
26
29
|
"map-graph",
|
|
27
30
|
"graph",
|
|
28
31
|
"directed-graph",
|
|
29
32
|
"undirected-graph",
|
|
30
|
-
"queue",
|
|
31
|
-
"deque",
|
|
32
33
|
"priority-queue",
|
|
33
|
-
"singly-linked-list",
|
|
34
34
|
"binary-tree-overall",
|
|
35
35
|
"bst",
|
|
36
36
|
"trie",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AVLTreeCounter, AVLTreeCounterNode,
|
|
1
|
+
import { AVLTreeCounter, AVLTreeCounterNode, IBinaryTree } from '../../../../src';
|
|
2
2
|
import { isDebugTest } from '../../../config';
|
|
3
3
|
|
|
4
4
|
const isDebug = isDebugTest;
|
|
@@ -619,14 +619,15 @@ describe('AVLTreeCounter iterative methods test', () => {
|
|
|
619
619
|
|
|
620
620
|
it('The node obtained by get Node should match the node type', () => {
|
|
621
621
|
const node3 = avlCounter.getNode(3);
|
|
622
|
-
expect(node3).toBeInstanceOf(BinaryTreeNode);
|
|
623
|
-
expect(node3).toBeInstanceOf(BSTNode);
|
|
624
|
-
expect(node3).toBeInstanceOf(AVLTreeNode);
|
|
622
|
+
// expect(node3).toBeInstanceOf(BinaryTreeNode);
|
|
623
|
+
// expect(node3).toBeInstanceOf(BSTNode);
|
|
624
|
+
// expect(node3).toBeInstanceOf(AVLTreeNode);
|
|
625
|
+
expect(node3).toBeInstanceOf(AVLTreeCounterNode);
|
|
625
626
|
});
|
|
626
627
|
|
|
627
628
|
it('forEach should iterate over all elements', () => {
|
|
628
629
|
const mockCallback = jest.fn();
|
|
629
|
-
avlCounter.forEach((
|
|
630
|
+
avlCounter.forEach((value, key) => {
|
|
630
631
|
mockCallback(key, value);
|
|
631
632
|
});
|
|
632
633
|
|
|
@@ -637,7 +638,7 @@ describe('AVLTreeCounter iterative methods test', () => {
|
|
|
637
638
|
});
|
|
638
639
|
|
|
639
640
|
it('filter should return a new avlCounter with filtered elements', () => {
|
|
640
|
-
const filteredTree = avlCounter.filter(key => key > 1);
|
|
641
|
+
const filteredTree = avlCounter.filter((_value, key) => key > 1);
|
|
641
642
|
expect(filteredTree.size).toBe(2);
|
|
642
643
|
expect([...filteredTree]).toEqual([
|
|
643
644
|
[2, 'b'],
|
|
@@ -646,7 +647,7 @@ describe('AVLTreeCounter iterative methods test', () => {
|
|
|
646
647
|
});
|
|
647
648
|
|
|
648
649
|
it('map should return a new avlCounter with modified elements', () => {
|
|
649
|
-
const avlCounterMapped = avlCounter.map((
|
|
650
|
+
const avlCounterMapped = avlCounter.map((value, key) => [(key * 2).toString(), value]);
|
|
650
651
|
expect(avlCounterMapped.size).toBe(3);
|
|
651
652
|
expect([...avlCounterMapped]).toEqual([
|
|
652
653
|
['2', 'a'],
|
|
@@ -415,7 +415,7 @@ describe('AVLTreeMultiMap iterative methods test', () => {
|
|
|
415
415
|
|
|
416
416
|
it('forEach should iterate over all elements', () => {
|
|
417
417
|
const mockCallback = jest.fn();
|
|
418
|
-
avlTmm.forEach((
|
|
418
|
+
avlTmm.forEach((value, key) => {
|
|
419
419
|
mockCallback(key, value);
|
|
420
420
|
});
|
|
421
421
|
|
|
@@ -426,7 +426,7 @@ describe('AVLTreeMultiMap iterative methods test', () => {
|
|
|
426
426
|
});
|
|
427
427
|
|
|
428
428
|
it('filter should return a new avlTmm with filtered elements', () => {
|
|
429
|
-
const filteredTree = avlTmm.filter(key => key > 1);
|
|
429
|
+
const filteredTree = avlTmm.filter((_value, key) => key > 1);
|
|
430
430
|
expect(filteredTree.size).toBe(2);
|
|
431
431
|
expect([...filteredTree]).toEqual([
|
|
432
432
|
[2, ['b']],
|
|
@@ -435,7 +435,7 @@ describe('AVLTreeMultiMap iterative methods test', () => {
|
|
|
435
435
|
});
|
|
436
436
|
|
|
437
437
|
it('map should return a new avlTmm with modified elements', () => {
|
|
438
|
-
const avlTmmMapped = avlTmm.map((
|
|
438
|
+
const avlTmmMapped = avlTmm.map((value, key) => [(key * 2).toString(), value ? value : []]);
|
|
439
439
|
expect(avlTmmMapped.size).toBe(3);
|
|
440
440
|
expect([...avlTmmMapped]).toEqual([
|
|
441
441
|
['2', ['a']],
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AVLTree, AVLTreeNode,
|
|
1
|
+
import { AVLTree, AVLTreeNode, IBinaryTree } from '../../../../src';
|
|
2
2
|
|
|
3
3
|
describe('AVL Tree Test', () => {
|
|
4
4
|
it('should perform various operations on a AVL Tree', () => {
|
|
@@ -379,14 +379,14 @@ describe('AVLTree iterative methods test', () => {
|
|
|
379
379
|
|
|
380
380
|
it('The node obtained by get Node should match the node type', () => {
|
|
381
381
|
const node3 = avlTree.getNode(3);
|
|
382
|
-
expect(node3).toBeInstanceOf(BinaryTreeNode);
|
|
383
|
-
expect(node3).toBeInstanceOf(BSTNode);
|
|
382
|
+
// expect(node3).toBeInstanceOf(BinaryTreeNode);
|
|
383
|
+
// expect(node3).toBeInstanceOf(BSTNode);
|
|
384
384
|
expect(node3).toBeInstanceOf(AVLTreeNode);
|
|
385
385
|
});
|
|
386
386
|
|
|
387
387
|
it('forEach should iterate over all elements', () => {
|
|
388
388
|
const mockCallback = jest.fn();
|
|
389
|
-
avlTree.forEach((
|
|
389
|
+
avlTree.forEach((value, key) => {
|
|
390
390
|
mockCallback(key, value);
|
|
391
391
|
});
|
|
392
392
|
|
|
@@ -397,7 +397,7 @@ describe('AVLTree iterative methods test', () => {
|
|
|
397
397
|
});
|
|
398
398
|
|
|
399
399
|
it('filter should return a new avlTree with filtered elements', () => {
|
|
400
|
-
const filteredTree = avlTree.filter(key => key > 1);
|
|
400
|
+
const filteredTree = avlTree.filter((_value, key) => key > 1);
|
|
401
401
|
expect(filteredTree.size).toBe(2);
|
|
402
402
|
expect([...filteredTree]).toEqual([
|
|
403
403
|
[2, 'b'],
|
|
@@ -406,7 +406,7 @@ describe('AVLTree iterative methods test', () => {
|
|
|
406
406
|
});
|
|
407
407
|
|
|
408
408
|
it('map should return a new avlTree with modified elements', () => {
|
|
409
|
-
const mappedTree = avlTree.map((
|
|
409
|
+
const mappedTree = avlTree.map((value, key) => [(key * 2).toString(), value]);
|
|
410
410
|
expect(mappedTree.size).toBe(3);
|
|
411
411
|
expect([...mappedTree]).toEqual([
|
|
412
412
|
['2', 'a'],
|
|
@@ -1308,7 +1308,7 @@ describe('BinaryTree (map mode) - higher-order & iteration', () => {
|
|
|
1308
1308
|
|
|
1309
1309
|
it('forEach(): iterates all entries', () => {
|
|
1310
1310
|
const mockCallback = jest.fn();
|
|
1311
|
-
binaryTree.forEach((
|
|
1311
|
+
binaryTree.forEach((value, key) => {
|
|
1312
1312
|
mockCallback(key, value);
|
|
1313
1313
|
});
|
|
1314
1314
|
|
|
@@ -1319,7 +1319,7 @@ describe('BinaryTree (map mode) - higher-order & iteration', () => {
|
|
|
1319
1319
|
});
|
|
1320
1320
|
|
|
1321
1321
|
it('filter(): returns new tree with filtered entries', () => {
|
|
1322
|
-
const filteredTree = binaryTree.filter(key => key > 1);
|
|
1322
|
+
const filteredTree = binaryTree.filter((_value, key) => key > 1);
|
|
1323
1323
|
expect(filteredTree.size).toBe(2);
|
|
1324
1324
|
expect([...filteredTree]).toEqual([
|
|
1325
1325
|
[3, 'c'],
|
|
@@ -1328,7 +1328,7 @@ describe('BinaryTree (map mode) - higher-order & iteration', () => {
|
|
|
1328
1328
|
});
|
|
1329
1329
|
|
|
1330
1330
|
it('map(): returns new tree with transformed keys/values', () => {
|
|
1331
|
-
const mappedTree = binaryTree.map((
|
|
1331
|
+
const mappedTree = binaryTree.map((value, key) => [(key * 2).toString(), value]);
|
|
1332
1332
|
expect(mappedTree.size).toBe(3);
|
|
1333
1333
|
expect([...mappedTree]).toEqual([
|
|
1334
1334
|
['2', 'a'],
|
|
@@ -1578,7 +1578,7 @@ describe('Coverage boosters - close remaining uncovered branches', () => {
|
|
|
1578
1578
|
[1, 'a'],
|
|
1579
1579
|
[2, 'b']
|
|
1580
1580
|
]);
|
|
1581
|
-
const mapped = t.map((
|
|
1581
|
+
const mapped = t.map((v, k) => [String(k), (v ?? '').toUpperCase()], { iterationType: 'RECURSIVE' } as any);
|
|
1582
1582
|
expect(Array.from(mapped)).toEqual([
|
|
1583
1583
|
['1', 'A'],
|
|
1584
1584
|
['2', 'B']
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BST, BSTNode, IBinaryTree, Range } from '../../../../src';
|
|
2
2
|
import { isDebugTest, isTestStackOverflow, SYSTEM_MAX_CALL_STACK } from '../../../config';
|
|
3
3
|
|
|
4
4
|
const isDebug = isDebugTest;
|
|
@@ -1103,13 +1103,13 @@ describe('BST iterative methods test', () => {
|
|
|
1103
1103
|
|
|
1104
1104
|
it('The node obtained by get Node should match the node type', () => {
|
|
1105
1105
|
const node3 = bst.getNode(3);
|
|
1106
|
-
expect(node3).toBeInstanceOf(BinaryTreeNode);
|
|
1106
|
+
// expect(node3).toBeInstanceOf(BinaryTreeNode);
|
|
1107
1107
|
expect(node3).toBeInstanceOf(BSTNode);
|
|
1108
1108
|
});
|
|
1109
1109
|
|
|
1110
1110
|
it('forEach should iterate over all elements', () => {
|
|
1111
1111
|
const mockCallback = jest.fn();
|
|
1112
|
-
bst.forEach((
|
|
1112
|
+
bst.forEach((value, key) => {
|
|
1113
1113
|
mockCallback(key, value);
|
|
1114
1114
|
});
|
|
1115
1115
|
|
|
@@ -1120,7 +1120,7 @@ describe('BST iterative methods test', () => {
|
|
|
1120
1120
|
});
|
|
1121
1121
|
|
|
1122
1122
|
it('filter should return a new tree with filtered elements', () => {
|
|
1123
|
-
const filteredTree = bst.filter(key => key > 1);
|
|
1123
|
+
const filteredTree = bst.filter((_value, key) => key > 1);
|
|
1124
1124
|
expect(filteredTree.size).toBe(2);
|
|
1125
1125
|
expect([...filteredTree]).toEqual([
|
|
1126
1126
|
[2, 'b'],
|
|
@@ -1129,7 +1129,7 @@ describe('BST iterative methods test', () => {
|
|
|
1129
1129
|
});
|
|
1130
1130
|
|
|
1131
1131
|
it('map should return a new tree with modified elements', () => {
|
|
1132
|
-
const mappedTree = bst.map((
|
|
1132
|
+
const mappedTree = bst.map((value, key) => [(key * 2).toString(), value]);
|
|
1133
1133
|
expect(mappedTree.size).toBe(3);
|
|
1134
1134
|
expect([...mappedTree]).toEqual([
|
|
1135
1135
|
['2', 'a'],
|