data-structure-typed 1.50.6 → 1.50.8
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 +27 -24
- package/benchmark/report.html +1 -37
- package/benchmark/report.json +17 -395
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +2 -2
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js +6 -4
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +3 -3
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +36 -33
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/bst.d.ts +7 -5
- package/dist/cjs/data-structures/binary-tree/bst.js +68 -47
- package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +2 -8
- package/dist/cjs/data-structures/binary-tree/rb-tree.js +7 -17
- 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 -2
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +1 -1
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
- package/dist/cjs/types/common.d.ts +5 -22
- package/dist/cjs/types/common.js +0 -33
- package/dist/cjs/types/common.js.map +1 -1
- package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +2 -2
- package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.js +6 -4
- package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +3 -3
- package/dist/mjs/data-structures/binary-tree/binary-tree.js +36 -33
- package/dist/mjs/data-structures/binary-tree/bst.d.ts +7 -5
- package/dist/mjs/data-structures/binary-tree/bst.js +68 -47
- package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +2 -8
- package/dist/mjs/data-structures/binary-tree/rb-tree.js +7 -17
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.d.ts +1 -2
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.js +2 -2
- package/dist/mjs/types/common.d.ts +5 -22
- package/dist/mjs/types/common.js +1 -32
- package/dist/umd/data-structure-typed.js +112 -138
- package/dist/umd/data-structure-typed.min.js +2 -2
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +6 -6
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +8 -5
- package/src/data-structures/binary-tree/avl-tree.ts +1 -1
- package/src/data-structures/binary-tree/binary-tree.ts +35 -36
- package/src/data-structures/binary-tree/bst.ts +67 -44
- package/src/data-structures/binary-tree/rb-tree.ts +11 -22
- package/src/data-structures/binary-tree/tree-multi-map.ts +2 -2
- package/src/types/common.ts +6 -23
- package/test/integration/all-in-one.test.ts +2 -2
- package/test/integration/avl-tree.test.ts +1 -1
- package/test/integration/bst.test.ts +2 -2
- package/test/performance/data-structures/binary-tree/rb-tree.test.ts +13 -22
- package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +12 -17
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +4 -4
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +118 -65
- package/test/unit/data-structures/binary-tree/bst.test.ts +12 -12
- package/test/unit/data-structures/binary-tree/overall.test.ts +7 -7
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +272 -267
- package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +249 -245
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BinaryTreeNode, BSTNode,
|
|
1
|
+
import { BinaryTreeNode, BSTNode, RBTNColor, RedBlackTree, RedBlackTreeNode } from '../../../../src';
|
|
2
2
|
import { getRandomInt, getRandomIntArray, magnitude } from '../../../utils';
|
|
3
3
|
import { OrderedMap } from 'js-sdsl';
|
|
4
4
|
|
|
@@ -8,136 +8,141 @@ const isDebug = isDebugTest;
|
|
|
8
8
|
// const isDebug = true;
|
|
9
9
|
|
|
10
10
|
describe('RedBlackTree 1', () => {
|
|
11
|
-
let
|
|
11
|
+
let rbTree: RedBlackTree<number>;
|
|
12
12
|
|
|
13
13
|
beforeEach(() => {
|
|
14
|
-
|
|
14
|
+
rbTree = new RedBlackTree<number>();
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
describe('add and getNode', () => {
|
|
18
|
-
it('should add and find a node in the
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
expect(
|
|
24
|
-
expect(
|
|
25
|
-
expect(
|
|
26
|
-
expect(
|
|
18
|
+
it('should add and find a node in the rbTree', () => {
|
|
19
|
+
rbTree.add(10);
|
|
20
|
+
rbTree.add(20);
|
|
21
|
+
rbTree.add(5);
|
|
22
|
+
|
|
23
|
+
expect(rbTree.getNode(10)).toBeInstanceOf(RedBlackTreeNode);
|
|
24
|
+
expect(rbTree.getNode(20)).toBeInstanceOf(RedBlackTreeNode);
|
|
25
|
+
expect(rbTree.getNode(5)).toBeInstanceOf(RedBlackTreeNode);
|
|
26
|
+
expect(rbTree.getNode(15)).toBe(undefined);
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
it('should add and find nodes with negative keys', () => {
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
rbTree.add(-10);
|
|
31
|
+
rbTree.add(-20);
|
|
32
32
|
|
|
33
|
-
expect(
|
|
34
|
-
expect(
|
|
33
|
+
expect(rbTree.getNode(-10)).toBeInstanceOf(RedBlackTreeNode);
|
|
34
|
+
expect(rbTree.getNode(-20)).toBeInstanceOf(RedBlackTreeNode);
|
|
35
35
|
});
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
describe('deleteNode', () => {
|
|
39
|
-
it('should delete a node from the
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
it('should delete a node from the rbTree', () => {
|
|
40
|
+
rbTree.add(10);
|
|
41
|
+
rbTree.add(20);
|
|
42
|
+
rbTree.add(5);
|
|
43
|
+
rbTree.delete(20);
|
|
44
44
|
|
|
45
|
-
expect(
|
|
45
|
+
expect(rbTree.getNode(20)).toBe(undefined);
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
it('should handle deleting a non-existent node', () => {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
rbTree.add(10);
|
|
50
|
+
rbTree.add(20);
|
|
51
|
+
rbTree.add(5);
|
|
52
|
+
rbTree.delete(15);
|
|
53
53
|
|
|
54
|
-
expect(
|
|
54
|
+
expect(rbTree.getNode(15)).toBe(undefined);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should getNode performance O(log n)', () => {
|
|
58
|
+
for (let i = 0; i < 10; i++) rbTree.add(i);
|
|
59
|
+
rbTree.getNode(6);
|
|
55
60
|
});
|
|
56
61
|
});
|
|
57
62
|
|
|
58
63
|
describe('minimum', () => {
|
|
59
|
-
it('should find the minimum node in the
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const minNode =
|
|
64
|
+
it('should find the minimum node in the rbTree', () => {
|
|
65
|
+
rbTree.add(10);
|
|
66
|
+
rbTree.add(20);
|
|
67
|
+
rbTree.add(5);
|
|
68
|
+
rbTree.add(15);
|
|
69
|
+
rbTree.add(3);
|
|
70
|
+
|
|
71
|
+
const minNode = rbTree.getLeftMost(rbTree.root);
|
|
67
72
|
expect(minNode?.key).toBe(3);
|
|
68
73
|
});
|
|
69
74
|
|
|
70
|
-
it('should handle an empty
|
|
71
|
-
const minNode =
|
|
72
|
-
expect(minNode).toBe(
|
|
75
|
+
it('should handle an empty rbTree', () => {
|
|
76
|
+
const minNode = rbTree.getLeftMost(rbTree.root);
|
|
77
|
+
expect(minNode).toBe(rbTree.SENTINEL);
|
|
73
78
|
});
|
|
74
79
|
});
|
|
75
80
|
|
|
76
81
|
describe('getRightMost', () => {
|
|
77
|
-
it('should find the getRightMost node in the
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const maxNode =
|
|
82
|
+
it('should find the getRightMost node in the rbTree', () => {
|
|
83
|
+
rbTree.add(10);
|
|
84
|
+
rbTree.add(20);
|
|
85
|
+
rbTree.add(5);
|
|
86
|
+
rbTree.add(15);
|
|
87
|
+
rbTree.add(25);
|
|
88
|
+
|
|
89
|
+
const maxNode = rbTree.getRightMost(rbTree.root);
|
|
85
90
|
expect(maxNode?.key).toBe(25);
|
|
86
91
|
});
|
|
87
92
|
|
|
88
|
-
it('should handle an empty
|
|
89
|
-
const maxNode =
|
|
90
|
-
expect(maxNode).toBe(
|
|
93
|
+
it('should handle an empty rbTree', () => {
|
|
94
|
+
const maxNode = rbTree.getRightMost(rbTree.root);
|
|
95
|
+
expect(maxNode).toBe(rbTree.SENTINEL);
|
|
91
96
|
});
|
|
92
97
|
});
|
|
93
98
|
|
|
94
99
|
describe('getSuccessor', () => {
|
|
95
100
|
it('should find the getSuccessor of a node', () => {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
+
rbTree.add(10);
|
|
102
|
+
rbTree.add(20);
|
|
103
|
+
rbTree.add(5);
|
|
104
|
+
rbTree.add(15);
|
|
105
|
+
rbTree.add(25);
|
|
101
106
|
|
|
102
|
-
const node =
|
|
103
|
-
const successorNode =
|
|
107
|
+
const node = rbTree.getNode(15);
|
|
108
|
+
const successorNode = rbTree.getSuccessor(node!);
|
|
104
109
|
|
|
105
110
|
expect(successorNode?.key).toBe(20);
|
|
106
111
|
});
|
|
107
112
|
|
|
108
113
|
it('should handle a node with no getSuccessor', () => {
|
|
109
|
-
|
|
110
|
-
|
|
114
|
+
rbTree.add(10);
|
|
115
|
+
rbTree.add(5);
|
|
111
116
|
|
|
112
|
-
const node =
|
|
113
|
-
const successorNode =
|
|
114
|
-
// TODO not sure if it should be undefined or
|
|
117
|
+
const node = rbTree.getNode(10);
|
|
118
|
+
const successorNode = rbTree.getSuccessor(node!);
|
|
119
|
+
// TODO not sure if it should be undefined or rbTree.SENTINEL
|
|
115
120
|
expect(successorNode).toBe(undefined);
|
|
116
121
|
});
|
|
117
122
|
});
|
|
118
123
|
|
|
119
124
|
describe('getPredecessor', () => {
|
|
120
125
|
it('should find the getPredecessor of a node', () => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
+
rbTree.add(10);
|
|
127
|
+
rbTree.add(20);
|
|
128
|
+
rbTree.add(5);
|
|
129
|
+
rbTree.add(15);
|
|
130
|
+
rbTree.add(25);
|
|
126
131
|
|
|
127
|
-
const node =
|
|
128
|
-
const predecessorNode =
|
|
132
|
+
const node = rbTree.getNode(20);
|
|
133
|
+
const predecessorNode = rbTree.getPredecessor(node!);
|
|
129
134
|
|
|
130
135
|
expect(predecessorNode?.key).toBe(15);
|
|
131
136
|
});
|
|
132
137
|
|
|
133
138
|
it('should handle a node with no getPredecessor', () => {
|
|
134
|
-
|
|
135
|
-
|
|
139
|
+
rbTree.add(10);
|
|
140
|
+
rbTree.add(20);
|
|
136
141
|
|
|
137
|
-
const node =
|
|
138
|
-
const predecessorNode =
|
|
139
|
-
// TODO not sure if it should be
|
|
140
|
-
expect(predecessorNode).toBe(
|
|
142
|
+
const node = rbTree.getNode(20);
|
|
143
|
+
const predecessorNode = rbTree.getPredecessor(node!);
|
|
144
|
+
// TODO not sure if it should be rbTree.SENTINEL or something else.
|
|
145
|
+
expect(predecessorNode).toBe(rbTree.getNode(20));
|
|
141
146
|
});
|
|
142
147
|
});
|
|
143
148
|
|
|
@@ -180,83 +185,83 @@ describe('RedBlackTree 1', () => {
|
|
|
180
185
|
});
|
|
181
186
|
|
|
182
187
|
describe('RedBlackTree 2', () => {
|
|
183
|
-
let
|
|
188
|
+
let rbTree: RedBlackTree<number>;
|
|
184
189
|
|
|
185
190
|
beforeEach(() => {
|
|
186
|
-
|
|
191
|
+
rbTree = new RedBlackTree<number>();
|
|
187
192
|
});
|
|
188
193
|
|
|
189
|
-
it('should add nodes into the
|
|
190
|
-
|
|
191
|
-
expect(
|
|
192
|
-
|
|
193
|
-
expect(
|
|
194
|
-
|
|
195
|
-
expect(
|
|
194
|
+
it('should add nodes into the rbTree', () => {
|
|
195
|
+
rbTree.add(10);
|
|
196
|
+
expect(rbTree.getNode(10)).toBeDefined();
|
|
197
|
+
rbTree.add(20);
|
|
198
|
+
expect(rbTree.getNode(20)).toBeDefined();
|
|
199
|
+
rbTree.add(5);
|
|
200
|
+
expect(rbTree.getNode(5)).toBeDefined();
|
|
196
201
|
});
|
|
197
202
|
|
|
198
|
-
it('should delete nodes from the
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
expect(
|
|
203
|
+
it('should delete nodes from the rbTree', () => {
|
|
204
|
+
rbTree.add(10);
|
|
205
|
+
rbTree.add(20);
|
|
206
|
+
rbTree.add(5);
|
|
207
|
+
rbTree.delete(20);
|
|
208
|
+
expect(rbTree.getNode(20)).toBe(undefined);
|
|
204
209
|
});
|
|
205
210
|
|
|
206
211
|
it('should get the successor of a node', () => {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const node =
|
|
210
|
-
const successor =
|
|
212
|
+
rbTree.add(10);
|
|
213
|
+
rbTree.add(20);
|
|
214
|
+
const node = rbTree.getNode(10);
|
|
215
|
+
const successor = rbTree.getSuccessor(node!);
|
|
211
216
|
expect(successor?.key).toBe(20);
|
|
212
217
|
});
|
|
213
218
|
|
|
214
219
|
it('should get the predecessor of a node', () => {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
const node =
|
|
218
|
-
const predecessor =
|
|
220
|
+
rbTree.add(10);
|
|
221
|
+
rbTree.add(20);
|
|
222
|
+
const node = rbTree.getNode(20);
|
|
223
|
+
const predecessor = rbTree.getPredecessor(node!);
|
|
219
224
|
expect(predecessor?.key).toBe(20);
|
|
220
225
|
});
|
|
221
226
|
|
|
222
227
|
it('should rotate nodes to the left', () => {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
const node =
|
|
227
|
-
|
|
228
|
+
rbTree.add(10);
|
|
229
|
+
rbTree.add(20);
|
|
230
|
+
rbTree.add(5);
|
|
231
|
+
const node = rbTree.getNode(10);
|
|
232
|
+
rbTree.add(15);
|
|
228
233
|
// Verify that rotation has occurred
|
|
229
234
|
expect(node?.left?.key).toBe(5);
|
|
230
235
|
expect(node?.right?.key).toBe(20);
|
|
231
236
|
});
|
|
232
237
|
|
|
233
238
|
it('should rotate nodes to the right', () => {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
const node =
|
|
238
|
-
|
|
239
|
+
rbTree.add(10);
|
|
240
|
+
rbTree.add(20);
|
|
241
|
+
rbTree.add(5);
|
|
242
|
+
const node = rbTree.getNode(20);
|
|
243
|
+
rbTree.add(25);
|
|
239
244
|
// Verify that rotation has occurred
|
|
240
245
|
expect(node?.left?.key).toBeNaN();
|
|
241
246
|
expect(node?.right?.key).toBe(25);
|
|
242
247
|
});
|
|
243
248
|
|
|
244
|
-
it('should all node attributes fully conform to the red-black
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
let node10F =
|
|
254
|
-
let node20F =
|
|
255
|
-
let node5F =
|
|
256
|
-
let node15F =
|
|
257
|
-
let node21F =
|
|
258
|
-
let node6F =
|
|
259
|
-
let node2F =
|
|
249
|
+
it('should all node attributes fully conform to the red-black rbTree standards.', () => {
|
|
250
|
+
rbTree.add(10);
|
|
251
|
+
rbTree.add(20);
|
|
252
|
+
rbTree.add(5);
|
|
253
|
+
rbTree.add(15);
|
|
254
|
+
rbTree.add(21);
|
|
255
|
+
rbTree.add(6);
|
|
256
|
+
rbTree.add(2);
|
|
257
|
+
|
|
258
|
+
let node10F = rbTree.getNode(10);
|
|
259
|
+
let node20F = rbTree.getNode(20);
|
|
260
|
+
let node5F = rbTree.getNode(5);
|
|
261
|
+
let node15F = rbTree.getNode(15);
|
|
262
|
+
let node21F = rbTree.getNode(21);
|
|
263
|
+
let node6F = rbTree.getNode(6);
|
|
264
|
+
let node2F = rbTree.getNode(2);
|
|
260
265
|
expect(node10F?.key).toBe(10);
|
|
261
266
|
expect(node10F?.color).toBe(RBTNColor.BLACK);
|
|
262
267
|
expect(node10F?.left).toBe(node5F);
|
|
@@ -274,37 +279,37 @@ describe('RedBlackTree 2', () => {
|
|
|
274
279
|
expect(node5F?.parent).toBe(node10F);
|
|
275
280
|
expect(node15F?.key).toBe(15);
|
|
276
281
|
expect(node15F?.color).toBe(RBTNColor.RED);
|
|
277
|
-
expect(node15F?.left).toBe(
|
|
278
|
-
expect(node15F?.right).toBe(
|
|
282
|
+
expect(node15F?.left).toBe(rbTree.SENTINEL);
|
|
283
|
+
expect(node15F?.right).toBe(rbTree.SENTINEL);
|
|
279
284
|
expect(node15F?.parent).toBe(node20F);
|
|
280
285
|
expect(node21F?.key).toBe(21);
|
|
281
286
|
expect(node21F?.color).toBe(RBTNColor.RED);
|
|
282
|
-
expect(node21F?.left).toBe(
|
|
283
|
-
expect(node21F?.right).toBe(
|
|
287
|
+
expect(node21F?.left).toBe(rbTree.SENTINEL);
|
|
288
|
+
expect(node21F?.right).toBe(rbTree.SENTINEL);
|
|
284
289
|
expect(node21F?.parent).toBe(node20F);
|
|
285
290
|
expect(node6F?.key).toBe(6);
|
|
286
291
|
expect(node6F?.color).toBe(RBTNColor.RED);
|
|
287
|
-
expect(node6F?.left).toBe(
|
|
288
|
-
expect(node6F?.right).toBe(
|
|
292
|
+
expect(node6F?.left).toBe(rbTree.SENTINEL);
|
|
293
|
+
expect(node6F?.right).toBe(rbTree.SENTINEL);
|
|
289
294
|
expect(node6F?.parent).toBe(node5F);
|
|
290
295
|
expect(node2F?.key).toBe(2);
|
|
291
296
|
expect(node2F?.color).toBe(RBTNColor.RED);
|
|
292
|
-
expect(node2F?.left).toBe(
|
|
293
|
-
expect(node2F?.right).toBe(
|
|
297
|
+
expect(node2F?.left).toBe(rbTree.SENTINEL);
|
|
298
|
+
expect(node2F?.right).toBe(rbTree.SENTINEL);
|
|
294
299
|
expect(node2F?.parent).toBe(node5F);
|
|
295
300
|
expect(node15F?.key).toBe(15);
|
|
296
301
|
expect(node15F?.color).toBe(RBTNColor.RED);
|
|
297
|
-
expect(node15F?.left).toBe(
|
|
298
|
-
expect(node15F?.right).toBe(
|
|
302
|
+
expect(node15F?.left).toBe(rbTree.SENTINEL);
|
|
303
|
+
expect(node15F?.right).toBe(rbTree.SENTINEL);
|
|
299
304
|
expect(node15F?.parent).toBe(node20F);
|
|
300
|
-
|
|
301
|
-
node10F =
|
|
302
|
-
node20F =
|
|
303
|
-
node5F =
|
|
304
|
-
node15F =
|
|
305
|
-
node21F =
|
|
306
|
-
node6F =
|
|
307
|
-
node2F =
|
|
305
|
+
rbTree.delete(5);
|
|
306
|
+
node10F = rbTree.getNode(10);
|
|
307
|
+
node20F = rbTree.getNode(20);
|
|
308
|
+
node5F = rbTree.getNode(5);
|
|
309
|
+
node15F = rbTree.getNode(15);
|
|
310
|
+
node21F = rbTree.getNode(21);
|
|
311
|
+
node6F = rbTree.getNode(6);
|
|
312
|
+
node2F = rbTree.getNode(2);
|
|
308
313
|
expect(node10F?.key).toBe(10);
|
|
309
314
|
expect(node10F?.color).toBe(RBTNColor.BLACK);
|
|
310
315
|
expect(node10F?.left).toBe(node6F);
|
|
@@ -318,37 +323,37 @@ describe('RedBlackTree 2', () => {
|
|
|
318
323
|
expect(node5F).toBe(undefined);
|
|
319
324
|
expect(node15F?.key).toBe(15);
|
|
320
325
|
expect(node15F?.color).toBe(RBTNColor.RED);
|
|
321
|
-
expect(node15F?.left).toBe(
|
|
322
|
-
expect(node15F?.right).toBe(
|
|
326
|
+
expect(node15F?.left).toBe(rbTree.SENTINEL);
|
|
327
|
+
expect(node15F?.right).toBe(rbTree.SENTINEL);
|
|
323
328
|
expect(node15F?.parent).toBe(node20F);
|
|
324
329
|
expect(node21F?.key).toBe(21);
|
|
325
330
|
expect(node21F?.color).toBe(RBTNColor.RED);
|
|
326
|
-
expect(node21F?.left).toBe(
|
|
327
|
-
expect(node21F?.right).toBe(
|
|
331
|
+
expect(node21F?.left).toBe(rbTree.SENTINEL);
|
|
332
|
+
expect(node21F?.right).toBe(rbTree.SENTINEL);
|
|
328
333
|
expect(node21F?.parent).toBe(node20F);
|
|
329
334
|
expect(node6F?.key).toBe(6);
|
|
330
335
|
expect(node6F?.color).toBe(RBTNColor.BLACK);
|
|
331
336
|
expect(node6F?.left).toBe(node2F);
|
|
332
|
-
expect(node6F?.right).toBe(
|
|
337
|
+
expect(node6F?.right).toBe(rbTree.SENTINEL);
|
|
333
338
|
expect(node6F?.parent).toBe(node10F);
|
|
334
339
|
expect(node2F?.key).toBe(2);
|
|
335
340
|
expect(node2F?.color).toBe(RBTNColor.RED);
|
|
336
|
-
expect(node2F?.left).toBe(
|
|
337
|
-
expect(node2F?.right).toBe(
|
|
341
|
+
expect(node2F?.left).toBe(rbTree.SENTINEL);
|
|
342
|
+
expect(node2F?.right).toBe(rbTree.SENTINEL);
|
|
338
343
|
expect(node2F?.parent).toBe(node6F);
|
|
339
344
|
expect(node15F?.key).toBe(15);
|
|
340
345
|
expect(node15F?.color).toBe(RBTNColor.RED);
|
|
341
|
-
expect(node15F?.left).toBe(
|
|
342
|
-
expect(node15F?.right).toBe(
|
|
346
|
+
expect(node15F?.left).toBe(rbTree.SENTINEL);
|
|
347
|
+
expect(node15F?.right).toBe(rbTree.SENTINEL);
|
|
343
348
|
expect(node15F?.parent).toBe(node20F);
|
|
344
|
-
|
|
345
|
-
node10F =
|
|
346
|
-
node20F =
|
|
347
|
-
node5F =
|
|
348
|
-
node15F =
|
|
349
|
-
node21F =
|
|
350
|
-
node6F =
|
|
351
|
-
node2F =
|
|
349
|
+
rbTree.delete(20);
|
|
350
|
+
node10F = rbTree.getNode(10);
|
|
351
|
+
node20F = rbTree.getNode(20);
|
|
352
|
+
node5F = rbTree.getNode(5);
|
|
353
|
+
node15F = rbTree.getNode(15);
|
|
354
|
+
node21F = rbTree.getNode(21);
|
|
355
|
+
node6F = rbTree.getNode(6);
|
|
356
|
+
node2F = rbTree.getNode(2);
|
|
352
357
|
expect(node10F?.key).toBe(10);
|
|
353
358
|
expect(node10F?.color).toBe(RBTNColor.BLACK);
|
|
354
359
|
expect(node10F?.left).toBe(node6F);
|
|
@@ -358,167 +363,167 @@ describe('RedBlackTree 2', () => {
|
|
|
358
363
|
expect(node5F).toBe(undefined);
|
|
359
364
|
expect(node15F?.key).toBe(15);
|
|
360
365
|
expect(node15F?.color).toBe(RBTNColor.RED);
|
|
361
|
-
expect(node15F?.left).toBe(
|
|
362
|
-
expect(node15F?.right).toBe(
|
|
366
|
+
expect(node15F?.left).toBe(rbTree.SENTINEL);
|
|
367
|
+
expect(node15F?.right).toBe(rbTree.SENTINEL);
|
|
363
368
|
expect(node15F?.parent).toBe(node21F);
|
|
364
369
|
expect(node21F?.key).toBe(21);
|
|
365
370
|
expect(node21F?.color).toBe(RBTNColor.BLACK);
|
|
366
371
|
expect(node21F?.left).toBe(node15F);
|
|
367
|
-
expect(node21F?.right).toBe(
|
|
372
|
+
expect(node21F?.right).toBe(rbTree.SENTINEL);
|
|
368
373
|
expect(node21F?.parent).toBe(node10F);
|
|
369
374
|
expect(node6F?.key).toBe(6);
|
|
370
375
|
expect(node6F?.color).toBe(RBTNColor.BLACK);
|
|
371
376
|
expect(node6F?.left).toBe(node2F);
|
|
372
|
-
expect(node6F?.right).toBe(
|
|
377
|
+
expect(node6F?.right).toBe(rbTree.SENTINEL);
|
|
373
378
|
expect(node6F?.parent).toBe(node10F);
|
|
374
379
|
expect(node2F?.key).toBe(2);
|
|
375
380
|
expect(node2F?.color).toBe(RBTNColor.RED);
|
|
376
|
-
expect(node2F?.left).toBe(
|
|
377
|
-
expect(node2F?.right).toBe(
|
|
381
|
+
expect(node2F?.left).toBe(rbTree.SENTINEL);
|
|
382
|
+
expect(node2F?.right).toBe(rbTree.SENTINEL);
|
|
378
383
|
expect(node2F?.parent).toBe(node6F);
|
|
379
384
|
expect(node15F?.key).toBe(15);
|
|
380
385
|
expect(node15F?.color).toBe(RBTNColor.RED);
|
|
381
|
-
expect(node15F?.left).toBe(
|
|
382
|
-
expect(node15F?.right).toBe(
|
|
386
|
+
expect(node15F?.left).toBe(rbTree.SENTINEL);
|
|
387
|
+
expect(node15F?.right).toBe(rbTree.SENTINEL);
|
|
383
388
|
expect(node15F?.parent).toBe(node21F);
|
|
384
389
|
});
|
|
385
390
|
|
|
386
|
-
it('should fix the
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
const node15F =
|
|
392
|
-
expect(node15F?.left).toBe(
|
|
393
|
-
expect(node15F?.right).toBe(
|
|
394
|
-
expect(node15F?.parent).toBe(
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
const node225F =
|
|
408
|
-
expect(node225F?.left).toBe(
|
|
409
|
-
expect(node225F?.right).toBe(
|
|
391
|
+
it('should fix the rbTree after insertion', () => {
|
|
392
|
+
rbTree.add(1);
|
|
393
|
+
rbTree.add(2);
|
|
394
|
+
rbTree.add(5);
|
|
395
|
+
rbTree.add(15);
|
|
396
|
+
const node15F = rbTree.getNode(15);
|
|
397
|
+
expect(node15F?.left).toBe(rbTree.SENTINEL);
|
|
398
|
+
expect(node15F?.right).toBe(rbTree.SENTINEL);
|
|
399
|
+
expect(node15F?.parent).toBe(rbTree.getNode(5));
|
|
400
|
+
|
|
401
|
+
rbTree.add(25);
|
|
402
|
+
rbTree.add(10);
|
|
403
|
+
rbTree.add(8);
|
|
404
|
+
rbTree.add(28);
|
|
405
|
+
rbTree.add(111);
|
|
406
|
+
rbTree.add(12);
|
|
407
|
+
rbTree.delete(2);
|
|
408
|
+
rbTree.add(22);
|
|
409
|
+
rbTree.add(50);
|
|
410
|
+
rbTree.add(155);
|
|
411
|
+
rbTree.add(225);
|
|
412
|
+
const node225F = rbTree.getNode(225);
|
|
413
|
+
expect(node225F?.left).toBe(rbTree.SENTINEL);
|
|
414
|
+
expect(node225F?.right).toBe(rbTree.SENTINEL);
|
|
410
415
|
expect(node225F?.parent?.key).toBe(155);
|
|
411
|
-
|
|
412
|
-
isDebug &&
|
|
416
|
+
rbTree.add(7);
|
|
417
|
+
isDebug && rbTree.print();
|
|
413
418
|
|
|
414
|
-
const node15S =
|
|
419
|
+
const node15S = rbTree.getNode(15);
|
|
415
420
|
expect(node15S?.left?.key).toBe(10);
|
|
416
421
|
expect(node15S?.right?.key).toBe(25);
|
|
417
|
-
expect(
|
|
422
|
+
expect(rbTree.root).toBe(rbTree.getNode(8));
|
|
418
423
|
expect(node15S?.parent?.key).toBe(28);
|
|
419
|
-
|
|
420
|
-
expect(
|
|
421
|
-
expect(
|
|
424
|
+
rbTree.delete(15);
|
|
425
|
+
expect(rbTree.root?.key).toBe(8);
|
|
426
|
+
expect(rbTree.root?.parent).toBe(undefined);
|
|
422
427
|
|
|
423
|
-
const node15T =
|
|
428
|
+
const node15T = rbTree.getNode(15);
|
|
424
429
|
expect(node15T).toBe(undefined);
|
|
425
430
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
431
|
+
rbTree.add(23);
|
|
432
|
+
rbTree.add(33);
|
|
433
|
+
rbTree.add(15);
|
|
429
434
|
|
|
430
|
-
const nodeLM =
|
|
435
|
+
const nodeLM = rbTree.getLeftMost();
|
|
431
436
|
expect(nodeLM?.key).toBe(1);
|
|
432
437
|
|
|
433
|
-
const node50 =
|
|
438
|
+
const node50 = rbTree.getNode(50);
|
|
434
439
|
expect(node50?.key).toBe(50);
|
|
435
440
|
expect(node50?.left?.key).toBe(33);
|
|
436
|
-
expect(node50?.right).toBe(
|
|
437
|
-
const node15Fo =
|
|
441
|
+
expect(node50?.right).toBe(rbTree.SENTINEL);
|
|
442
|
+
const node15Fo = rbTree.getNode(15);
|
|
438
443
|
|
|
439
444
|
expect(node15Fo?.key).toBe(15);
|
|
440
|
-
expect(node15Fo?.left).toBe(
|
|
441
|
-
const node225S =
|
|
442
|
-
expect(node225S?.left).toBe(
|
|
443
|
-
expect(node225S?.right).toBe(
|
|
445
|
+
expect(node15Fo?.left).toBe(rbTree.SENTINEL);
|
|
446
|
+
const node225S = rbTree.getNode(225);
|
|
447
|
+
expect(node225S?.left).toBe(rbTree.SENTINEL);
|
|
448
|
+
expect(node225S?.right).toBe(rbTree.SENTINEL);
|
|
444
449
|
expect(node225S?.parent?.key).toBe(155);
|
|
445
450
|
// TODO
|
|
446
|
-
// expect(
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
isDebug &&
|
|
462
|
-
|
|
463
|
-
expect(
|
|
451
|
+
// expect(rbTree.getNode(0)).toBe(undefined);
|
|
452
|
+
rbTree.add(2);
|
|
453
|
+
rbTree.add(3);
|
|
454
|
+
rbTree.add(4);
|
|
455
|
+
rbTree.add(6);
|
|
456
|
+
rbTree.add(9);
|
|
457
|
+
rbTree.add(11);
|
|
458
|
+
rbTree.add(13);
|
|
459
|
+
rbTree.add(14);
|
|
460
|
+
rbTree.add(16);
|
|
461
|
+
rbTree.add(17);
|
|
462
|
+
rbTree.add(18);
|
|
463
|
+
rbTree.add(19);
|
|
464
|
+
rbTree.add(110);
|
|
465
|
+
|
|
466
|
+
isDebug && rbTree.print();
|
|
467
|
+
|
|
468
|
+
expect(rbTree.dfs()).toEqual([
|
|
464
469
|
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
|
|
465
470
|
]);
|
|
466
471
|
|
|
467
|
-
expect(
|
|
472
|
+
expect(rbTree.isBST()).toBe(true);
|
|
468
473
|
});
|
|
469
474
|
|
|
470
|
-
it('should fix the
|
|
475
|
+
it('should fix the rbTree after insertion and deletion', () => {
|
|
471
476
|
for (let i = 0; i < 100; i++) {
|
|
472
|
-
|
|
477
|
+
rbTree.add(i);
|
|
473
478
|
}
|
|
474
479
|
for (let i = 0; i < 49; i++) {
|
|
475
|
-
|
|
480
|
+
rbTree.delete(i);
|
|
476
481
|
}
|
|
477
482
|
|
|
478
|
-
expect(
|
|
479
|
-
expect(
|
|
480
|
-
expect(
|
|
483
|
+
expect(rbTree.size).toBe(51);
|
|
484
|
+
expect(rbTree.isBST()).toBe(true);
|
|
485
|
+
expect(rbTree.isBST(rbTree.root, 'RECURSIVE')).toBe(true);
|
|
481
486
|
|
|
482
|
-
expect(
|
|
487
|
+
expect(rbTree.dfs(n => n.key, 'in', rbTree.root, 'ITERATIVE')).toEqual([
|
|
483
488
|
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,
|
|
484
489
|
77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
|
|
485
490
|
]);
|
|
486
|
-
expect(
|
|
491
|
+
expect(rbTree.dfs(n => n.key, 'in', rbTree.root, 'RECURSIVE')).toEqual([
|
|
487
492
|
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,
|
|
488
493
|
77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
|
|
489
494
|
]);
|
|
490
495
|
});
|
|
491
496
|
|
|
492
|
-
it('should fix the
|
|
497
|
+
it('should fix the rbTree after large scale insertion and deletion', () => {
|
|
493
498
|
for (let i = 0; i < 10000; i++) {
|
|
494
|
-
|
|
499
|
+
rbTree.add(i);
|
|
495
500
|
}
|
|
496
501
|
for (let i = 0; i < 10000; i++) {
|
|
497
|
-
|
|
502
|
+
rbTree.delete(i);
|
|
498
503
|
}
|
|
499
504
|
|
|
500
|
-
expect(
|
|
501
|
-
expect(
|
|
502
|
-
expect(
|
|
505
|
+
expect(rbTree.size).toBe(0);
|
|
506
|
+
expect(rbTree.isBST()).toBe(true);
|
|
507
|
+
expect(rbTree.dfs(n => n.key, 'in', rbTree.root, 'ITERATIVE')).toEqual([]);
|
|
503
508
|
|
|
504
|
-
|
|
509
|
+
rbTree.clear();
|
|
505
510
|
for (let i = 0; i < 1000; i++) {
|
|
506
|
-
|
|
507
|
-
|
|
511
|
+
rbTree.add(getRandomInt(-100, 1000));
|
|
512
|
+
rbTree.delete(getRandomInt(-100, 1000));
|
|
508
513
|
}
|
|
509
514
|
|
|
510
|
-
// TODO there is a bug when dfs the
|
|
511
|
-
// expect(
|
|
515
|
+
// TODO there is a bug when dfs the rbTree with SENTINEL node
|
|
516
|
+
// expect(rbTree.isBST()).toBe(true);
|
|
512
517
|
});
|
|
513
518
|
const { HUNDRED_THOUSAND } = magnitude;
|
|
514
519
|
const arr = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND, true);
|
|
515
520
|
const competitor = new OrderedMap<number, number>();
|
|
516
521
|
|
|
517
|
-
it('should fix the
|
|
518
|
-
|
|
522
|
+
it('should fix the rbTree after large scale insertion and deletion', () => {
|
|
523
|
+
rbTree.clear();
|
|
519
524
|
const tS = performance.now();
|
|
520
525
|
for (let i = 0; i < arr.length; i++) {
|
|
521
|
-
|
|
526
|
+
rbTree.add(arr[i]);
|
|
522
527
|
}
|
|
523
528
|
isDebug && console.log(performance.now() - tS);
|
|
524
529
|
|
|
@@ -531,20 +536,20 @@ describe('RedBlackTree 2', () => {
|
|
|
531
536
|
});
|
|
532
537
|
|
|
533
538
|
it('duplicates', () => {
|
|
534
|
-
|
|
535
|
-
isDebug &&
|
|
536
|
-
|
|
537
|
-
expect(
|
|
538
|
-
expect(
|
|
539
|
-
expect(
|
|
540
|
-
|
|
541
|
-
expect(
|
|
542
|
-
expect(
|
|
543
|
-
expect(
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
expect(
|
|
539
|
+
rbTree.addMany([9, 8, 7, 8, 8, 8, 2, 3, 6, 5, 5, 4]);
|
|
540
|
+
isDebug && rbTree.print();
|
|
541
|
+
|
|
542
|
+
expect(rbTree.size).toBe(8);
|
|
543
|
+
expect(rbTree.isBST()).toBe(true);
|
|
544
|
+
expect(rbTree.isAVLBalanced()).toBe(true);
|
|
545
|
+
rbTree.addMany([10, 5, 2, 11]);
|
|
546
|
+
expect(rbTree.size).toBe(10);
|
|
547
|
+
expect(rbTree.isBST()).toBe(true);
|
|
548
|
+
expect(rbTree.isAVLBalanced()).toBe(true);
|
|
549
|
+
|
|
550
|
+
rbTree.clear();
|
|
551
|
+
rbTree.addMany([10, 20, 30, 40, 50, 60]);
|
|
552
|
+
expect(rbTree.isAVLBalanced()).toBe(false);
|
|
548
553
|
});
|
|
549
554
|
|
|
550
555
|
describe('RedBlackTree delete test', function () {
|
|
@@ -598,7 +603,7 @@ describe('RedBlackTree 2', () => {
|
|
|
598
603
|
if (rbTree.root) dfs(rbTree.root);
|
|
599
604
|
|
|
600
605
|
expect(rbTree.size).toBe(0);
|
|
601
|
-
expect(rbTree.getHeight()).toBe(
|
|
606
|
+
expect(rbTree.getHeight()).toBe(-1);
|
|
602
607
|
expect(nanCount).toBeLessThanOrEqual(inputSize);
|
|
603
608
|
|
|
604
609
|
isDebug && rbTree.print();
|
|
@@ -633,7 +638,7 @@ describe('RedBlackTree 2', () => {
|
|
|
633
638
|
expect(mockCallback.mock.calls[2]).toEqual(['c', 3]);
|
|
634
639
|
});
|
|
635
640
|
|
|
636
|
-
test('filter should return a new
|
|
641
|
+
test('filter should return a new rbTree with filtered elements', () => {
|
|
637
642
|
const filteredTree = rbTree.filter((value, key) => key > 1);
|
|
638
643
|
expect(filteredTree.size).toBe(2);
|
|
639
644
|
expect([...filteredTree]).toEqual([
|
|
@@ -642,7 +647,7 @@ describe('RedBlackTree 2', () => {
|
|
|
642
647
|
]);
|
|
643
648
|
});
|
|
644
649
|
|
|
645
|
-
test('map should return a new
|
|
650
|
+
test('map should return a new rbTree with modified elements', () => {
|
|
646
651
|
const mappedTree = rbTree.map((value, key) => (key * 2).toString());
|
|
647
652
|
expect(mappedTree.size).toBe(3);
|
|
648
653
|
expect([...mappedTree]).toEqual([
|