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