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.
Files changed (47) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +13 -18
  3. package/benchmark/report.html +13 -13
  4. package/benchmark/report.json +167 -143
  5. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -0
  6. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js +3 -0
  7. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
  8. package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
  9. package/dist/cjs/data-structures/binary-tree/binary-tree.js +32 -28
  10. package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
  11. package/dist/cjs/data-structures/binary-tree/bst.js +17 -17
  12. package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
  13. package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +158 -141
  14. package/dist/cjs/data-structures/binary-tree/rb-tree.js +416 -396
  15. package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
  16. package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +1 -0
  17. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +84 -76
  18. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
  19. package/dist/cjs/types/common.d.ts +6 -0
  20. package/dist/cjs/types/common.js +8 -1
  21. package/dist/cjs/types/common.js.map +1 -1
  22. package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -0
  23. package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.js +3 -0
  24. package/dist/mjs/data-structures/binary-tree/binary-tree.js +32 -28
  25. package/dist/mjs/data-structures/binary-tree/bst.js +17 -17
  26. package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +158 -141
  27. package/dist/mjs/data-structures/binary-tree/rb-tree.js +413 -396
  28. package/dist/mjs/data-structures/binary-tree/tree-multi-map.d.ts +1 -0
  29. package/dist/mjs/data-structures/binary-tree/tree-multi-map.js +84 -76
  30. package/dist/mjs/types/common.d.ts +6 -0
  31. package/dist/mjs/types/common.js +7 -0
  32. package/dist/umd/data-structure-typed.js +519 -467
  33. package/dist/umd/data-structure-typed.min.js +2 -2
  34. package/dist/umd/data-structure-typed.min.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +5 -1
  37. package/src/data-structures/binary-tree/avl-tree.ts +1 -1
  38. package/src/data-structures/binary-tree/binary-tree.ts +31 -29
  39. package/src/data-structures/binary-tree/bst.ts +18 -18
  40. package/src/data-structures/binary-tree/rb-tree.ts +436 -405
  41. package/src/data-structures/binary-tree/tree-multi-map.ts +85 -82
  42. package/src/types/common.ts +7 -0
  43. package/test/performance/data-structures/binary-tree/rb-tree.test.ts +26 -16
  44. package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +4 -1
  45. package/test/unit/data-structures/binary-tree/overall.test.ts +23 -21
  46. package/test/unit/data-structures/binary-tree/rb-tree.test.ts +387 -324
  47. 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 tree: RedBlackTree<number>;
