data-structure-typed 1.41.1 → 1.41.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/CHANGELOG.md +1 -1
- package/benchmark/report.json +30 -0
- package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +9 -9
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +2 -5
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +17 -2
- package/dist/cjs/data-structures/binary-tree/rb-tree.js +87 -20
- package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +9 -9
- package/dist/mjs/data-structures/binary-tree/binary-tree.js +1 -4
- package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +17 -2
- package/dist/mjs/data-structures/binary-tree/rb-tree.js +87 -20
- package/dist/umd/data-structure-typed.min.js +1 -1
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/jest.integration.config.js +5 -0
- package/package.json +10 -6
- package/src/data-structures/binary-tree/binary-tree.ts +13 -13
- package/src/data-structures/binary-tree/rb-tree.ts +94 -20
- package/test/integration/avl-tree.test.ts +3 -3
- package/test/integration/bst.test.ts +7 -7
- package/test/performance/data-structures/binary-tree/avl-tree.test.ts +0 -0
- package/test/performance/data-structures/binary-tree/binary-index-tree.test.ts +0 -0
- package/test/performance/data-structures/binary-tree/binary-tree.test.ts +0 -0
- package/test/performance/data-structures/binary-tree/bst.test.ts +0 -0
- package/test/performance/data-structures/binary-tree/overall.test.ts +0 -0
- package/test/performance/data-structures/binary-tree/rb-tree.test.ts +0 -0
- package/test/performance/data-structures/binary-tree/segment-tree.test.ts +0 -0
- package/test/performance/data-structures/binary-tree/tree-multiset.test.ts +0 -0
- package/test/performance/data-structures/graph/abstract-graph.test.ts +0 -0
- package/test/performance/data-structures/graph/directed-graph.test.ts +0 -0
- package/test/performance/data-structures/graph/map-graph.test.ts +0 -0
- package/test/performance/data-structures/graph/overall.test.ts +0 -0
- package/test/performance/data-structures/graph/undirected-graph.test.ts +0 -0
- package/test/performance/data-structures/hash/coordinate-map.test.ts +0 -0
- package/test/performance/data-structures/hash/coordinate-set.test.ts +0 -0
- package/test/performance/data-structures/hash/hash-map.test.ts +0 -0
- package/test/performance/data-structures/hash/hash-table.test.ts +0 -0
- package/test/performance/data-structures/heap/heap.test.ts +0 -0
- package/test/performance/data-structures/heap/max-heap.test.ts +0 -0
- package/test/performance/data-structures/heap/min-heap.test.ts +0 -0
- package/test/performance/data-structures/linked-list/doubly-linked-list.test.ts +0 -0
- package/test/performance/data-structures/linked-list/linked-list.test.ts +0 -0
- package/test/performance/data-structures/linked-list/singly-linked-list.test.ts +0 -0
- package/test/performance/data-structures/linked-list/skip-linked-list.test.ts +0 -0
- package/test/performance/data-structures/linked-list/skip-list.test.ts +0 -0
- package/test/performance/data-structures/matrix/matrix.test.ts +0 -0
- package/test/performance/data-structures/matrix/matrix2d.test.ts +0 -0
- package/test/performance/data-structures/matrix/navigator.test.ts +0 -0
- package/test/performance/data-structures/matrix/vector2d.test.ts +0 -0
- package/test/performance/data-structures/priority-queue/max-priority-queue.test.ts +0 -0
- package/test/performance/data-structures/priority-queue/min-priority-queue.test.ts +0 -0
- package/test/performance/data-structures/priority-queue/priority-queue.test.ts +0 -0
- package/test/performance/data-structures/queue/deque.test.ts +19 -0
- package/test/performance/data-structures/queue/queue.test.ts +20 -0
- package/test/performance/data-structures/stack/stack.test.ts +0 -0
- package/test/performance/data-structures/tree/tree.test.ts +0 -0
- package/test/performance/data-structures/trie/trie.test.ts +0 -0
- package/test/performance/index.ts +47 -0
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +175 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "data-structure-typed",
|
|
3
|
-
"version": "1.41.
|
|
3
|
+
"version": "1.41.3",
|
|
4
4
|
"description": "Data Structures of Javascript & TypeScript. Binary Tree, BST, Graph, Heap, Priority Queue, Linked List, Queue, Deque, Stack, AVL Tree, Tree Multiset, Trie, Directed Graph, Undirected Graph, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue.",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/mjs/index.js",
|
|
@@ -32,10 +32,12 @@
|
|
|
32
32
|
"update:subs": "npm i avl-tree-typed binary-tree-typed bst-typed heap-typed --save-dev",
|
|
33
33
|
"install:all-subs": "npm i avl-tree-typed binary-tree-typed bst-typed deque-typed directed-graph-typed doubly-linked-list-typed graph-typed heap-typed linked-list-typed max-heap-typed max-priority-queue-typed min-heap-typed min-priority-queue-typed priority-queue-typed singly-linked-list-typed stack-typed tree-multiset-typed trie-typed undirected-graph-typed queue-typed --save-dev",
|
|
34
34
|
"test": "jest",
|
|
35
|
+
"test:integration": "npm run update:subs && jest --config jest.integration.config.js",
|
|
36
|
+
"benchmark": "ts-node test/performance/index.ts",
|
|
35
37
|
"check:deps": "dependency-cruiser src",
|
|
36
38
|
"changelog": "auto-changelog",
|
|
37
39
|
"coverage:badge": "istanbul-badges-readme",
|
|
38
|
-
"ci": "env && git fetch --tags && npm run check && npm run lint && npm run build && npm run
|
|
40
|
+
"ci": "env && git fetch --tags && npm run check && npm run lint && npm run build && npm run test && npm run changelog",
|
|
39
41
|
"copy:to-subs": "sh scripts/copy_to_all_subs.sh",
|
|
40
42
|
"publish:subs": "npm run copy:to-subs && sh scripts/publish_all_subs.sh",
|
|
41
43
|
"publish:docs": "sh scripts/publish_docs.sh",
|
|
@@ -61,22 +63,24 @@
|
|
|
61
63
|
"@typescript-eslint/eslint-plugin": "^6.7.4",
|
|
62
64
|
"@typescript-eslint/parser": "^6.7.4",
|
|
63
65
|
"auto-changelog": "^2.4.0",
|
|
64
|
-
"avl-tree-typed": "^1.41.
|
|
66
|
+
"avl-tree-typed": "^1.41.2",
|
|
65
67
|
"benchmark": "^2.1.4",
|
|
66
|
-
"binary-tree-typed": "^1.41.
|
|
67
|
-
"bst-typed": "^1.41.
|
|
68
|
+
"binary-tree-typed": "^1.41.2",
|
|
69
|
+
"bst-typed": "^1.41.2",
|
|
68
70
|
"dependency-cruiser": "^14.1.0",
|
|
69
71
|
"eslint": "^8.50.0",
|
|
70
72
|
"eslint-config-prettier": "^9.0.0",
|
|
71
73
|
"eslint-import-resolver-alias": "^1.1.2",
|
|
72
74
|
"eslint-import-resolver-typescript": "^3.6.1",
|
|
73
75
|
"eslint-plugin-import": "^2.28.1",
|
|
74
|
-
"
|
|
76
|
+
"fast-glob": "^3.3.1",
|
|
77
|
+
"heap-typed": "^1.41.2",
|
|
75
78
|
"istanbul-badges-readme": "^1.8.5",
|
|
76
79
|
"jest": "^29.7.0",
|
|
77
80
|
"prettier": "^3.0.3",
|
|
78
81
|
"ts-jest": "^29.1.1",
|
|
79
82
|
"ts-loader": "^9.4.4",
|
|
83
|
+
"ts-node": "^10.9.1",
|
|
80
84
|
"tsup": "^7.2.0",
|
|
81
85
|
"typedoc": "^0.25.1",
|
|
82
86
|
"typescript": "^5.2.2"
|
|
@@ -559,21 +559,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
559
559
|
has<C extends BTNCallback<N, BTNKey>>(
|
|
560
560
|
identifier: BTNKey,
|
|
561
561
|
callback?: C,
|
|
562
|
-
beginRoot?: N,
|
|
562
|
+
beginRoot?: N | null,
|
|
563
563
|
iterationType?: IterationType
|
|
564
564
|
): boolean;
|
|
565
565
|
|
|
566
566
|
has<C extends BTNCallback<N, N>>(
|
|
567
567
|
identifier: N | null,
|
|
568
568
|
callback?: C,
|
|
569
|
-
beginRoot?: N,
|
|
569
|
+
beginRoot?: N | null,
|
|
570
570
|
iterationType?: IterationType
|
|
571
571
|
): boolean;
|
|
572
572
|
|
|
573
573
|
has<C extends BTNCallback<N>>(
|
|
574
574
|
identifier: ReturnType<C> | null,
|
|
575
575
|
callback: C,
|
|
576
|
-
beginRoot?: N,
|
|
576
|
+
beginRoot?: N | null,
|
|
577
577
|
iterationType?: IterationType
|
|
578
578
|
): boolean;
|
|
579
579
|
|
|
@@ -601,28 +601,28 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
601
601
|
iterationType = this.iterationType
|
|
602
602
|
): boolean {
|
|
603
603
|
if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|
|
604
|
-
|
|
604
|
+
|
|
605
605
|
return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
|
|
606
606
|
}
|
|
607
607
|
|
|
608
608
|
getNode<C extends BTNCallback<N, BTNKey>>(
|
|
609
609
|
identifier: BTNKey,
|
|
610
610
|
callback?: C,
|
|
611
|
-
beginRoot?: N,
|
|
611
|
+
beginRoot?: N | null,
|
|
612
612
|
iterationType?: IterationType
|
|
613
613
|
): N | null;
|
|
614
614
|
|
|
615
615
|
getNode<C extends BTNCallback<N, N>>(
|
|
616
616
|
identifier: N | null,
|
|
617
617
|
callback?: C,
|
|
618
|
-
beginRoot?: N,
|
|
618
|
+
beginRoot?: N | null,
|
|
619
619
|
iterationType?: IterationType
|
|
620
620
|
): N | null;
|
|
621
621
|
|
|
622
622
|
getNode<C extends BTNCallback<N>>(
|
|
623
623
|
identifier: ReturnType<C>,
|
|
624
624
|
callback: C,
|
|
625
|
-
beginRoot?: N,
|
|
625
|
+
beginRoot?: N | null,
|
|
626
626
|
iterationType?: IterationType
|
|
627
627
|
): N | null;
|
|
628
628
|
|
|
@@ -648,28 +648,28 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
648
648
|
iterationType = this.iterationType
|
|
649
649
|
): N | null {
|
|
650
650
|
if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|
|
651
|
-
|
|
651
|
+
|
|
652
652
|
return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;
|
|
653
653
|
}
|
|
654
654
|
|
|
655
655
|
get<C extends BTNCallback<N, BTNKey>>(
|
|
656
656
|
identifier: BTNKey,
|
|
657
657
|
callback?: C,
|
|
658
|
-
beginRoot?: N,
|
|
658
|
+
beginRoot?: N | null,
|
|
659
659
|
iterationType?: IterationType
|
|
660
660
|
): V | undefined;
|
|
661
661
|
|
|
662
662
|
get<C extends BTNCallback<N, N>>(
|
|
663
663
|
identifier: N | null,
|
|
664
664
|
callback?: C,
|
|
665
|
-
beginRoot?: N,
|
|
665
|
+
beginRoot?: N | null,
|
|
666
666
|
iterationType?: IterationType
|
|
667
667
|
): V | undefined;
|
|
668
668
|
|
|
669
669
|
get<C extends BTNCallback<N>>(
|
|
670
670
|
identifier: ReturnType<C>,
|
|
671
671
|
callback: C,
|
|
672
|
-
beginRoot?: N,
|
|
672
|
+
beginRoot?: N | null,
|
|
673
673
|
iterationType?: IterationType
|
|
674
674
|
): V | undefined;
|
|
675
675
|
|
|
@@ -695,8 +695,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
695
695
|
iterationType = this.iterationType
|
|
696
696
|
): V | undefined {
|
|
697
697
|
if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|
|
698
|
-
|
|
699
|
-
return this.
|
|
698
|
+
|
|
699
|
+
return this.getNode(identifier, callback, beginRoot, iterationType)?.value ?? undefined;
|
|
700
700
|
}
|
|
701
701
|
|
|
702
702
|
/**
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* data-structure-typed
|
|
3
|
+
*
|
|
4
|
+
* @author Tyler Zeng
|
|
5
|
+
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
6
|
+
* @license MIT License
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
import {RBTNColor} from '../../types';
|
|
2
10
|
|
|
3
11
|
export class RBTreeNode {
|
|
@@ -16,11 +24,18 @@ export class RBTreeNode {
|
|
|
16
24
|
}
|
|
17
25
|
}
|
|
18
26
|
|
|
19
|
-
export const
|
|
27
|
+
export const NIL = new RBTreeNode(0);
|
|
20
28
|
|
|
29
|
+
/**
|
|
30
|
+
* 1. Each node is either red or black.
|
|
31
|
+
* 2. The root node is always black.
|
|
32
|
+
* 3. Leaf nodes are typically NIL nodes and are considered black.
|
|
33
|
+
* 4. Red nodes must have black children.
|
|
34
|
+
* 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.
|
|
35
|
+
*/
|
|
21
36
|
export class RedBlackTree {
|
|
22
37
|
constructor() {
|
|
23
|
-
this._root =
|
|
38
|
+
this._root = NIL;
|
|
24
39
|
}
|
|
25
40
|
|
|
26
41
|
protected _root: RBTreeNode;
|
|
@@ -38,13 +53,13 @@ export class RedBlackTree {
|
|
|
38
53
|
*/
|
|
39
54
|
insert(key: number): void {
|
|
40
55
|
const node: RBTreeNode = new RBTreeNode(key, RBTNColor.RED);
|
|
41
|
-
node.left =
|
|
42
|
-
node.right =
|
|
56
|
+
node.left = NIL;
|
|
57
|
+
node.right = NIL;
|
|
43
58
|
|
|
44
59
|
let y: RBTreeNode = null as unknown as RBTreeNode;
|
|
45
60
|
let x: RBTreeNode = this.root;
|
|
46
61
|
|
|
47
|
-
while (x !==
|
|
62
|
+
while (x !== NIL) {
|
|
48
63
|
y = x;
|
|
49
64
|
if (node.key < x.key) {
|
|
50
65
|
x = x.left;
|
|
@@ -83,9 +98,9 @@ export class RedBlackTree {
|
|
|
83
98
|
*/
|
|
84
99
|
delete(key: number): void {
|
|
85
100
|
const helper = (node: RBTreeNode): void => {
|
|
86
|
-
let z: RBTreeNode =
|
|
101
|
+
let z: RBTreeNode = NIL;
|
|
87
102
|
let x: RBTreeNode, y: RBTreeNode;
|
|
88
|
-
while (node !==
|
|
103
|
+
while (node !== NIL) {
|
|
89
104
|
if (node.key === key) {
|
|
90
105
|
z = node;
|
|
91
106
|
}
|
|
@@ -97,16 +112,16 @@ export class RedBlackTree {
|
|
|
97
112
|
}
|
|
98
113
|
}
|
|
99
114
|
|
|
100
|
-
if (z ===
|
|
115
|
+
if (z === NIL) {
|
|
101
116
|
return;
|
|
102
117
|
}
|
|
103
118
|
|
|
104
119
|
y = z;
|
|
105
120
|
let yOriginalColor: number = y.color;
|
|
106
|
-
if (z.left ===
|
|
121
|
+
if (z.left === NIL) {
|
|
107
122
|
x = z.right;
|
|
108
123
|
this._rbTransplant(z, z.right);
|
|
109
|
-
} else if (z.right ===
|
|
124
|
+
} else if (z.right === NIL) {
|
|
110
125
|
x = z.left;
|
|
111
126
|
this._rbTransplant(z, z.left);
|
|
112
127
|
} else {
|
|
@@ -133,8 +148,8 @@ export class RedBlackTree {
|
|
|
133
148
|
helper(this.root);
|
|
134
149
|
}
|
|
135
150
|
|
|
136
|
-
isRealNode(node: RBTreeNode): node is RBTreeNode {
|
|
137
|
-
return node !==
|
|
151
|
+
isRealNode(node: RBTreeNode | null | undefined): node is RBTreeNode {
|
|
152
|
+
return node !== NIL && node !== null;
|
|
138
153
|
}
|
|
139
154
|
|
|
140
155
|
/**
|
|
@@ -170,7 +185,7 @@ export class RedBlackTree {
|
|
|
170
185
|
* @returns The leftmost node in the given RBTreeNode.
|
|
171
186
|
*/
|
|
172
187
|
getLeftMost(node: RBTreeNode = this.root): RBTreeNode {
|
|
173
|
-
while (node.left !== null && node.left !==
|
|
188
|
+
while (node.left !== null && node.left !== NIL) {
|
|
174
189
|
node = node.left;
|
|
175
190
|
}
|
|
176
191
|
return node;
|
|
@@ -182,7 +197,7 @@ export class RedBlackTree {
|
|
|
182
197
|
* @returns the rightmost node in a red-black tree.
|
|
183
198
|
*/
|
|
184
199
|
getRightMost(node: RBTreeNode): RBTreeNode {
|
|
185
|
-
while (node.right !== null && node.right !==
|
|
200
|
+
while (node.right !== null && node.right !== NIL) {
|
|
186
201
|
node = node.right;
|
|
187
202
|
}
|
|
188
203
|
return node;
|
|
@@ -194,12 +209,12 @@ export class RedBlackTree {
|
|
|
194
209
|
* @returns the successor of the given RBTreeNode.
|
|
195
210
|
*/
|
|
196
211
|
getSuccessor(x: RBTreeNode): RBTreeNode {
|
|
197
|
-
if (x.right !==
|
|
212
|
+
if (x.right !== NIL) {
|
|
198
213
|
return this.getLeftMost(x.right);
|
|
199
214
|
}
|
|
200
215
|
|
|
201
216
|
let y: RBTreeNode = x.parent;
|
|
202
|
-
while (y !==
|
|
217
|
+
while (y !== NIL && y !== null && x === y.right) {
|
|
203
218
|
x = y;
|
|
204
219
|
y = y.parent;
|
|
205
220
|
}
|
|
@@ -213,12 +228,12 @@ export class RedBlackTree {
|
|
|
213
228
|
* @returns the predecessor of the given RBTreeNode 'x'.
|
|
214
229
|
*/
|
|
215
230
|
getPredecessor(x: RBTreeNode): RBTreeNode {
|
|
216
|
-
if (x.left !==
|
|
231
|
+
if (x.left !== NIL) {
|
|
217
232
|
return this.getRightMost(x.left);
|
|
218
233
|
}
|
|
219
234
|
|
|
220
235
|
let y: RBTreeNode = x.parent;
|
|
221
|
-
while (y !==
|
|
236
|
+
while (y !== NIL && x === y.left) {
|
|
222
237
|
x = y;
|
|
223
238
|
y = y.parent;
|
|
224
239
|
}
|
|
@@ -226,6 +241,65 @@ export class RedBlackTree {
|
|
|
226
241
|
return y;
|
|
227
242
|
}
|
|
228
243
|
|
|
244
|
+
print(beginRoot: RBTreeNode = this.root) {
|
|
245
|
+
const display = (root: RBTreeNode | null): void => {
|
|
246
|
+
const [lines, , ,] = _displayAux(root);
|
|
247
|
+
for (const line of lines) {
|
|
248
|
+
console.log(line);
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
const _displayAux = (node: RBTreeNode | null): [string[], number, number, number] => {
|
|
253
|
+
if (node === null) {
|
|
254
|
+
return [[], 0, 0, 0];
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (node.right === null && node.left === null) {
|
|
258
|
+
const line = `${node.key}`;
|
|
259
|
+
const width = line.length;
|
|
260
|
+
const height = 1;
|
|
261
|
+
const middle = Math.floor(width / 2);
|
|
262
|
+
return [[line], width, height, middle];
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (node.right === null) {
|
|
266
|
+
const [lines, n, p, x] = _displayAux(node.left);
|
|
267
|
+
const s = `${node.key}`;
|
|
268
|
+
const u = s.length;
|
|
269
|
+
const first_line = ' '.repeat(x + 1) + '_'.repeat(n - x - 1) + s;
|
|
270
|
+
const second_line = ' '.repeat(x) + '/' + ' '.repeat(n - x - 1 + u);
|
|
271
|
+
const shifted_lines = lines.map(line => line + ' '.repeat(u));
|
|
272
|
+
return [[first_line, second_line, ...shifted_lines], n + u, p + 2, n + Math.floor(u / 2)];
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (node.left === null) {
|
|
276
|
+
const [lines, n, p, u] = _displayAux(node.right);
|
|
277
|
+
const s = `${node.key}`;
|
|
278
|
+
const x = s.length;
|
|
279
|
+
const first_line = s + '_'.repeat(x) + ' '.repeat(n - x);
|
|
280
|
+
const second_line = ' '.repeat(u + x) + '\\' + ' '.repeat(n - x - 1);
|
|
281
|
+
const shifted_lines = lines.map(line => ' '.repeat(u) + line);
|
|
282
|
+
return [[first_line, second_line, ...shifted_lines], n + x, p + 2, Math.floor(u / 2)];
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const [left, n, p, x] = _displayAux(node.left);
|
|
286
|
+
const [right, m, q, y] = _displayAux(node.right);
|
|
287
|
+
const s = `${node.key}`;
|
|
288
|
+
const u = s.length;
|
|
289
|
+
const first_line = ' '.repeat(x + 1) + '_'.repeat(n - x - 1) + s + '_'.repeat(y) + ' '.repeat(m - y);
|
|
290
|
+
const second_line = ' '.repeat(x) + '/' + ' '.repeat(n - x - 1 + u + y) + '\\' + ' '.repeat(m - y - 1);
|
|
291
|
+
if (p < q) {
|
|
292
|
+
left.push(...new Array(q - p).fill(' '.repeat(n)));
|
|
293
|
+
} else if (q < p) {
|
|
294
|
+
right.push(...new Array(p - q).fill(' '.repeat(m)));
|
|
295
|
+
}
|
|
296
|
+
const zipped_lines = left.map((a, i) => a + ' '.repeat(u) + right[i]);
|
|
297
|
+
return [[first_line, second_line, ...zipped_lines], n + m + u, Math.max(p, q) + 2, n + Math.floor(u / 2)];
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
display(beginRoot);
|
|
301
|
+
}
|
|
302
|
+
|
|
229
303
|
/**
|
|
230
304
|
* The function performs a left rotation on a red-black tree node.
|
|
231
305
|
* @param {RBTreeNode} x - The parameter `x` is a RBTreeNode object.
|
|
@@ -233,7 +307,7 @@ export class RedBlackTree {
|
|
|
233
307
|
protected _leftRotate(x: RBTreeNode): void {
|
|
234
308
|
const y: RBTreeNode = x.right;
|
|
235
309
|
x.right = y.left;
|
|
236
|
-
if (y.left !==
|
|
310
|
+
if (y.left !== NIL) {
|
|
237
311
|
y.left.parent = x;
|
|
238
312
|
}
|
|
239
313
|
y.parent = x.parent;
|
|
@@ -256,7 +330,7 @@ export class RedBlackTree {
|
|
|
256
330
|
protected _rightRotate(x: RBTreeNode): void {
|
|
257
331
|
const y: RBTreeNode = x.left;
|
|
258
332
|
x.left = y.right;
|
|
259
|
-
if (y.right !==
|
|
333
|
+
if (y.right !== NIL) {
|
|
260
334
|
y.right.parent = x;
|
|
261
335
|
}
|
|
262
336
|
y.parent = x.parent;
|
|
@@ -12,13 +12,13 @@ describe('AVL Tree Test', () => {
|
|
|
12
12
|
expect(node6 && tree.getHeight(node6)).toBe(3);
|
|
13
13
|
expect(node6 && tree.getDepth(node6)).toBe(1);
|
|
14
14
|
|
|
15
|
-
const
|
|
16
|
-
expect(
|
|
15
|
+
const getValueById = tree.get(10);
|
|
16
|
+
expect(getValueById).toBe(10);
|
|
17
17
|
|
|
18
18
|
const getMinNodeByRoot = tree.getLeftMost();
|
|
19
19
|
expect(getMinNodeByRoot?.key).toBe(1);
|
|
20
20
|
|
|
21
|
-
const node15 = tree.
|
|
21
|
+
const node15 = tree.getNode(15);
|
|
22
22
|
const getMinNodeBySpecificNode = node15 && tree.getLeftMost(node15);
|
|
23
23
|
expect(getMinNodeBySpecificNode?.key).toBe(12);
|
|
24
24
|
|
|
@@ -20,16 +20,16 @@ describe('Individual package BST operations test', () => {
|
|
|
20
20
|
expect(node6 && bst.getHeight(6)).toBe(2);
|
|
21
21
|
expect(node6 && bst.getDepth(6)).toBe(3);
|
|
22
22
|
|
|
23
|
-
const nodeId10 = bst.
|
|
23
|
+
const nodeId10 = bst.getNode(10);
|
|
24
24
|
expect(nodeId10?.key).toBe(10);
|
|
25
25
|
|
|
26
|
-
const nodeVal9 = bst.
|
|
26
|
+
const nodeVal9 = bst.getNode(9, node => node.value);
|
|
27
27
|
expect(nodeVal9?.key).toBe(9);
|
|
28
28
|
|
|
29
29
|
const leftMost = bst.getLeftMost();
|
|
30
30
|
expect(leftMost?.key).toBe(1);
|
|
31
31
|
|
|
32
|
-
const node15 = bst.
|
|
32
|
+
const node15 = bst.getNode(15);
|
|
33
33
|
const minNodeBySpecificNode = node15 && bst.getLeftMost(node15);
|
|
34
34
|
expect(minNodeBySpecificNode?.key).toBe(12);
|
|
35
35
|
|
|
@@ -43,7 +43,7 @@ describe('Individual package BST operations test', () => {
|
|
|
43
43
|
|
|
44
44
|
expect(node15).toBeInstanceOf(BSTNode);
|
|
45
45
|
|
|
46
|
-
const node11 = bst.
|
|
46
|
+
const node11 = bst.getNode(11);
|
|
47
47
|
expect(node11).toBeInstanceOf(BSTNode);
|
|
48
48
|
|
|
49
49
|
const dfsInorderNodes = bst.dfs(node => node, 'in');
|
|
@@ -216,7 +216,7 @@ describe('Individual package BST operations test', () => {
|
|
|
216
216
|
|
|
217
217
|
expect(objBST.has(6)).toBe(true);
|
|
218
218
|
|
|
219
|
-
const node6 = objBST.
|
|
219
|
+
const node6 = objBST.getNode(6);
|
|
220
220
|
expect(node6 && objBST.getHeight(node6)).toBe(2);
|
|
221
221
|
expect(node6 && objBST.getDepth(node6)).toBe(3);
|
|
222
222
|
|
|
@@ -229,7 +229,7 @@ describe('Individual package BST operations test', () => {
|
|
|
229
229
|
const leftMost = objBST.getLeftMost();
|
|
230
230
|
expect(leftMost?.key).toBe(1);
|
|
231
231
|
|
|
232
|
-
const node15 = objBST.
|
|
232
|
+
const node15 = objBST.getNode(15);
|
|
233
233
|
expect(node15?.value).toEqual({key: 15, keyA: 15});
|
|
234
234
|
const minNodeBySpecificNode = node15 && objBST.getLeftMost(node15);
|
|
235
235
|
expect(minNodeBySpecificNode?.key).toBe(12);
|
|
@@ -244,7 +244,7 @@ describe('Individual package BST operations test', () => {
|
|
|
244
244
|
|
|
245
245
|
expect(node15).toBeInstanceOf(BSTNode);
|
|
246
246
|
|
|
247
|
-
const node11 = objBST.
|
|
247
|
+
const node11 = objBST.getNode(11);
|
|
248
248
|
expect(node11).toBeInstanceOf(BSTNode);
|
|
249
249
|
|
|
250
250
|
const dfsInorderNodes = objBST.dfs(node => node, 'in');
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {Deque} from "../../../../src";
|
|
2
|
+
import * as Benchmark from 'benchmark';
|
|
3
|
+
|
|
4
|
+
export const suite = new Benchmark.Suite();
|
|
5
|
+
|
|
6
|
+
suite
|
|
7
|
+
.add('push', () => {
|
|
8
|
+
const deque = new Deque<number>();
|
|
9
|
+
for (let i = 0; i < 10; i++) {
|
|
10
|
+
deque.push(i);
|
|
11
|
+
}
|
|
12
|
+
})
|
|
13
|
+
.add('shift', () => {
|
|
14
|
+
const deque = new Deque<number>();
|
|
15
|
+
for (let i = 0; i < 10; i++) {
|
|
16
|
+
deque.push(i);
|
|
17
|
+
deque.shift();
|
|
18
|
+
}
|
|
19
|
+
})
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {Queue} from "../../../../src";
|
|
2
|
+
|
|
3
|
+
import * as Benchmark from 'benchmark';
|
|
4
|
+
|
|
5
|
+
export const suite = new Benchmark.Suite();
|
|
6
|
+
|
|
7
|
+
suite
|
|
8
|
+
.add('push', () => {
|
|
9
|
+
const queue = new Queue<number>();
|
|
10
|
+
for (let i = 0; i < 1000000; i++) {
|
|
11
|
+
queue.push(i);
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
// .add('shift', () => {
|
|
15
|
+
// const queue = new Queue<number>();
|
|
16
|
+
// for (let i = 0; i < 10000; i++) {
|
|
17
|
+
// queue.push(i);
|
|
18
|
+
// queue.shift();
|
|
19
|
+
// }
|
|
20
|
+
// })
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import * as Benchmark from 'benchmark';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import * as fastGlob from 'fast-glob';
|
|
5
|
+
|
|
6
|
+
const reportDistPath = 'benchmark';
|
|
7
|
+
const testDir = path.join(__dirname, 'data-structures');
|
|
8
|
+
const testFiles = fastGlob.sync(path.join(testDir, '**', '*.test.ts'));
|
|
9
|
+
|
|
10
|
+
const report: {[key: string] : any} = {};
|
|
11
|
+
|
|
12
|
+
let i = 0;
|
|
13
|
+
testFiles.forEach((file: string) => {
|
|
14
|
+
i++;
|
|
15
|
+
console.log(`testing file ${file}`);
|
|
16
|
+
const testName = path.basename(file, '.test.ts');
|
|
17
|
+
const testFunction = require(file);
|
|
18
|
+
const {suite} = testFunction;
|
|
19
|
+
|
|
20
|
+
if (suite) {
|
|
21
|
+
suite.on('cycle', (event: any) => {
|
|
22
|
+
console.log(String(event.target));
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
suite.on('complete', function (this: Benchmark.Suite) {
|
|
26
|
+
console.log('Fastest is ' + this.filter('fastest').map('name'));
|
|
27
|
+
report[testName] = this.map((test: Benchmark) => ({
|
|
28
|
+
name: test.name,
|
|
29
|
+
periodMS: test.times.period * 1000,
|
|
30
|
+
hz: test.hz,
|
|
31
|
+
count: test.count,
|
|
32
|
+
mean: test.stats.mean,
|
|
33
|
+
deviation: test.stats.deviation,
|
|
34
|
+
}));
|
|
35
|
+
// report[testName] = this;
|
|
36
|
+
console.log('----i', i, testFiles.length)
|
|
37
|
+
if (testFiles.length === i) {
|
|
38
|
+
if (!fs.existsSync(reportDistPath)) fs.mkdirSync(reportDistPath, { recursive: true });
|
|
39
|
+
|
|
40
|
+
const filePath = path.join(reportDistPath, 'report.json');
|
|
41
|
+
fs.writeFileSync(filePath, JSON.stringify(report, null, 2));
|
|
42
|
+
console.log('Performance test report file generated')
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
.run({async: true});
|
|
46
|
+
}
|
|
47
|
+
});
|