data-structure-typed 1.52.4 → 1.52.5

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 (181) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +13 -13
  3. package/README_zh-CN.md +216 -26
  4. package/benchmark/report.html +13 -13
  5. package/benchmark/report.json +158 -158
  6. package/dist/cjs/data-structures/base/iterable-element-base.d.ts +1 -37
  7. package/dist/cjs/data-structures/base/iterable-element-base.js +1 -37
  8. package/dist/cjs/data-structures/base/iterable-element-base.js.map +1 -1
  9. package/dist/cjs/data-structures/base/iterable-entry-base.d.ts +2 -54
  10. package/dist/cjs/data-structures/base/iterable-entry-base.js +1 -49
  11. package/dist/cjs/data-structures/base/iterable-entry-base.js.map +1 -1
  12. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +0 -32
  13. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js +9 -41
  14. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
  15. package/dist/cjs/data-structures/binary-tree/avl-tree.d.ts +0 -46
  16. package/dist/cjs/data-structures/binary-tree/avl-tree.js +0 -46
  17. package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
  18. package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +82 -147
  19. package/dist/cjs/data-structures/binary-tree/binary-tree.js +299 -331
  20. package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
  21. package/dist/cjs/data-structures/binary-tree/bst.d.ts +1 -40
  22. package/dist/cjs/data-structures/binary-tree/bst.js +12 -44
  23. package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
  24. package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +0 -48
  25. package/dist/cjs/data-structures/binary-tree/rb-tree.js +2 -50
  26. package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
  27. package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +0 -32
  28. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +9 -41
  29. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
  30. package/dist/cjs/data-structures/graph/abstract-graph.d.ts +0 -75
  31. package/dist/cjs/data-structures/graph/abstract-graph.js +0 -75
  32. package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
  33. package/dist/cjs/data-structures/graph/directed-graph.d.ts +0 -98
  34. package/dist/cjs/data-structures/graph/directed-graph.js +0 -98
  35. package/dist/cjs/data-structures/graph/directed-graph.js.map +1 -1
  36. package/dist/cjs/data-structures/graph/undirected-graph.d.ts +0 -50
  37. package/dist/cjs/data-structures/graph/undirected-graph.js +0 -50
  38. package/dist/cjs/data-structures/graph/undirected-graph.js.map +1 -1
  39. package/dist/cjs/data-structures/hash/hash-map.d.ts +5 -92
  40. package/dist/cjs/data-structures/hash/hash-map.js +27 -111
  41. package/dist/cjs/data-structures/hash/hash-map.js.map +1 -1
  42. package/dist/cjs/data-structures/heap/heap.d.ts +0 -32
  43. package/dist/cjs/data-structures/heap/heap.js +0 -32
  44. package/dist/cjs/data-structures/heap/heap.js.map +1 -1
  45. package/dist/cjs/data-structures/linked-list/doubly-linked-list.d.ts +5 -88
  46. package/dist/cjs/data-structures/linked-list/doubly-linked-list.js +5 -88
  47. package/dist/cjs/data-structures/linked-list/doubly-linked-list.js.map +1 -1
  48. package/dist/cjs/data-structures/linked-list/singly-linked-list.d.ts +1 -83
  49. package/dist/cjs/data-structures/linked-list/singly-linked-list.js +2 -84
  50. package/dist/cjs/data-structures/linked-list/singly-linked-list.js.map +1 -1
  51. package/dist/cjs/data-structures/linked-list/skip-linked-list.d.ts +1 -35
  52. package/dist/cjs/data-structures/linked-list/skip-linked-list.js +1 -35
  53. package/dist/cjs/data-structures/linked-list/skip-linked-list.js.map +1 -1
  54. package/dist/cjs/data-structures/queue/deque.d.ts +1 -98
  55. package/dist/cjs/data-structures/queue/deque.js +3 -99
  56. package/dist/cjs/data-structures/queue/deque.js.map +1 -1
  57. package/dist/cjs/data-structures/queue/queue.d.ts +1 -54
  58. package/dist/cjs/data-structures/queue/queue.js +0 -53
  59. package/dist/cjs/data-structures/queue/queue.js.map +1 -1
  60. package/dist/cjs/data-structures/stack/stack.d.ts +1 -34
  61. package/dist/cjs/data-structures/stack/stack.js +1 -34
  62. package/dist/cjs/data-structures/stack/stack.js.map +1 -1
  63. package/dist/cjs/data-structures/tree/tree.js +0 -1
  64. package/dist/cjs/data-structures/tree/tree.js.map +1 -1
  65. package/dist/cjs/data-structures/trie/trie.d.ts +0 -64
  66. package/dist/cjs/data-structures/trie/trie.js +0 -64
  67. package/dist/cjs/data-structures/trie/trie.js.map +1 -1
  68. package/dist/cjs/types/data-structures/binary-tree/binary-tree.d.ts +8 -0
  69. package/dist/cjs/types/data-structures/binary-tree/binary-tree.js +6 -0
  70. package/dist/cjs/types/data-structures/binary-tree/binary-tree.js.map +1 -1
  71. package/dist/cjs/types/utils/utils.d.ts +13 -12
  72. package/dist/cjs/utils/number.d.ts +13 -0
  73. package/dist/cjs/utils/number.js +13 -0
  74. package/dist/cjs/utils/number.js.map +1 -1
  75. package/dist/cjs/utils/utils.d.ts +125 -3
  76. package/dist/cjs/utils/utils.js +177 -21
  77. package/dist/cjs/utils/utils.js.map +1 -1
  78. package/dist/mjs/data-structures/base/iterable-element-base.d.ts +1 -37
  79. package/dist/mjs/data-structures/base/iterable-element-base.js +1 -37
  80. package/dist/mjs/data-structures/base/iterable-entry-base.d.ts +2 -54
  81. package/dist/mjs/data-structures/base/iterable-entry-base.js +1 -49
  82. package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +0 -32
  83. package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.js +9 -41
  84. package/dist/mjs/data-structures/binary-tree/avl-tree.d.ts +0 -46
  85. package/dist/mjs/data-structures/binary-tree/avl-tree.js +0 -46
  86. package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +82 -147
  87. package/dist/mjs/data-structures/binary-tree/binary-tree.js +298 -332
  88. package/dist/mjs/data-structures/binary-tree/bst.d.ts +1 -40
  89. package/dist/mjs/data-structures/binary-tree/bst.js +12 -44
  90. package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +0 -48
  91. package/dist/mjs/data-structures/binary-tree/rb-tree.js +2 -50
  92. package/dist/mjs/data-structures/binary-tree/tree-multi-map.d.ts +0 -32
  93. package/dist/mjs/data-structures/binary-tree/tree-multi-map.js +9 -41
  94. package/dist/mjs/data-structures/graph/abstract-graph.d.ts +0 -75
  95. package/dist/mjs/data-structures/graph/abstract-graph.js +0 -75
  96. package/dist/mjs/data-structures/graph/directed-graph.d.ts +0 -98
  97. package/dist/mjs/data-structures/graph/directed-graph.js +0 -98
  98. package/dist/mjs/data-structures/graph/undirected-graph.d.ts +0 -50
  99. package/dist/mjs/data-structures/graph/undirected-graph.js +0 -50
  100. package/dist/mjs/data-structures/hash/hash-map.d.ts +5 -92
  101. package/dist/mjs/data-structures/hash/hash-map.js +27 -111
  102. package/dist/mjs/data-structures/heap/heap.d.ts +0 -32
  103. package/dist/mjs/data-structures/heap/heap.js +0 -32
  104. package/dist/mjs/data-structures/linked-list/doubly-linked-list.d.ts +5 -88
  105. package/dist/mjs/data-structures/linked-list/doubly-linked-list.js +5 -88
  106. package/dist/mjs/data-structures/linked-list/singly-linked-list.d.ts +1 -83
  107. package/dist/mjs/data-structures/linked-list/singly-linked-list.js +2 -84
  108. package/dist/mjs/data-structures/linked-list/skip-linked-list.d.ts +1 -35
  109. package/dist/mjs/data-structures/linked-list/skip-linked-list.js +1 -35
  110. package/dist/mjs/data-structures/queue/deque.d.ts +1 -98
  111. package/dist/mjs/data-structures/queue/deque.js +3 -99
  112. package/dist/mjs/data-structures/queue/queue.d.ts +1 -54
  113. package/dist/mjs/data-structures/queue/queue.js +0 -53
  114. package/dist/mjs/data-structures/stack/stack.d.ts +1 -34
  115. package/dist/mjs/data-structures/stack/stack.js +1 -34
  116. package/dist/mjs/data-structures/tree/tree.js +0 -1
  117. package/dist/mjs/data-structures/trie/trie.d.ts +0 -64
  118. package/dist/mjs/data-structures/trie/trie.js +0 -64
  119. package/dist/mjs/types/data-structures/binary-tree/binary-tree.d.ts +8 -0
  120. package/dist/mjs/types/data-structures/binary-tree/binary-tree.js +5 -1
  121. package/dist/mjs/types/utils/utils.d.ts +13 -12
  122. package/dist/mjs/utils/number.d.ts +13 -0
  123. package/dist/mjs/utils/number.js +13 -0
  124. package/dist/mjs/utils/utils.d.ts +125 -3
  125. package/dist/mjs/utils/utils.js +177 -21
  126. package/dist/umd/data-structure-typed.js +408 -1474
  127. package/dist/umd/data-structure-typed.min.js +5 -4
  128. package/dist/umd/data-structure-typed.min.js.map +1 -1
  129. package/package.json +6 -6
  130. package/src/data-structures/base/iterable-element-base.ts +2 -42
  131. package/src/data-structures/base/iterable-entry-base.ts +3 -62
  132. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +8 -48
  133. package/src/data-structures/binary-tree/avl-tree.ts +0 -57
  134. package/src/data-structures/binary-tree/binary-tree.ts +329 -358
  135. package/src/data-structures/binary-tree/bst.ts +11 -54
  136. package/src/data-structures/binary-tree/rb-tree.ts +2 -62
  137. package/src/data-structures/binary-tree/tree-multi-map.ts +8 -48
  138. package/src/data-structures/graph/abstract-graph.ts +0 -92
  139. package/src/data-structures/graph/directed-graph.ts +0 -122
  140. package/src/data-structures/graph/undirected-graph.ts +0 -62
  141. package/src/data-structures/hash/hash-map.ts +29 -133
  142. package/src/data-structures/heap/heap.ts +0 -40
  143. package/src/data-structures/linked-list/doubly-linked-list.ts +5 -112
  144. package/src/data-structures/linked-list/singly-linked-list.ts +2 -104
  145. package/src/data-structures/linked-list/skip-linked-list.ts +1 -44
  146. package/src/data-structures/queue/deque.ts +2 -125
  147. package/src/data-structures/queue/queue.ts +1 -68
  148. package/src/data-structures/stack/stack.ts +1 -43
  149. package/src/data-structures/tree/tree.ts +1 -1
  150. package/src/data-structures/trie/trie.ts +0 -80
  151. package/src/types/data-structures/binary-tree/binary-tree.ts +8 -1
  152. package/src/types/utils/utils.ts +17 -15
  153. package/src/utils/number.ts +13 -0
  154. package/src/utils/utils.ts +174 -18
  155. package/test/config.ts +8 -0
  156. package/test/integration/all-in-one.test.ts +1 -1
  157. package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +13 -13
  158. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +18 -13
  159. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +471 -64
  160. package/test/unit/data-structures/binary-tree/bst.test.ts +167 -23
  161. package/test/unit/data-structures/binary-tree/overall.test.ts +1 -1
  162. package/test/unit/data-structures/binary-tree/rb-tree.test.ts +136 -13
  163. package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +18 -13
  164. package/test/unit/data-structures/graph/directed-graph.test.ts +46 -32
  165. package/test/unit/data-structures/graph/map-graph.test.ts +24 -2
  166. package/test/unit/data-structures/graph/undirected-graph.test.ts +24 -24
  167. package/test/unit/data-structures/hash/hash-map.test.ts +225 -35
  168. package/test/unit/data-structures/heap/heap.test.ts +47 -39
  169. package/test/unit/data-structures/heap/min-heap.test.ts +5 -5
  170. package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +34 -4
  171. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +32 -0
  172. package/test/unit/data-structures/matrix/matrix.test.ts +35 -5
  173. package/test/unit/data-structures/priority-queue/max-priority-queue.test.ts +31 -0
  174. package/test/unit/data-structures/priority-queue/min-priority-queue.test.ts +18 -0
  175. package/test/unit/data-structures/priority-queue/priority-queue.test.ts +17 -0
  176. package/test/unit/data-structures/queue/deque.test.ts +288 -47
  177. package/test/unit/data-structures/queue/queue.test.ts +62 -37
  178. package/test/unit/data-structures/stack/stack.test.ts +30 -5
  179. package/test/unit/data-structures/tree/tree.test.ts +58 -0
  180. package/test/unit/data-structures/trie/trie.test.ts +46 -5
  181. package/test/unit/utils/utils.test.ts +169 -0
