data-structure-typed 1.50.5 → 1.50.6
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 -13
- package/benchmark/report.html +13 -13
- package/benchmark/report.json +168 -144
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +19 -19
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +158 -135
- package/dist/cjs/data-structures/binary-tree/rb-tree.js +415 -386
- 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/mjs/data-structures/binary-tree/binary-tree.js +19 -19
- package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +158 -135
- package/dist/mjs/data-structures/binary-tree/rb-tree.js +412 -386
- 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/umd/data-structure-typed.js +477 -431
- 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/binary-tree.ts +19 -19
- package/src/data-structures/binary-tree/rb-tree.ts +437 -395
- package/src/data-structures/binary-tree/tree-multi-map.ts +85 -82
- package/test/performance/data-structures/binary-tree/rb-tree.test.ts +26 -16
- package/test/unit/data-structures/binary-tree/overall.test.ts +23 -21
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +168 -105
- package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +311 -192
|
@@ -1,11 +1,13 @@
|
|
|
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', () => {
|
|
10
|
+
describe('RedBlackTree 1', () => {
|
|
9
11
|
let tree: RedBlackTree<number>;
|
|
10
12
|
|
|
11
13
|
beforeEach(() => {
|
|
@@ -67,7 +69,7 @@ describe('RedBlackTree', () => {
|
|
|
67
69
|
|
|
68
70
|
it('should handle an empty tree', () => {
|
|
69
71
|
const minNode = tree.getLeftMost(tree.root);
|
|
70
|
-
expect(minNode).toBe(tree.
|
|
72
|
+
expect(minNode).toBe(tree.SENTINEL);
|
|
71
73
|
});
|
|
72
74
|
});
|
|
73
75
|
|
|
@@ -85,7 +87,7 @@ describe('RedBlackTree', () => {
|
|
|
85
87
|
|
|
86
88
|
it('should handle an empty tree', () => {
|
|
87
89
|
const maxNode = tree.getRightMost(tree.root);
|
|
88
|
-
expect(maxNode).toBe(tree.
|
|
90
|
+
expect(maxNode).toBe(tree.SENTINEL);
|
|
89
91
|
});
|
|
90
92
|
});
|
|
91
93
|
|
|
@@ -109,7 +111,7 @@ describe('RedBlackTree', () => {
|
|
|
109
111
|
|
|
110
112
|
const node = tree.getNode(10);
|
|
111
113
|
const successorNode = tree.getSuccessor(node!);
|
|
112
|
-
// TODO not sure if it should be undefined or tree.
|
|
114
|
+
// TODO not sure if it should be undefined or tree.SENTINEL
|
|
113
115
|
expect(successorNode).toBe(undefined);
|
|
114
116
|
});
|
|
115
117
|
});
|
|
@@ -134,8 +136,8 @@ describe('RedBlackTree', () => {
|
|
|
134
136
|
|
|
135
137
|
const node = tree.getNode(20);
|
|
136
138
|
const predecessorNode = tree.getPredecessor(node!);
|
|
137
|
-
// TODO not sure if it should be tree.
|
|
138
|
-
expect(predecessorNode).toBe(tree.getNode(
|
|
139
|
+
// TODO not sure if it should be tree.SENTINEL or something else.
|
|
140
|
+
expect(predecessorNode).toBe(tree.getNode(20));
|
|
139
141
|
});
|
|
140
142
|
});
|
|
141
143
|
|
|
@@ -214,7 +216,7 @@ describe('RedBlackTree 2', () => {
|
|
|
214
216
|
tree.add(20);
|
|
215
217
|
const node = tree.getNode(20);
|
|
216
218
|
const predecessor = tree.getPredecessor(node!);
|
|
217
|
-
expect(predecessor?.key).toBe(
|
|
219
|
+
expect(predecessor?.key).toBe(20);
|
|
218
220
|
});
|
|
219
221
|
|
|
220
222
|
it('should rotate nodes to the left', () => {
|
|
@@ -272,28 +274,28 @@ 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.
|
|
276
|
-
expect(node15F?.right).toBe(tree.
|
|
277
|
+
expect(node15F?.left).toBe(tree.SENTINEL);
|
|
278
|
+
expect(node15F?.right).toBe(tree.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.
|
|
281
|
-
expect(node21F?.right).toBe(tree.
|
|
282
|
+
expect(node21F?.left).toBe(tree.SENTINEL);
|
|
283
|
+
expect(node21F?.right).toBe(tree.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.
|
|
286
|
-
expect(node6F?.right).toBe(tree.
|
|
287
|
+
expect(node6F?.left).toBe(tree.SENTINEL);
|
|
288
|
+
expect(node6F?.right).toBe(tree.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.
|
|
291
|
-
expect(node2F?.right).toBe(tree.
|
|
292
|
+
expect(node2F?.left).toBe(tree.SENTINEL);
|
|
293
|
+
expect(node2F?.right).toBe(tree.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.
|
|
296
|
-
expect(node15F?.right).toBe(tree.
|
|
297
|
+
expect(node15F?.left).toBe(tree.SENTINEL);
|
|
298
|
+
expect(node15F?.right).toBe(tree.SENTINEL);
|
|
297
299
|
expect(node15F?.parent).toBe(node20F);
|
|
298
300
|
tree.delete(5);
|
|
299
301
|
node10F = tree.getNode(10);
|
|
@@ -316,28 +318,28 @@ 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.
|
|
320
|
-
expect(node15F?.right).toBe(tree.
|
|
321
|
+
expect(node15F?.left).toBe(tree.SENTINEL);
|
|
322
|
+
expect(node15F?.right).toBe(tree.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.
|
|
325
|
-
expect(node21F?.right).toBe(tree.
|
|
326
|
+
expect(node21F?.left).toBe(tree.SENTINEL);
|
|
327
|
+
expect(node21F?.right).toBe(tree.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.
|
|
332
|
+
expect(node6F?.right).toBe(tree.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.
|
|
335
|
-
expect(node2F?.right).toBe(tree.
|
|
336
|
+
expect(node2F?.left).toBe(tree.SENTINEL);
|
|
337
|
+
expect(node2F?.right).toBe(tree.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.
|
|
340
|
-
expect(node15F?.right).toBe(tree.
|
|
341
|
+
expect(node15F?.left).toBe(tree.SENTINEL);
|
|
342
|
+
expect(node15F?.right).toBe(tree.SENTINEL);
|
|
341
343
|
expect(node15F?.parent).toBe(node20F);
|
|
342
344
|
tree.delete(20);
|
|
343
345
|
node10F = tree.getNode(10);
|
|
@@ -356,28 +358,28 @@ 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.
|
|
360
|
-
expect(node15F?.right).toBe(tree.
|
|
361
|
+
expect(node15F?.left).toBe(tree.SENTINEL);
|
|
362
|
+
expect(node15F?.right).toBe(tree.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.
|
|
367
|
+
expect(node21F?.right).toBe(tree.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.
|
|
372
|
+
expect(node6F?.right).toBe(tree.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.
|
|
375
|
-
expect(node2F?.right).toBe(tree.
|
|
376
|
+
expect(node2F?.left).toBe(tree.SENTINEL);
|
|
377
|
+
expect(node2F?.right).toBe(tree.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.
|
|
380
|
-
expect(node15F?.right).toBe(tree.
|
|
381
|
+
expect(node15F?.left).toBe(tree.SENTINEL);
|
|
382
|
+
expect(node15F?.right).toBe(tree.SENTINEL);
|
|
381
383
|
expect(node15F?.parent).toBe(node21F);
|
|
382
384
|
});
|
|
383
385
|
|
|
@@ -387,8 +389,8 @@ describe('RedBlackTree 2', () => {
|
|
|
387
389
|
tree.add(5);
|
|
388
390
|
tree.add(15);
|
|
389
391
|
const node15F = tree.getNode(15);
|
|
390
|
-
expect(node15F?.left).toBe(tree.
|
|
391
|
-
expect(node15F?.right).toBe(tree.
|
|
392
|
+
expect(node15F?.left).toBe(tree.SENTINEL);
|
|
393
|
+
expect(node15F?.right).toBe(tree.SENTINEL);
|
|
392
394
|
expect(node15F?.parent).toBe(tree.getNode(5));
|
|
393
395
|
|
|
394
396
|
tree.add(25);
|
|
@@ -403,19 +405,20 @@ describe('RedBlackTree 2', () => {
|
|
|
403
405
|
tree.add(155);
|
|
404
406
|
tree.add(225);
|
|
405
407
|
const node225F = tree.getNode(225);
|
|
406
|
-
expect(node225F?.left).toBe(tree.
|
|
407
|
-
expect(node225F?.right).toBe(tree.
|
|
408
|
+
expect(node225F?.left).toBe(tree.SENTINEL);
|
|
409
|
+
expect(node225F?.right).toBe(tree.SENTINEL);
|
|
408
410
|
expect(node225F?.parent?.key).toBe(155);
|
|
409
411
|
tree.add(7);
|
|
412
|
+
isDebug && tree.print();
|
|
410
413
|
|
|
411
414
|
const node15S = tree.getNode(15);
|
|
412
|
-
expect(node15S?.left?.key).toBe(
|
|
413
|
-
expect(node15S?.right?.key).toBe(
|
|
414
|
-
expect(
|
|
415
|
-
expect(node15S?.parent).toBe(
|
|
415
|
+
expect(node15S?.left?.key).toBe(10);
|
|
416
|
+
expect(node15S?.right?.key).toBe(25);
|
|
417
|
+
expect(tree.root).toBe(tree.getNode(8));
|
|
418
|
+
expect(node15S?.parent?.key).toBe(28);
|
|
416
419
|
tree.delete(15);
|
|
417
|
-
expect(tree.root
|
|
418
|
-
expect(tree.root
|
|
420
|
+
expect(tree.root?.key).toBe(8);
|
|
421
|
+
expect(tree.root?.parent).toBe(undefined);
|
|
419
422
|
|
|
420
423
|
const node15T = tree.getNode(15);
|
|
421
424
|
expect(node15T).toBe(undefined);
|
|
@@ -430,14 +433,14 @@ describe('RedBlackTree 2', () => {
|
|
|
430
433
|
const node50 = tree.getNode(50);
|
|
431
434
|
expect(node50?.key).toBe(50);
|
|
432
435
|
expect(node50?.left?.key).toBe(33);
|
|
433
|
-
expect(node50?.right).toBe(tree.
|
|
436
|
+
expect(node50?.right).toBe(tree.SENTINEL);
|
|
434
437
|
const node15Fo = tree.getNode(15);
|
|
435
438
|
|
|
436
439
|
expect(node15Fo?.key).toBe(15);
|
|
437
|
-
expect(node15Fo?.left).toBe(tree.
|
|
440
|
+
expect(node15Fo?.left).toBe(tree.SENTINEL);
|
|
438
441
|
const node225S = tree.getNode(225);
|
|
439
|
-
expect(node225S?.left).toBe(tree.
|
|
440
|
-
expect(node225S?.right).toBe(tree.
|
|
442
|
+
expect(node225S?.left).toBe(tree.SENTINEL);
|
|
443
|
+
expect(node225S?.right).toBe(tree.SENTINEL);
|
|
441
444
|
expect(node225S?.parent?.key).toBe(155);
|
|
442
445
|
// TODO
|
|
443
446
|
// expect(tree.getNode(0)).toBe(undefined);
|
|
@@ -474,6 +477,8 @@ describe('RedBlackTree 2', () => {
|
|
|
474
477
|
|
|
475
478
|
expect(tree.size).toBe(51);
|
|
476
479
|
expect(tree.isBST()).toBe(true);
|
|
480
|
+
expect(tree.isBST(tree.root, IterationType.RECURSIVE)).toBe(true);
|
|
481
|
+
|
|
477
482
|
expect(tree.dfs(n => n.key, 'in', tree.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
|
|
@@ -502,7 +507,7 @@ describe('RedBlackTree 2', () => {
|
|
|
502
507
|
tree.delete(getRandomInt(-100, 1000));
|
|
503
508
|
}
|
|
504
509
|
|
|
505
|
-
// TODO there is a bug when dfs the tree with
|
|
510
|
+
// TODO there is a bug when dfs the tree with SENTINEL node
|
|
506
511
|
// expect(tree.isBST()).toBe(true);
|
|
507
512
|
});
|
|
508
513
|
const { HUNDRED_THOUSAND } = magnitude;
|
|
@@ -541,71 +546,129 @@ describe('RedBlackTree 2', () => {
|
|
|
541
546
|
tree.addMany([10, 20, 30, 40, 50, 60]);
|
|
542
547
|
expect(tree.isAVLBalanced()).toBe(false);
|
|
543
548
|
});
|
|
544
|
-
});
|
|
545
549
|
|
|
546
|
-
describe('RedBlackTree
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
550
|
+
describe('RedBlackTree delete test', function () {
|
|
551
|
+
const rbTree = new RedBlackTree<number, number>();
|
|
552
|
+
const inputSize = 100; // Adjust input sizes as needed
|
|
553
|
+
|
|
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
|
+
});
|
|
554
580
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
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(0);
|
|
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 tree 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 tree 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
|
});
|