10
+ describe('RedBlackTree 1', () => {
11
+ let rbTree: RedBlackTree<number>;
10
12
 
11
13
  beforeEach(() => {
12
- tree = new RedBlackTree<number>();
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 tree', () => {
17
- tree.add(10);
18
- tree.add(20);
19
- tree.add(5);
20
-
21
- expect(tree.getNode(10)).toBeInstanceOf(RedBlackTreeNode);
22
- expect(tree.getNode(20)).toBeInstanceOf(RedBlackTreeNode);
23
- expect(tree.getNode(5)).toBeInstanceOf(RedBlackTreeNode);
24
- expect(tree.getNode(15)).toBe(undefined);
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
- tree.add(-10);
29
- tree.add(-20);
30
+ rbTree.add(-10);
31
+ rbTree.add(-20);
30
32
 
31
- expect(tree.getNode(-10)).toBeInstanceOf(RedBlackTreeNode);
32
- expect(tree.getNode(-20)).toBeInstanceOf(RedBlackTreeNode);
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 tree', () => {
38
- tree.add(10);
39
- tree.add(20);
40
- tree.add(5);
41
- tree.delete(20);
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(tree.getNode(20)).toBe(undefined);
45
+ expect(rbTree.getNode(20)).toBe(undefined);
44
46
  });
45
47
 
46
48
  it('should handle deleting a non-existent node', () => {
47
- tree.add(10);
48
- tree.add(20);
49
- tree.add(5);
50
- tree.delete(15);
49
+ rbTree.add(10);
50
+ rbTree.add(20);
51
+ rbTree.add(5);
52
+ rbTree.delete(15);
51
53
 
52
- expect(tree.getNode(15)).toBe(undefined);
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 tree', () => {
58
- tree.add(10);
59
- tree.add(20);
60
- tree.add(5);
61
- tree.add(15);
62
- tree.add(3);
63
-
64
- const minNode = tree.getLeftMost(tree.root);
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 tree', () => {
69
- const minNode = tree.getLeftMost(tree.root);
70
- expect(minNode).toBe(tree.Sentinel);
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 tree', () => {
76
- tree.add(10);
77
- tree.add(20);
78
- tree.add(5);
79
- tree.add(15);
80
- tree.add(25);
81
-
82
- const maxNode = tree.getRightMost(tree.root);
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 tree', () => {
87
- const maxNode = tree.getRightMost(tree.root);
88
- expect(maxNode).toBe(tree.Sentinel);
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
- tree.add(10);
95
- tree.add(20);
96
- tree.add(5);
97
- tree.add(15);
98
- tree.add(25);
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 = tree.getNode(15);
101
- const successorNode = tree.getSuccessor(node!);
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
- tree.add(10);
108
- tree.add(5);
109
+ rbTree.add(10);
110
+ rbTree.add(5);
109
111
 
110
- const node = tree.getNode(10);
111
- const successorNode = tree.getSuccessor(node!);
112
- // TODO not sure if it should be undefined or tree.Sentinel
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
- tree.add(10);
120
- tree.add(20);
121
- tree.add(5);
122
- tree.add(15);
123
- tree.add(25);
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 = tree.getNode(20);
126
- const predecessorNode = tree.getPredecessor(node!);
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
- tree.add(10);
133
- tree.add(20);
134
+ rbTree.add(10);
135
+ rbTree.add(20);
134
136
 
135
- const node = tree.getNode(20);
136
- const predecessorNode = tree.getPredecessor(node!);
137
- // TODO not sure if it should be tree.Sentinel or something else.
138
- expect(predecessorNode).toBe(tree.getNode(10));
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 tree: RedBlackTree<number>;
183
+ let rbTree: RedBlackTree<number>;
182
184
 
183
185
  beforeEach(() => {
184
- tree = new RedBlackTree<number>();
186
+ rbTree = new RedBlackTree<number>();
185
187
  });
186
188
 
187
- it('should add nodes into the tree', () => {
188
- tree.add(10);
189
- expect(tree.getNode(10)).toBeDefined();
190
- tree.add(20);
191
- expect(tree.getNode(20)).toBeDefined();
192
- tree.add(5);
193
- expect(tree.getNode(5)).toBeDefined();
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 tree', () => {
197
- tree.add(10);
198
- tree.add(20);
199
- tree.add(5);
200
- tree.delete(20);
201
- expect(tree.getNode(20)).toBe(undefined);
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
- tree.add(10);
206
- tree.add(20);
207
- const node = tree.getNode(10);
208
- const successor = tree.getSuccessor(node!);
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
- tree.add(10);
214
- tree.add(20);
215
- const node = tree.getNode(20);
216
- const predecessor = tree.getPredecessor(node!);
217
- expect(predecessor?.key).toBe(10);
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
- tree.add(10);
222
- tree.add(20);
223
- tree.add(5);
224
- const node = tree.getNode(10);
225
- tree.add(15);
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
- tree.add(10);
233
- tree.add(20);
234
- tree.add(5);
235
- const node = tree.getNode(20);
236
- tree.add(25);
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 tree standards.', () => {
243
- tree.add(10);
244
- tree.add(20);
245
- tree.add(5);
246
- tree.add(15);
247
- tree.add(21);
248
- tree.add(6);
249
- tree.add(2);
250
-
251
- let node10F = tree.getNode(10);
252
- let node20F = tree.getNode(20);
253
- let node5F = tree.getNode(5);
254
- let node15F = tree.getNode(15);
255
- let node21F = tree.getNode(21);
256
- let node6F = tree.getNode(6);
257
- let node2F = tree.getNode(2);
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(tree.Sentinel);
276
- expect(node15F?.right).toBe(tree.Sentinel);
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(tree.Sentinel);
281
- expect(node21F?.right).toBe(tree.Sentinel);
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(tree.Sentinel);
286
- expect(node6F?.right).toBe(tree.Sentinel);
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(tree.Sentinel);
291
- expect(node2F?.right).toBe(tree.Sentinel);
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(tree.Sentinel);
296
- expect(node15F?.right).toBe(tree.Sentinel);
297
+ expect(node15F?.left).toBe(rbTree.SENTINEL);
298
+ expect(node15F?.right).toBe(rbTree.SENTINEL);
297
299
  expect(node15F?.parent).toBe(node20F);
298
- tree.delete(5);
299
- node10F = tree.getNode(10);
300
- node20F = tree.getNode(20);
301
- node5F = tree.getNode(5);
302
- node15F = tree.getNode(15);
303
- node21F = tree.getNode(21);
304
- node6F = tree.getNode(6);
305
- node2F = tree.getNode(2);
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(tree.Sentinel);
320
- expect(node15F?.right).toBe(tree.Sentinel);
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(tree.Sentinel);
325
- expect(node21F?.right).toBe(tree.Sentinel);
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(tree.Sentinel);
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(tree.Sentinel);
335
- expect(node2F?.right).toBe(tree.Sentinel);
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(tree.Sentinel);
340
- expect(node15F?.right).toBe(tree.Sentinel);
341
+ expect(node15F?.left).toBe(rbTree.SENTINEL);
342
+ expect(node15F?.right).toBe(rbTree.SENTINEL);
341
343
  expect(node15F?.parent).toBe(node20F);
342
- tree.delete(20);
343
- node10F = tree.getNode(10);
344
- node20F = tree.getNode(20);
345
- node5F = tree.getNode(5);
346
- node15F = tree.getNode(15);
347
- node21F = tree.getNode(21);
348
- node6F = tree.getNode(6);
349
- node2F = tree.getNode(2);
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(tree.Sentinel);
360
- expect(node15F?.right).toBe(tree.Sentinel);
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(tree.Sentinel);
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(tree.Sentinel);
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(tree.Sentinel);
375
- expect(node2F?.right).toBe(tree.Sentinel);
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(tree.Sentinel);
380
- expect(node15F?.right).toBe(tree.Sentinel);
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 tree after insertion', () => {
385
- tree.add(1);
386
- tree.add(2);
387
- tree.add(5);
388
- tree.add(15);
389
- const node15F = tree.getNode(15);
390
- expect(node15F?.left).toBe(tree.Sentinel);
391
- expect(node15F?.right).toBe(tree.Sentinel);
392
- expect(node15F?.parent).toBe(tree.getNode(5));
393
-
394
- tree.add(25);
395
- tree.add(10);
396
- tree.add(8);
397
- tree.add(28);
398
- tree.add(111);
399
- tree.add(12);
400
- tree.delete(2);
401
- tree.add(22);
402
- tree.add(50);
403
- tree.add(155);
404
- tree.add(225);
405
- const node225F = tree.getNode(225);
406
- expect(node225F?.left).toBe(tree.Sentinel);
407
- expect(node225F?.right).toBe(tree.Sentinel);
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
- tree.add(7);
410
-
411
- const node15S = tree.getNode(15);
412
- expect(node15S?.left?.key).toBe(8);
413
- expect(node15S?.right?.key).toBe(28);
414
- expect(node15S).toBe(tree.root);
415
- expect(node15S?.parent).toBe(undefined);
416
- tree.delete(15);
417
- expect(tree.root.key).toBe(22);
418
- expect(tree.root.parent).toBe(undefined);
419
-
420
- const node15T = tree.getNode(15);
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
- tree.add(23);
424
- tree.add(33);
425
- tree.add(15);
426
+ rbTree.add(23);
427
+ rbTree.add(33);
428
+ rbTree.add(15);
426
429
 
427
- const nodeLM = tree.getLeftMost();
430
+ const nodeLM = rbTree.getLeftMost();
428
431
  expect(nodeLM?.key).toBe(1);
429
432
 
430
- const node50 = tree.getNode(50);
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(tree.Sentinel);
434
- const node15Fo = tree.getNode(15);
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(tree.Sentinel);
438
- const node225S = tree.getNode(225);
439
- expect(node225S?.left).toBe(tree.Sentinel);
440
- expect(node225S?.right).toBe(tree.Sentinel);
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(tree.getNode(0)).toBe(undefined);
444
- tree.add(2);
445
- tree.add(3);
446
- tree.add(4);
447
- tree.add(6);
448
- tree.add(9);
449
- tree.add(11);
450
- tree.add(13);
451
- tree.add(14);
452
- tree.add(16);
453
- tree.add(17);
454
- tree.add(18);
455
- tree.add(19);
456
- tree.add(110);
457
-
458
- isDebug && tree.print();
459
-
460
- expect(tree.dfs()).toEqual([
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(tree.isBST()).toBe(true);
467
+ expect(rbTree.isBST()).toBe(true);
465
468
  });
466
469
 
467
- it('should fix the tree after insertion and deletion', () => {
470
+ it('should fix the rbTree after insertion and deletion', () => {
468
471
  for (let i = 0; i < 100; i++) {
469
- tree.add(i);
472
+ rbTree.add(i);
470
473
  }
471
474
  for (let i = 0; i < 49; i++) {
472
- tree.delete(i);
475
+ rbTree.delete(i);
473
476
  }
474
477
 
475
- expect(tree.size).toBe(51);
476
- expect(tree.isBST()).toBe(true);
477
- expect(tree.dfs(n => n.key, 'in', tree.root, IterationType.ITERATIVE)).toEqual([
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(tree.dfs(n => n.key, 'in', tree.root, IterationType.RECURSIVE)).toEqual([
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 tree after large scale insertion and deletion', () => {
492
+ it('should fix the rbTree after large scale insertion and deletion', () => {
488
493
  for (let i = 0; i < 10000; i++) {
489
- tree.add(i);
494
+ rbTree.add(i);
490
495
  }
491
496
  for (let i = 0; i < 10000; i++) {
492
- tree.delete(i);
497
+ rbTree.delete(i);
493
498
  }
494
499
 
495
- expect(tree.size).toBe(0);
496
- expect(tree.isBST()).toBe(true);
497
- expect(tree.dfs(n => n.key, 'in', tree.root, IterationType.ITERATIVE)).toEqual([]);
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
- tree.clear();
504
+ rbTree.clear();
500
505
  for (let i = 0; i < 1000; i++) {
501
- tree.add(getRandomInt(-100, 1000));
502
- tree.delete(getRandomInt(-100, 1000));
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 tree with Sentinel node
506
- // expect(tree.isBST()).toBe(true);
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 tree after large scale insertion and deletion', () => {
513
- tree.clear();
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
- tree.add(arr[i]);
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
- tree.addMany([9, 8, 7, 8, 8, 8, 2, 3, 6, 5, 5, 4]);
530
- isDebug && tree.print();
531
-
532
- expect(tree.size).toBe(8);
533
- expect(tree.isBST()).toBe(true);
534
- expect(tree.isAVLBalanced()).toBe(true);
535
- tree.addMany([10, 5, 2, 11]);
536
- expect(tree.size).toBe(10);
537
- expect(tree.isBST()).toBe(true);
538
- expect(tree.isAVLBalanced()).toBe(true);
539
-
540
- tree.clear();
541
- tree.addMany([10, 20, 30, 40, 50, 60]);
542
- expect(tree.isAVLBalanced()).toBe(false);
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 iterative methods test', () => {
547
- let rbTree: RedBlackTree<number, string>;
548
- beforeEach(() => {
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
- test('The node obtained by get Node should match the node type', () => {
556
- const node3 = rbTree.getNode(3);
557
- expect(node3).toBeInstanceOf(BinaryTreeNode);
558
- expect(node3).toBeInstanceOf(BSTNode);
559
- expect(node3).toBeInstanceOf(RedBlackTreeNode);
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
- test('forEach should iterate over all elements', () => {
563
- const mockCallback = jest.fn();
564
- rbTree.forEach((value, key) => {
565
- mockCallback(value, key);
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
- expect(mockCallback.mock.calls.length).toBe(3);
569
- expect(mockCallback.mock.calls[0]).toEqual(['a', 1]);
570
- expect(mockCallback.mock.calls[1]).toEqual(['b', 2]);
571
- expect(mockCallback.mock.calls[2]).toEqual(['c', 3]);
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
- test('filter should return a new tree with filtered elements', () => {
575
- const filteredTree = rbTree.filter((value, key) => key > 1);
576
- expect(filteredTree.size).toBe(2);
577
- expect([...filteredTree]).toEqual([
578
- [2, 'b'],
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
- test('map should return a new tree with modified elements', () => {
584
- const mappedTree = rbTree.map((value, key) => (key * 2).toString());
585
- expect(mappedTree.size).toBe(3);
586
- expect([...mappedTree]).toEqual([
587
- [1, '2'],
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
- test('reduce should accumulate values', () => {
594
- const sum = rbTree.reduce((acc, value, key) => acc + key, 0);
595
- expect(sum).toBe(6);
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
- test('[Symbol.iterator] should provide an iterator', () => {
599
- const entries = [];
600
- for (const entry of rbTree) {
601
- entries.push(entry);
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
- expect(entries.length).toBe(3);
605
- expect(entries).toEqual([
606
- [1, 'a'],
607
- [2, 'b'],
608
- [3, 'c']
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
  });