@@ -1,9 +1,37 @@
1
1
  import { BinaryTreeNode, BST, BSTNode } from '../../../../src';
2
- import { isDebugTest } from '../../../config';
2
+ import { isDebugTest, SYSTEM_MAX_CALL_STACK, isTestStackOverflow } from '../../../config';
3
3
 
4
4
  const isDebug = isDebugTest;
5
5
 
6
6
  describe('BST operations test', () => {
7
+ it('should add undefined and null', () => {
8
+ const bst = new BST<number, string>();
9
+ const isAddUndefined = bst.add(undefined);
10
+ expect(isAddUndefined).toBe(false);
11
+ expect(bst.get(undefined)).toBe(undefined);
12
+ const isAddNull = bst.add(null);
13
+ expect(isAddNull).toBe(false);
14
+ expect(bst.get(null)).toBe(undefined);
15
+ const isAdd0 = bst.add(0, '0');
16
+ expect(isAdd0).toBe(true);
17
+ expect(bst.get(0)).toBe('0');
18
+ });
19
+ it('should addMany undefined and null', () => {
20
+ const bst = new BST<number, string>();
21
+ const addManyWithUndefined = bst.addMany([1, undefined, 3]);
22
+ // TODO
23
+ // expect(addManyWithUndefined).toEqual([true, false, true]);
24
+ expect(addManyWithUndefined).toEqual([true, true]);
25
+ expect(bst.get(undefined)).toBe(undefined);
26
+ const addManyWithNull = bst.addMany([1, null, 3, 4]);
27
+ // TODO
28
+ // expect(addManyWithNull).toEqual([false, false, false, true]);
29
+ expect(addManyWithNull).toEqual([true, true, true]);
30
+ expect(bst.get(null)).toBe(undefined);
31
+ const node0 = bst.add(0, '0');
32
+ expect(node0).toBe(true);
33
+ expect(bst.get(0)).toBe('0');
34
+ });
7
35
  it('should perform various operations on a Binary Search Tree with numeric values', () => {
8
36
  const bst = new BST<number, number>();
9
37
  expect(bst).toBeInstanceOf(BST);
@@ -45,12 +73,12 @@ describe('BST operations test', () => {
45
73
  expect(nodeVal9?.key).toBe(9);
46
74
 
47
75
  const leftMost = bst.getLeftMost();
48
- expect(leftMost?.key).toBe(1);
76
+ expect(leftMost).toBe(1);
49
77
 
50
78
  expect(bst.isBST()).toBe(true);
51
79
 
52
80
  const node15 = bst.getNode(15);
53
- const minNodeBySpecificNode = node15 && bst.getLeftMost(node15);
81
+ const minNodeBySpecificNode = node15 && bst.getLeftMost(node => node, node15);
54
82
  expect(minNodeBySpecificNode?.key).toBe(12);
55
83
 
56
84
  let subTreeSum = 0;
@@ -249,14 +277,14 @@ describe('BST operations test', () => {
249
277
  expect(nodeVal9?.key).toBe(9);
250
278
 
251
279
  const leftMost = objBST.getLeftMost();
252
- expect(leftMost?.key).toBe(1);
280
+ expect(leftMost).toBe(1);
253
281
 
254
282
  const node15 = objBST.getNode(15);
255
283
  expect(node15?.value).toEqual({
256
284
  name: 'Alice',
257
285
  age: 15
258
286
  });
259
- const minNodeBySpecificNode = node15 && objBST.getLeftMost(node15);
287
+ const minNodeBySpecificNode = node15 && objBST.getLeftMost(node => node, node15);
260
288
  expect(minNodeBySpecificNode?.key).toBe(12);
261
289
 
262
290
  let subTreeSum = 0;
@@ -410,6 +438,24 @@ describe('BST operations test', () => {
410
438
  expect(bfsNodes[1].key).toBe(12);
411
439
  expect(bfsNodes[2].key).toBe(16);
412
440
  });
441
+
442
+ it('should keyValueOrEntryOrRawElementToNode', () => {
443
+ const bst = new BST<number>();
444
+ const node0 = bst.keyValueOrEntryOrRawElementToNode(0);
445
+ expect(node0).toEqual({
446
+ _left: undefined,
447
+ _right: undefined,
448
+ key: 0,
449
+ parent: undefined,
450
+ value: undefined
451
+ });
452
+
453
+ const nodeUndefined = bst.keyValueOrEntryOrRawElementToNode(undefined);
454
+ expect(nodeUndefined).toBe(undefined);
455
+
456
+ const nodeNull = bst.keyValueOrEntryOrRawElementToNode(null);
457
+ expect(nodeNull).toBe(undefined);
458
+ });
413
459
  });
414
460
 
415
461
  describe('BST operations test recursively', () => {
@@ -442,10 +488,10 @@ describe('BST operations test recursively', () => {
442
488
  expect(nodeVal9?.key).toBe(undefined);
443
489
 
444
490
  const leftMost = bst.getLeftMost();
445
- expect(leftMost?.key).toBe(1);
491
+ expect(leftMost).toBe(1);
446
492
 
447
493
  const node15 = bst.getNode(15);
448
- const minNodeBySpecificNode = node15 && bst.getLeftMost(node15);
494
+ const minNodeBySpecificNode = node15 && bst.getLeftMost(node => node, node15);
449
495
  expect(minNodeBySpecificNode?.key).toBe(12);
450
496
 
451
497
  let subTreeSum = 0;
@@ -645,14 +691,14 @@ describe('BST operations test recursively', () => {
645
691
  expect(nodeVal9?.key).toBe(9);
646
692
 
647
693
  const leftMost = objBST.getLeftMost();
648
- expect(leftMost?.key).toBe(1);
694
+ expect(leftMost).toBe(1);
649
695
 
650
696
  const node15 = objBST.getNode(15);
651
697
  expect(node15?.value).toEqual({
652
698
  key: 15,
653
699
  keyA: 15
654
700
  });
655
- const minNodeBySpecificNode = node15 && objBST.getLeftMost(node15);
701
+ const minNodeBySpecificNode = node15 && objBST.getLeftMost(node => node, node15);
656
702
  expect(minNodeBySpecificNode?.key).toBe(12);
657
703
 
658
704
  let subTreeSum = 0;
@@ -870,16 +916,43 @@ describe('BST operations test recursively', () => {
870
916
  cloned.delete('5');
871
917
  expect(cloned.size).toBe(0);
872
918
  });
919
+
920
+ if (isTestStackOverflow) {
921
+ it('should getLeftMost', () => {
922
+ const bst = new BST<number>([], { comparator: (a, b) => b - a });
923
+ for (let i = 1; i <= SYSTEM_MAX_CALL_STACK; i++) bst.add(i);
924
+
925
+ expect(() => {
926
+ const leftMost = bst.getLeftMost(node => node, bst.root, 'RECURSIVE');
927
+ expect(leftMost?.key).toEqual(SYSTEM_MAX_CALL_STACK);
928
+ }).toThrow('Maximum call stack size exceeded');
929
+
930
+ const leftMost = bst.getLeftMost(node => node, bst.root, 'ITERATIVE');
931
+ expect(leftMost?.key).toEqual(SYSTEM_MAX_CALL_STACK);
932
+ });
933
+
934
+ it('should getRightMost', () => {
935
+ const bst = new BST<number>();
936
+ for (let i = 1; i <= SYSTEM_MAX_CALL_STACK; i++) bst.add(i);
937
+
938
+ expect(() => {
939
+ const rightMost = bst.getRightMost(node => node, bst.root, 'RECURSIVE');
940
+ expect(rightMost?.key).toEqual(SYSTEM_MAX_CALL_STACK);
941
+ }).toThrow('Maximum call stack size exceeded');
942
+ const rightMost = bst.getRightMost(node => node, bst.root, 'ITERATIVE');
943
+ expect(rightMost?.key).toEqual(SYSTEM_MAX_CALL_STACK);
944
+ });
945
+ }
873
946
  });
874
947
 
875
948
  describe('BST isBST', function () {
876
- test('isBST', () => {
949
+ it('isBST', () => {
877
950
  const bst = new BST<number, number>();
878
951
  bst.addMany([1, 2, 3, 9, 8, 5, 6, 7, 4]);
879
952
  expect(bst.isBST()).toBe(true);
880
953
  });
881
954
 
882
- test('isBST when variant is Max', () => {
955
+ it('isBST when variant is Max', () => {
883
956
  const bst = new BST<number, number>([1, 2, 3, 9, 8, 5, 6, 7, 4], {
884
957
  comparator: (a, b) => b - a
885
958
  });
@@ -956,18 +1029,24 @@ describe('BST iterative methods test', () => {
956
1029
  let bst: BST<number, string>;
957
1030
  beforeEach(() => {
958
1031
  bst = new BST();
959
- bst.add([1, 'a']);
960
- bst.add([2, 'b']);
961
- bst.add([3, 'c']);
1032
+ bst.addMany(
1033
+ [
1034
+ [1, 'a'],
1035
+ [2, 'b'],
1036
+ [3, 'c']
1037
+ ],
1038
+ [],
1039
+ false
1040
+ );
962
1041
  });
963
1042
 
964
- test('The node obtained by get Node should match the node type', () => {
1043
+ it('The node obtained by get Node should match the node type', () => {
965
1044
  const node3 = bst.getNode(3);
966
1045
  expect(node3).toBeInstanceOf(BinaryTreeNode);
967
1046
  expect(node3).toBeInstanceOf(BSTNode);
968
1047
  });
969
1048
 
970
- test('forEach should iterate over all elements', () => {
1049
+ it('forEach should iterate over all elements', () => {
971
1050
  const mockCallback = jest.fn();
972
1051
  bst.forEach((value, key) => {
973
1052
  mockCallback(value, key);
@@ -979,7 +1058,7 @@ describe('BST iterative methods test', () => {
979
1058
  expect(mockCallback.mock.calls[2]).toEqual(['c', 3]);
980
1059
  });
981
1060
 
982
- test('filter should return a new tree with filtered elements', () => {
1061
+ it('filter should return a new tree with filtered elements', () => {
983
1062
  const filteredTree = bst.filter((value, key) => key > 1);
984
1063
  expect(filteredTree.size).toBe(2);
985
1064
  expect([...filteredTree]).toEqual([
@@ -988,7 +1067,7 @@ describe('BST iterative methods test', () => {
988
1067
  ]);
989
1068
  });
990
1069
 
991
- test('map should return a new tree with modified elements', () => {
1070
+ it('map should return a new tree with modified elements', () => {
992
1071
  const mappedTree = bst.map((value, key) => (key * 2).toString());
993
1072
  expect(mappedTree.size).toBe(3);
994
1073
  expect([...mappedTree]).toEqual([
@@ -998,12 +1077,12 @@ describe('BST iterative methods test', () => {
998
1077
  ]);
999
1078
  });
1000
1079
 
1001
- test('reduce should accumulate values', () => {
1080
+ it('reduce should accumulate values', () => {
1002
1081
  const sum = bst.reduce((acc, value, key) => acc + key, 0);
1003
1082
  expect(sum).toBe(6);
1004
1083
  });
1005
1084
 
1006
- test('[Symbol.iterator] should provide an iterator', () => {
1085
+ it('[Symbol.iterator] should provide an iterator', () => {
1007
1086
  const entries = [];
1008
1087
  for (const entry of bst) {
1009
1088
  entries.push(entry);
@@ -1017,19 +1096,84 @@ describe('BST iterative methods test', () => {
1017
1096
  ]);
1018
1097
  });
1019
1098
 
1020
- test('should clone work well', () => {
1099
+ it('should clone work well', () => {
1021
1100
  const cloned = bst.clone();
1022
1101
  expect(cloned.root?.left).toBe(undefined);
1023
1102
  expect(cloned.root?.right?.value).toBe('b');
1024
1103
  });
1025
1104
 
1026
- test('should keys', () => {
1105
+ it('should keys', () => {
1027
1106
  const keys = bst.keys();
1028
1107
  expect([...keys]).toEqual([1, 2, 3]);
1029
1108
  });
1030
1109
 
1031
- test('should values', () => {
1110
+ it('should values', () => {
1032
1111
  const values = bst.values();
1033
1112
  expect([...values]).toEqual(['a', 'b', 'c']);
1034
1113
  });
1114
+
1115
+ it('should leaves', () => {
1116
+ const leaves = bst.leaves();
1117
+ expect(leaves).toEqual([3]);
1118
+ });
1119
+
1120
+ it('should collapsed, unbalanced, balanced bst leaves', () => {
1121
+ const collapsedToLinkedList = new BST();
1122
+ collapsedToLinkedList.addMany(
1123
+ [
1124
+ [1, 'a'],
1125
+ [2, 'b'],
1126
+ [3, 'c'],
1127
+ [4, 'd'],
1128
+ [5, 'e'],
1129
+ [6, 'f'],
1130
+ [7, 'g'],
1131
+ [8, 'h'],
1132
+ [9, 'i']
1133
+ ],
1134
+ [],
1135
+ false
1136
+ );
1137
+
1138
+ expect(collapsedToLinkedList.leaves()).toEqual([9]);
1139
+
1140
+ const unbalanced = new BST();
1141
+ unbalanced.addMany(
1142
+ [
1143
+ [2, 'b'],
1144
+ [1, 'a'],
1145
+ [3, 'c'],
1146
+ [4, 'd'],
1147
+ [5, 'e'],
1148
+ [6, 'f'],
1149
+ [7, 'g'],
1150
+ [8, 'h'],
1151
+ [9, 'i']
1152
+ ],
1153
+ [],
1154
+ false
1155
+ );
1156
+
1157
+ expect(unbalanced.leaves()).toEqual([1, 9]);
1158
+
1159
+ const balanced = new BST();
1160
+ balanced.addMany(
1161
+ [
1162
+ [2, 'b'],
1163
+ [1, 'a'],
1164
+ [3, 'c'],
1165
+ [4, 'd'],
1166
+ [5, 'e'],
1167
+ [6, 'f'],
1168
+ [7, 'g'],
1169
+ [8, 'h'],
1170
+ [9, 'i']
1171
+ ],
1172
+ [],
1173
+ true
1174
+ );
1175
+
1176
+ expect(balanced.leaves()).toEqual([1, 6, 4, 9]);
1177
+ expect(balanced.leaves(node => node?.value)).toEqual(['a', 'f', 'd', 'i']);
1178
+ });
1035
1179
  });
@@ -18,7 +18,7 @@ describe('Overall BinaryTree Test', () => {
18
18
  expect(bst.getDepth(6)).toBe(3); // true
19
19
  const leftMost = bst.getLeftMost();
20
20
  leftMost?.key === 1; // true
21
- expect(leftMost?.key).toBe(1);
21
+ expect(leftMost).toBe(1);
22
22
  bst.delete(6);
23
23
  bst.getNode(6); // undefined
24
24
  expect(bst.getNode(6)).toBe(undefined);
@@ -68,13 +68,13 @@ describe('RedBlackTree 1', () => {
68
68
  rbTree.add(15);
69
69
  rbTree.add(3);
70
70
 
71
- const minNode = rbTree.getLeftMost(rbTree.root);
71
+ const minNode = rbTree.getLeftMost(node => node, rbTree.root);
72
72
  expect(minNode?.key).toBe(3);
73
73
  });
74
74
 
75
75
  it('should handle an empty rbTree', () => {
76
- const minNode = rbTree.getLeftMost(rbTree.root);
77
- expect(minNode).toBe(rbTree.NIL);
76
+ const minNode = rbTree.getLeftMost(node => node, rbTree.root);
77
+ expect(minNode).toBe(undefined);
78
78
  });
79
79
  });
80
80
 
@@ -86,13 +86,13 @@ describe('RedBlackTree 1', () => {
86
86
  rbTree.add(15);
87
87
  rbTree.add(25);
88
88
 
89
- const maxNode = rbTree.getRightMost(rbTree.root);
89
+ const maxNode = rbTree.getRightMost(node => node, rbTree.root);
90
90
  expect(maxNode?.key).toBe(25);
91
91
  });
92
92
 
93
93
  it('should handle an empty rbTree', () => {
94
- const maxNode = rbTree.getRightMost(rbTree.root);
95
- expect(maxNode).toBe(rbTree.NIL);
94
+ const maxNode = rbTree.getRightMost(node => node, rbTree.root);
95
+ expect(maxNode).toBe(undefined);
96
96
  });
97
97
  });
98
98
 
@@ -433,7 +433,7 @@ describe('RedBlackTree 2', () => {
433
433
  rbTree.add(15);
434
434
 
435
435
  const nodeLM = rbTree.getLeftMost();
436
- expect(nodeLM?.key).toBe(1);
436
+ expect(nodeLM).toBe(1);
437
437
 
438
438
  const node50 = rbTree.getNode(50);
439
439
  expect(node50?.key).toBe(50);
@@ -619,14 +619,14 @@ describe('RedBlackTree 2', () => {
619
619
  rbTree.add([3, 'c']);
620
620
  });
621
621
 
622
- test('The node obtained by get Node should match the node type', () => {
622
+ it('The node obtained by get Node should match the node type', () => {
623
623
  const node3 = rbTree.getNode(3);
624
624
  expect(node3).toBeInstanceOf(BinaryTreeNode);
625
625
  expect(node3).toBeInstanceOf(BSTNode);
626
626
  expect(node3).toBeInstanceOf(RedBlackTreeNode);
627
627
  });
628
628
 
629
- test('forEach should iterate over all elements', () => {
629
+ it('forEach should iterate over all elements', () => {
630
630
  const mockCallback = jest.fn();
631
631
  rbTree.forEach((value, key) => {
632
632
  mockCallback(value, key);
@@ -638,7 +638,7 @@ describe('RedBlackTree 2', () => {
638
638
  expect(mockCallback.mock.calls[2]).toEqual(['c', 3]);
639
639
  });
640
640
 
641
- test('filter should return a new rbTree with filtered elements', () => {
641
+ it('filter should return a new rbTree with filtered elements', () => {
642
642
  const filteredTree = rbTree.filter((value, key) => key > 1);
643
643
  expect(filteredTree.size).toBe(2);
644
644
  expect([...filteredTree]).toEqual([
@@ -647,7 +647,7 @@ describe('RedBlackTree 2', () => {
647
647
  ]);
648
648
  });
649
649
 
650
- test('map should return a new rbTree with modified elements', () => {
650
+ it('map should return a new rbTree with modified elements', () => {
651
651
  const mappedTree = rbTree.map((value, key) => (key * 2).toString());
652
652
  expect(mappedTree.size).toBe(3);
653
653
  expect([...mappedTree]).toEqual([
@@ -657,12 +657,12 @@ describe('RedBlackTree 2', () => {
657
657
  ]);
658
658
  });
659
659
 
660
- test('reduce should accumulate values', () => {
660
+ it('reduce should accumulate values', () => {
661
661
  const sum = rbTree.reduce((acc, value, key) => acc + key, 0);
662
662
  expect(sum).toBe(6);
663
663
  });
664
664
 
665
- test('[Symbol.iterator] should provide an iterator', () => {
665
+ it('[Symbol.iterator] should provide an iterator', () => {
666
666
  const entries = [];
667
667
  for (const entry of rbTree) {
668
668
  entries.push(entry);
@@ -677,3 +677,126 @@ describe('RedBlackTree 2', () => {
677
677
  });
678
678
  });
679
679
  });
680
+
681
+ describe('RedBlackTree - _deleteFixup', () => {
682
+ let tree: RedBlackTree<number, number>;
683
+
684
+ beforeEach(() => {
685
+ tree = new RedBlackTree();
686
+ });
687
+
688
+ it('should handle deleting a red leaf node', () => {
689
+ tree.add(10, 10);
690
+ tree.add(5, 5); // Red leaf
691
+ tree.add(20, 20);
692
+
693
+ expect(tree.delete(5)).toHaveLength(1); // Delete red leaf
694
+ expect(tree.root?.left).toBe(tree.NIL); // Left child should be NIL
695
+ });
696
+
697
+ it('should handle deleting a black leaf node', () => {
698
+ tree.add(10, 10);
699
+ tree.add(5, 5); // Black node
700
+ tree.add(20, 20);
701
+ tree.add(1, 1); // Black leaf node
702
+
703
+ expect(tree.delete(1)).toHaveLength(1); // Delete black leaf
704
+ expect(tree.root?.left?.left).toBe(tree.NIL);
705
+ });
706
+
707
+ it('should handle deleting black node with red sibling', () => {
708
+ tree.add(10, 10);
709
+ tree.add(5, 5); // Black node
710
+ tree.add(20, 20); // Red sibling
711
+ tree.add(25, 25); // Force the sibling to be red
712
+
713
+ expect(tree.delete(5)).toHaveLength(1); // Delete black node
714
+ expect(tree.root?.right?.color).toBe('BLACK'); // Ensure sibling color is black after fixup
715
+ });
716
+
717
+ it('should handle deleting black node with black sibling', () => {
718
+ tree.add(10, 10);
719
+ tree.add(5, 5); // Black node
720
+ tree.add(20, 20); // Black sibling
721
+
722
+ expect(tree.delete(5)).toHaveLength(1); // Delete black node
723
+ expect(tree.root?.left).toBe(tree.NIL);
724
+ });
725
+
726
+ it('should handle deleting the root node', () => {
727
+ tree.add(10, 10); // Root node
728
+ tree.add(5, 5);
729
+ tree.add(20, 20);
730
+
731
+ expect(tree.delete(10)).toHaveLength(1); // Delete root node
732
+ expect(tree.root?.key).toBe(20); // New root should be 20
733
+ });
734
+
735
+ it('should handle complex case with multiple rotations', () => {
736
+ tree.add(10, 10);
737
+ tree.add(5, 5);
738
+ tree.add(15, 15);
739
+ tree.add(12, 12);
740
+ tree.add(18, 18);
741
+ tree.add(16, 16);
742
+
743
+ // Delete a node that will cause rotations and color changes
744
+ expect(tree.delete(5)).toHaveLength(1);
745
+
746
+ // Verify the color and structure after fixup
747
+ expect(tree.root?.color).toBe('BLACK');
748
+ expect(tree.root?.left).toBe(tree.NIL);
749
+ expect(tree.root?.right?.left?.color).toBe('BLACK');
750
+ });
751
+
752
+ it('should handle complex delete fixup scenarios', () => {
753
+ const tree = new RedBlackTree<number, number>();
754
+
755
+ // Build a tree that will require complex fixup
756
+ tree.add(20, 20);
757
+ tree.add(10, 10);
758
+ tree.add(30, 30);
759
+ tree.add(5, 5);
760
+ tree.add(15, 15);
761
+ tree.add(25, 25);
762
+ tree.add(35, 35);
763
+ tree.add(2, 2);
764
+ tree.add(8, 8);
765
+
766
+ // This deletion should trigger a complex fixup
767
+ tree.delete(2);
768
+ // tree.print(tree.root, { isShowNull: true, isShowRedBlackNIL: true, isShowUndefined: false });
769
+
770
+ expect(tree.isLeaf(2)).toBe(false);
771
+ expect(tree.isLeaf(8)).toBe(true);
772
+ expect(tree.isLeaf(15)).toBe(true);
773
+ expect(tree.isLeaf(25)).toBe(true);
774
+ expect(tree.isLeaf(35)).toBe(true);
775
+ expect(tree.isLeaf(20)).toBe(false);
776
+ expect(tree.isLeaf(30)).toBe(false);
777
+ // Verify tree structure and colors after fixup
778
+ expect(tree.root?.color).toBe('BLACK');
779
+ expect(tree.root?.key).toBe(20);
780
+ expect(tree.root?.left?.color).toBe('RED');
781
+ expect(tree.root?.left?.key).toBe(10);
782
+ expect(tree.root?.right?.color).toBe('BLACK');
783
+ expect(tree.root?.right?.key).toBe(30);
784
+ expect(tree.root?.left?.left?.color).toBe('BLACK');
785
+ expect(tree.root?.left?.left?.key).toBe(5);
786
+ expect(tree.root?.left?.right?.color).toBe('BLACK');
787
+ expect(tree.root?.left?.right?.key).toBe(15);
788
+ expect(tree.leaves(node => (node === null ? '' : `${node.key} ${node.color}`), tree.root, 'RECURSIVE')).toEqual([
789
+ '8 RED',
790
+ '15 BLACK',
791
+ '25 RED',
792
+ '35 RED'
793
+ ]);
794
+ expect(tree.listLevels(node => (node === tree.NIL ? 'NIL' : `${node.key} ${node.color}`))).toEqual([
795
+ ['20 BLACK'],
796
+ ['10 RED', '30 BLACK'],
797
+ ['5 BLACK', '15 BLACK', '25 RED', '35 RED'],
798
+ ['NIL', '8 RED', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL'],
799
+ ['NIL', 'NIL']
800
+ ]);
801
+ });
802
+ });
@@ -142,10 +142,10 @@ describe('TreeMultiMap operations test1', () => {
142
142
  const nodesByCount2 = tmm.getNodes(2, node => node.count);
143
143
  expect(nodesByCount2.length).toBe(2);
144
144
  const leftMost = tmm.getLeftMost();
145
- expect(leftMost?.key).toBe(1);
145
+ expect(leftMost).toBe(1);
146
146
 
147
147
  const node15 = tmm.getNode(15);
148
- const minNodeBySpecificNode = node15 && tmm.getLeftMost(node15);
148
+ const minNodeBySpecificNode = node15 && tmm.getLeftMost(node => node, node15);
149
149
  expect(minNodeBySpecificNode?.key).toBe(14);
150
150
 
151
151
  let subTreeSum = 0;
@@ -400,10 +400,10 @@ describe('TreeMultiMap operations test recursively1', () => {
400
400
  const nodesByCount2 = tmm.getNodes(2, node => node.count);
401
401
  expect(nodesByCount2.length).toBe(2);
402
402
  const leftMost = tmm.getLeftMost();
403
- expect(leftMost?.key).toBe(1);
403
+ expect(leftMost).toBe(1);
404
404
 
405
405
  const node15 = tmm.getNode(15);
406
- const minNodeBySpecificNode = node15 && tmm.getLeftMost(node15);
406
+ const minNodeBySpecificNode = node15 && tmm.getLeftMost(node => node, node15);
407
407
  expect(minNodeBySpecificNode?.key).toBe(14);
408
408
 
409
409
  let subTreeSum = 0;
@@ -755,14 +755,14 @@ describe('TreeMultiMap iterative methods test', () => {
755
755
  treeMM.add([3, 'c'], undefined, 1);
756
756
  });
757
757
 
758
- test('The node obtained by get Node should match the node type', () => {
758
+ it('The node obtained by get Node should match the node type', () => {
759
759
  const node3 = treeMM.getNode(3);
760
760
  expect(node3).toBeInstanceOf(BinaryTreeNode);
761
761
  expect(node3).toBeInstanceOf(BSTNode);
762
762
  expect(node3).toBeInstanceOf(RedBlackTreeNode);
763
763
  });
764
764
 
765
- test('forEach should iterate over all elements', () => {
765
+ it('forEach should iterate over all elements', () => {
766
766
  const mockCallback = jest.fn();
767
767
  treeMM.forEach((value, key) => {
768
768
  mockCallback(value, key);
@@ -774,7 +774,7 @@ describe('TreeMultiMap iterative methods test', () => {
774
774
  expect(mockCallback.mock.calls[2]).toEqual(['c', 3]);
775
775
  });
776
776
 
777
- test('filter should return a new tree with filtered elements', () => {
777
+ it('filter should return a new tree with filtered elements', () => {
778
778
  const filteredTree = treeMM.filter((value, key) => key > 1);
779
779
  expect(filteredTree.size).toBe(2);
780
780
  expect([...filteredTree]).toEqual([
@@ -783,7 +783,7 @@ describe('TreeMultiMap iterative methods test', () => {
783
783
  ]);
784
784
  });
785
785
 
786
- test('map should return a new tree with modified elements', () => {
786
+ it('map should return a new tree with modified elements', () => {
787
787
  const mappedTree = treeMM.map((value, key) => (key * 2).toString());
788
788
  expect(mappedTree.size).toBe(3);
789
789
  expect([...mappedTree]).toEqual([
@@ -793,12 +793,12 @@ describe('TreeMultiMap iterative methods test', () => {
793
793
  ]);
794
794
  });
795
795
 
796
- test('reduce should accumulate values', () => {
796
+ it('reduce should accumulate values', () => {
797
797
  const sum = treeMM.reduce((acc, value, key) => acc + key, 0);
798
798
  expect(sum).toBe(6);
799
799
  });
800
800
 
801
- test('[Symbol.iterator] should provide an iterator', () => {
801
+ it('[Symbol.iterator] should provide an iterator', () => {
802
802
  const entries = [];
803
803
  for (const entry of treeMM) {
804
804
  entries.push(entry);
@@ -812,7 +812,7 @@ describe('TreeMultiMap iterative methods test', () => {
812
812
  ]);
813
813
  });
814
814
 
815
- test('should clone work well', () => {
815
+ it('should clone work well', () => {
816
816
  expect(treeMM.count).toBe(21);
817
817
  expect(treeMM.getComputedCount()).toBe(21);
818
818
  const cloned = treeMM.clone();
@@ -820,13 +820,18 @@ describe('TreeMultiMap iterative methods test', () => {
820
820
  expect(cloned.root?.right?.value).toBe('c');
821
821
  });
822
822
 
823
- test('should keys', () => {
823
+ it('should keys', () => {
824
824
  const keys = treeMM.keys();
825
825
  expect([...keys]).toEqual([1, 2, 3]);
826
826
  });
827
827
 
828
- test('should values', () => {
828
+ it('should values', () => {
829
829
  const values = treeMM.values();
830
830
  expect([...values]).toEqual(['a', 'b', 'c']);
831
831
  });
832
+
833
+ it('should leaves', () => {
834
+ const leaves = treeMM.leaves();
835
+ expect(leaves).toEqual([1, 3]);
836
+ });
832
837
  });