data-structure-typed 1.41.6 → 1.41.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 (107) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +11 -11
  3. package/benchmark/report.html +11 -11
  4. package/benchmark/report.json +111 -111
  5. package/dist/cjs/src/data-structures/graph/abstract-graph.js +5 -5
  6. package/dist/cjs/src/data-structures/graph/abstract-graph.js.map +1 -1
  7. package/dist/mjs/src/data-structures/graph/abstract-graph.js +5 -5
  8. package/dist/umd/data-structure-typed.min.js +1 -1
  9. package/dist/umd/data-structure-typed.min.js.map +1 -1
  10. package/package.json +5 -5
  11. package/src/data-structures/graph/abstract-graph.ts +6 -6
  12. package/test/config.ts +1 -0
  13. package/test/integration/avl-tree.test.ts +110 -0
  14. package/test/integration/bst.test.ts +385 -0
  15. package/test/integration/heap.test.js +16 -0
  16. package/test/integration/index.html +51 -0
  17. package/test/performance/data-structures/binary-tree/avl-tree.test.ts +36 -0
  18. package/test/performance/data-structures/binary-tree/binary-index-tree.test.ts +0 -0
  19. package/test/performance/data-structures/binary-tree/binary-tree.test.ts +45 -0
  20. package/test/performance/data-structures/binary-tree/bst.test.ts +36 -0
  21. package/test/performance/data-structures/binary-tree/overall.test.ts +0 -0
  22. package/test/performance/data-structures/binary-tree/rb-tree.test.ts +0 -0
  23. package/test/performance/data-structures/binary-tree/segment-tree.test.ts +0 -0
  24. package/test/performance/data-structures/binary-tree/tree-multiset.test.ts +0 -0
  25. package/test/performance/data-structures/graph/abstract-graph.test.ts +0 -0
  26. package/test/performance/data-structures/graph/directed-graph.test.ts +49 -0
  27. package/test/performance/data-structures/graph/map-graph.test.ts +0 -0
  28. package/test/performance/data-structures/graph/overall.test.ts +0 -0
  29. package/test/performance/data-structures/graph/undirected-graph.test.ts +0 -0
  30. package/test/performance/data-structures/hash/coordinate-map.test.ts +0 -0
  31. package/test/performance/data-structures/hash/coordinate-set.test.ts +0 -0
  32. package/test/performance/data-structures/hash/hash-map.test.ts +0 -0
  33. package/test/performance/data-structures/hash/hash-table.test.ts +0 -0
  34. package/test/performance/data-structures/heap/heap.test.ts +30 -0
  35. package/test/performance/data-structures/heap/max-heap.test.ts +0 -0
  36. package/test/performance/data-structures/heap/min-heap.test.ts +0 -0
  37. package/test/performance/data-structures/linked-list/doubly-linked-list.test.ts +40 -0
  38. package/test/performance/data-structures/linked-list/linked-list.test.ts +0 -0
  39. package/test/performance/data-structures/linked-list/singly-linked-list.test.ts +34 -0
  40. package/test/performance/data-structures/linked-list/skip-linked-list.test.ts +0 -0
  41. package/test/performance/data-structures/linked-list/skip-list.test.ts +0 -0
  42. package/test/performance/data-structures/matrix/matrix.test.ts +0 -0
  43. package/test/performance/data-structures/matrix/matrix2d.test.ts +0 -0
  44. package/test/performance/data-structures/matrix/navigator.test.ts +0 -0
  45. package/test/performance/data-structures/matrix/vector2d.test.ts +0 -0
  46. package/test/performance/data-structures/priority-queue/max-priority-queue.test.ts +19 -0
  47. package/test/performance/data-structures/priority-queue/min-priority-queue.test.ts +0 -0
  48. package/test/performance/data-structures/priority-queue/priority-queue.test.ts +0 -0
  49. package/test/performance/data-structures/queue/deque.test.ts +21 -0
  50. package/test/performance/data-structures/queue/queue.test.ts +25 -0
  51. package/test/performance/data-structures/stack/stack.test.ts +0 -0
  52. package/test/performance/data-structures/tree/tree.test.ts +0 -0
  53. package/test/performance/data-structures/trie/trie.test.ts +22 -0
  54. package/test/performance/reportor.ts +186 -0
  55. package/test/performance/types/index.ts +1 -0
  56. package/test/performance/types/reportor.ts +3 -0
  57. package/test/types/index.ts +1 -0
  58. package/test/types/utils/big-o.ts +1 -0
  59. package/test/types/utils/index.ts +2 -0
  60. package/test/types/utils/json2html.ts +1 -0
  61. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +269 -0
  62. package/test/unit/data-structures/binary-tree/binary-index-tree.test.ts +320 -0
  63. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +486 -0
  64. package/test/unit/data-structures/binary-tree/bst.test.ts +840 -0
  65. package/test/unit/data-structures/binary-tree/overall.test.ts +66 -0
  66. package/test/unit/data-structures/binary-tree/rb-tree.test.ts +435 -0
  67. package/test/unit/data-structures/binary-tree/segment-tree.test.ts +50 -0
  68. package/test/unit/data-structures/binary-tree/tree-multiset.test.ts +542 -0
  69. package/test/unit/data-structures/graph/abstract-graph.test.ts +100 -0
  70. package/test/unit/data-structures/graph/directed-graph.test.ts +564 -0
  71. package/test/unit/data-structures/graph/map-graph.test.ts +126 -0
  72. package/test/unit/data-structures/graph/overall.test.ts +49 -0
  73. package/test/unit/data-structures/graph/salty-edges.json +1 -0
  74. package/test/unit/data-structures/graph/salty-vertexes.json +1 -0
  75. package/test/unit/data-structures/graph/undirected-graph.test.ts +168 -0
  76. package/test/unit/data-structures/hash/coordinate-map.test.ts +74 -0
  77. package/test/unit/data-structures/hash/coordinate-set.test.ts +66 -0
  78. package/test/unit/data-structures/hash/hash-map.test.ts +103 -0
  79. package/test/unit/data-structures/hash/hash-table.test.ts +186 -0
  80. package/test/unit/data-structures/heap/heap.test.ts +254 -0
  81. package/test/unit/data-structures/heap/max-heap.test.ts +52 -0
  82. package/test/unit/data-structures/heap/min-heap.test.ts +52 -0
  83. package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +400 -0
  84. package/test/unit/data-structures/linked-list/linked-list.test.ts +8 -0
  85. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +474 -0
  86. package/test/unit/data-structures/linked-list/skip-linked-list.test.ts +13 -0
  87. package/test/unit/data-structures/linked-list/skip-list.test.ts +86 -0
  88. package/test/unit/data-structures/matrix/matrix.test.ts +54 -0
  89. package/test/unit/data-structures/matrix/matrix2d.test.ts +345 -0
  90. package/test/unit/data-structures/matrix/navigator.test.ts +244 -0
  91. package/test/unit/data-structures/matrix/vector2d.test.ts +171 -0
  92. package/test/unit/data-structures/priority-queue/max-priority-queue.test.ts +73 -0
  93. package/test/unit/data-structures/priority-queue/min-priority-queue.test.ts +63 -0
  94. package/test/unit/data-structures/priority-queue/priority-queue.test.ts +53 -0
  95. package/test/unit/data-structures/queue/deque.test.ts +410 -0
  96. package/test/unit/data-structures/queue/queue.test.ts +207 -0
  97. package/test/unit/data-structures/stack/stack.test.ts +67 -0
  98. package/test/unit/data-structures/tree/tree.test.ts +39 -0
  99. package/test/unit/data-structures/trie/trie.test.ts +825 -0
  100. package/test/utils/array.ts +5514 -0
  101. package/test/utils/big-o.ts +207 -0
  102. package/test/utils/console.ts +31 -0
  103. package/test/utils/index.ts +7 -0
  104. package/test/utils/is.ts +56 -0
  105. package/test/utils/json2html.ts +322 -0
  106. package/test/utils/number.ts +13 -0
  107. package/test/utils/string.ts +1 -0
@@ -0,0 +1,542 @@
1
+ import {CP, IterationType, TreeMultiset, TreeMultisetNode} from '../../../../src';
2
+ import {isDebugTest} from '../../../config';
3
+
4
+ const isDebug = isDebugTest;
5
+
6
+ describe('TreeMultiset operations test', () => {
7
+ it('should perform various operations on a Binary Search Tree with numeric values', () => {
8
+ const treeMultiset = new TreeMultiset();
9
+
10
+ expect(treeMultiset instanceof TreeMultiset);
11
+ treeMultiset.add(11, 11);
12
+ treeMultiset.add(3, 3);
13
+ const idAndValues = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
14
+ treeMultiset.addMany(idAndValues, idAndValues);
15
+ expect(treeMultiset.root instanceof TreeMultisetNode);
16
+
17
+ if (treeMultiset.root) expect(treeMultiset.root.key == 11);
18
+
19
+ expect(treeMultiset.size).toBe(16);
20
+ expect(treeMultiset.count).toBe(18);
21
+
22
+ expect(treeMultiset.has(6));
23
+
24
+ expect(treeMultiset.getHeight(6)).toBe(3);
25
+ expect(treeMultiset.getDepth(6)).toBe(1);
26
+ const nodeId10 = treeMultiset.getNode(10);
27
+ expect(nodeId10?.key).toBe(10);
28
+
29
+ const nodeVal9 = treeMultiset.getNode(9, node => node.value);
30
+ expect(nodeVal9?.key).toBe(9);
31
+
32
+ const nodesByCount1 = treeMultiset.getNodes(1, node => node.count);
33
+ expect(nodesByCount1.length).toBe(14);
34
+
35
+ const nodesByCount2 = treeMultiset.getNodes(2, node => node.count);
36
+ expect(nodesByCount2.length).toBe(2);
37
+ const leftMost = treeMultiset.getLeftMost();
38
+ expect(leftMost?.key).toBe(1);
39
+
40
+ const node15 = treeMultiset.getNode(15);
41
+ const minNodeBySpecificNode = node15 && treeMultiset.getLeftMost(node15);
42
+ expect(minNodeBySpecificNode?.key).toBe(12);
43
+
44
+ let subTreeSum = 0;
45
+ node15 && treeMultiset.subTreeTraverse((node: TreeMultisetNode<number>) => (subTreeSum += node.key), 15);
46
+ expect(subTreeSum).toBe(70);
47
+ let lesserSum = 0;
48
+ treeMultiset.lesserOrGreaterTraverse((node: TreeMultisetNode<number>) => (lesserSum += node.key), CP.lt, 10);
49
+ expect(lesserSum).toBe(45);
50
+
51
+ expect(node15 instanceof TreeMultisetNode);
52
+ if (node15 instanceof TreeMultisetNode) {
53
+ const subTreeAdd = treeMultiset.subTreeTraverse((node: TreeMultisetNode<number>) => (node.count += 1), 15);
54
+ expect(subTreeAdd);
55
+ }
56
+ const node11 = treeMultiset.getNode(11);
57
+ expect(node11 instanceof TreeMultisetNode);
58
+ if (node11 instanceof TreeMultisetNode) {
59
+ const allGreaterNodesAdded = treeMultiset.lesserOrGreaterTraverse(node => (node.count += 2), CP.gt, 11);
60
+ expect(allGreaterNodesAdded);
61
+ }
62
+
63
+ const dfsInorderNodes = treeMultiset.dfs(node => node, 'in');
64
+ expect(dfsInorderNodes[0].key).toBe(1);
65
+ expect(dfsInorderNodes[dfsInorderNodes.length - 1].key).toBe(16);
66
+ expect(treeMultiset.isPerfectlyBalanced()).toBe(false);
67
+
68
+ treeMultiset.perfectlyBalance();
69
+
70
+ expect(treeMultiset.isPerfectlyBalanced()).toBe(true);
71
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
72
+
73
+ const bfsNodesAfterBalanced = treeMultiset.bfs(node => node);
74
+ expect(bfsNodesAfterBalanced[0].key).toBe(8);
75
+ expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
76
+
77
+ const removed11 = treeMultiset.delete(11, undefined, true);
78
+ expect(removed11 instanceof Array);
79
+ expect(removed11[0]);
80
+ expect(removed11[0].deleted);
81
+
82
+ if (removed11[0].deleted) expect(removed11[0].deleted.key).toBe(11);
83
+
84
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
85
+
86
+ expect(treeMultiset.getHeight(15)).toBe(1);
87
+
88
+ const removed1 = treeMultiset.delete(1, undefined, true);
89
+ expect(removed1 instanceof Array);
90
+ expect(removed1[0]);
91
+ expect(removed1[0].deleted);
92
+ if (removed1[0].deleted) expect(removed1[0].deleted.key).toBe(1);
93
+
94
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
95
+
96
+ expect(treeMultiset.getHeight()).toBe(4);
97
+
98
+ const removed4 = treeMultiset.delete(4, undefined, true);
99
+ expect(removed4 instanceof Array);
100
+ expect(removed4[0]);
101
+ expect(removed4[0].deleted);
102
+ if (removed4[0].deleted) expect(removed4[0].deleted.key).toBe(4);
103
+
104
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
105
+ expect(treeMultiset.getHeight()).toBe(4);
106
+
107
+ const removed10 = treeMultiset.delete(10, undefined, true);
108
+ expect(removed10 instanceof Array);
109
+ expect(removed10[0]);
110
+ expect(removed10[0].deleted);
111
+ if (removed10[0].deleted) expect(removed10[0].deleted.key).toBe(10);
112
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
113
+
114
+ expect(treeMultiset.getHeight()).toBe(3);
115
+
116
+ const removed15 = treeMultiset.delete(15, undefined, true);
117
+ expect(removed15 instanceof Array);
118
+ expect(removed15[0]);
119
+ expect(removed15[0].deleted);
120
+ if (removed15[0].deleted) expect(removed15[0].deleted.key).toBe(15);
121
+
122
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
123
+ expect(treeMultiset.getHeight()).toBe(3);
124
+
125
+ const removed5 = treeMultiset.delete(5, undefined, true);
126
+ expect(removed5 instanceof Array);
127
+ expect(removed5[0]);
128
+ expect(removed5[0].deleted);
129
+ if (removed5[0].deleted) expect(removed5[0].deleted.key).toBe(5);
130
+
131
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
132
+ expect(treeMultiset.getHeight()).toBe(3);
133
+
134
+ const removed13 = treeMultiset.delete(13, undefined, true);
135
+ expect(removed13 instanceof Array);
136
+ expect(removed13[0]);
137
+ expect(removed13[0].deleted);
138
+ if (removed13[0].deleted) expect(removed13[0].deleted.key).toBe(13);
139
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
140
+ expect(treeMultiset.getHeight()).toBe(3);
141
+
142
+ const removed3 = treeMultiset.delete(3, undefined, true);
143
+ expect(removed3 instanceof Array);
144
+ expect(removed3[0]);
145
+ expect(removed3[0].deleted);
146
+ if (removed3[0].deleted) expect(removed3[0].deleted.key).toBe(3);
147
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
148
+ expect(treeMultiset.getHeight()).toBe(3);
149
+
150
+ const removed8 = treeMultiset.delete(8, undefined, true);
151
+ expect(removed8 instanceof Array);
152
+ expect(removed8[0]);
153
+ expect(removed8[0].deleted);
154
+ if (removed8[0].deleted) expect(removed8[0].deleted.key).toBe(8);
155
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
156
+ expect(treeMultiset.getHeight()).toBe(3);
157
+
158
+ const removed6 = treeMultiset.delete(6, undefined, true);
159
+ expect(removed6 instanceof Array);
160
+ expect(removed6[0]);
161
+ expect(removed6[0].deleted);
162
+ if (removed6[0].deleted) expect(removed6[0].deleted.key).toBe(6);
163
+ expect(treeMultiset.delete(6, undefined, true).length).toBe(0);
164
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
165
+
166
+ expect(treeMultiset.getHeight()).toBe(2);
167
+
168
+ const removed7 = treeMultiset.delete(7, undefined, true);
169
+ expect(removed7 instanceof Array);
170
+ expect(removed7[0]);
171
+ expect(removed7[0].deleted);
172
+ if (removed7[0].deleted) expect(removed7[0].deleted.key).toBe(7);
173
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
174
+ expect(treeMultiset.getHeight()).toBe(2);
175
+
176
+ const removed9 = treeMultiset.delete(9, undefined, true);
177
+ expect(removed9 instanceof Array);
178
+ expect(removed9[0]);
179
+ expect(removed9[0].deleted);
180
+ if (removed9[0].deleted) expect(removed9[0].deleted.key).toBe(9);
181
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
182
+ expect(treeMultiset.getHeight()).toBe(2);
183
+
184
+ const removed14 = treeMultiset.delete(14, undefined, true);
185
+ expect(removed14 instanceof Array);
186
+ expect(removed14[0]);
187
+ expect(removed14[0].deleted);
188
+ if (removed14[0].deleted) expect(removed14[0].deleted.key).toBe(14);
189
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
190
+ expect(treeMultiset.getHeight()).toBe(1);
191
+
192
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
193
+
194
+ const bfsIDs = treeMultiset.bfs(node => node.key);
195
+
196
+ expect(bfsIDs[0]).toBe(12);
197
+ expect(bfsIDs[1]).toBe(2);
198
+ expect(bfsIDs[2]).toBe(16);
199
+
200
+ const bfsNodes = treeMultiset.bfs(node => node);
201
+
202
+ expect(bfsNodes[0].key).toBe(12);
203
+ expect(bfsNodes[1].key).toBe(2);
204
+ expect(bfsNodes[2].key).toBe(16);
205
+
206
+ expect(treeMultiset.count).toBe(9);
207
+ });
208
+
209
+ it('should perform various operations on a Binary Search Tree with object values', () => {
210
+ const objTreeMultiset = new TreeMultiset<{key: number; keyA: number}>();
211
+ expect(objTreeMultiset).toBeInstanceOf(TreeMultiset);
212
+ objTreeMultiset.add(11, {key: 11, keyA: 11});
213
+ objTreeMultiset.add(3, {key: 3, keyA: 3});
214
+ const values = [
215
+ {key: 15, keyA: 15},
216
+ {key: 1, keyA: 1},
217
+ {key: 8, keyA: 8},
218
+ {key: 13, keyA: 13},
219
+ {key: 16, keyA: 16},
220
+ {key: 2, keyA: 2},
221
+ {key: 6, keyA: 6},
222
+ {key: 9, keyA: 9},
223
+ {key: 12, keyA: 12},
224
+ {key: 14, keyA: 14},
225
+ {key: 4, keyA: 4},
226
+ {key: 7, keyA: 7},
227
+ {key: 10, keyA: 10},
228
+ {key: 5, keyA: 5}
229
+ ];
230
+
231
+ objTreeMultiset.addMany(
232
+ values.map(item => item.key),
233
+ values
234
+ );
235
+
236
+ expect(objTreeMultiset.root).toBeInstanceOf(TreeMultisetNode);
237
+
238
+ if (objTreeMultiset.root) expect(objTreeMultiset.root.key).toBe(11);
239
+
240
+ expect(objTreeMultiset.count).toBe(16);
241
+
242
+ expect(objTreeMultiset.has(6)).toBe(true);
243
+ });
244
+ });
245
+
246
+ describe('TreeMultiset operations test recursively', () => {
247
+ it('should perform various operations on a Binary Search Tree with numeric values', () => {
248
+ const treeMultiset = new TreeMultiset({iterationType: IterationType.RECURSIVE});
249
+
250
+ expect(treeMultiset instanceof TreeMultiset);
251
+ treeMultiset.add(11, 11);
252
+ treeMultiset.add(3, 3);
253
+ const idAndValues = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
254
+ treeMultiset.addMany(idAndValues, idAndValues);
255
+ expect(treeMultiset.root instanceof TreeMultisetNode);
256
+
257
+ if (treeMultiset.root) expect(treeMultiset.root.key == 11);
258
+
259
+ expect(treeMultiset.size).toBe(16);
260
+ expect(treeMultiset.count).toBe(18);
261
+
262
+ expect(treeMultiset.has(6));
263
+
264
+ expect(treeMultiset.getHeight(6)).toBe(3);
265
+ expect(treeMultiset.getDepth(6)).toBe(1);
266
+ const nodeId10 = treeMultiset.getNode(10);
267
+ expect(nodeId10?.key).toBe(10);
268
+
269
+ const nodeVal9 = treeMultiset.getNode(9, node => node.value);
270
+ expect(nodeVal9?.key).toBe(9);
271
+
272
+ const nodesByCount1 = treeMultiset.getNodes(1, node => node.count);
273
+ expect(nodesByCount1.length).toBe(14);
274
+
275
+ const nodesByCount2 = treeMultiset.getNodes(2, node => node.count);
276
+ expect(nodesByCount2.length).toBe(2);
277
+ const leftMost = treeMultiset.getLeftMost();
278
+ expect(leftMost?.key).toBe(1);
279
+
280
+ const node15 = treeMultiset.getNode(15);
281
+ const minNodeBySpecificNode = node15 && treeMultiset.getLeftMost(node15);
282
+ expect(minNodeBySpecificNode?.key).toBe(12);
283
+
284
+ let subTreeSum = 0;
285
+ node15 && treeMultiset.subTreeTraverse((node: TreeMultisetNode<number>) => (subTreeSum += node.key), 15);
286
+ expect(subTreeSum).toBe(70);
287
+ let lesserSum = 0;
288
+ treeMultiset.lesserOrGreaterTraverse((node: TreeMultisetNode<number>) => (lesserSum += node.key), CP.lt, 10);
289
+ expect(lesserSum).toBe(45);
290
+
291
+ expect(node15 instanceof TreeMultisetNode);
292
+ if (node15 instanceof TreeMultisetNode) {
293
+ const subTreeAdd = treeMultiset.subTreeTraverse((node: TreeMultisetNode<number>) => (node.count += 1), 15);
294
+ expect(subTreeAdd);
295
+ }
296
+ const node11 = treeMultiset.getNode(11);
297
+ expect(node11 instanceof TreeMultisetNode);
298
+ if (node11 instanceof TreeMultisetNode) {
299
+ const allGreaterNodesAdded = treeMultiset.lesserOrGreaterTraverse(node => (node.count += 2), CP.gt, 11);
300
+ expect(allGreaterNodesAdded);
301
+ }
302
+
303
+ const dfsInorderNodes = treeMultiset.dfs(node => node, 'in');
304
+ expect(dfsInorderNodes[0].key).toBe(1);
305
+ expect(dfsInorderNodes[dfsInorderNodes.length - 1].key).toBe(16);
306
+ expect(treeMultiset.isPerfectlyBalanced()).toBe(false);
307
+
308
+ treeMultiset.perfectlyBalance();
309
+
310
+ expect(treeMultiset.isPerfectlyBalanced()).toBe(true);
311
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
312
+
313
+ const bfsNodesAfterBalanced = treeMultiset.bfs(node => node);
314
+ expect(bfsNodesAfterBalanced[0].key).toBe(8);
315
+ expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
316
+
317
+ const removed11 = treeMultiset.delete(11, undefined, true);
318
+ expect(removed11 instanceof Array);
319
+ expect(removed11[0]);
320
+ expect(removed11[0].deleted);
321
+
322
+ if (removed11[0].deleted) expect(removed11[0].deleted.key).toBe(11);
323
+
324
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
325
+
326
+ expect(treeMultiset.getHeight(15)).toBe(1);
327
+
328
+ const removed1 = treeMultiset.delete(1, undefined, true);
329
+ expect(removed1 instanceof Array);
330
+ expect(removed1[0]);
331
+ expect(removed1[0].deleted);
332
+ if (removed1[0].deleted) expect(removed1[0].deleted.key).toBe(1);
333
+
334
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
335
+
336
+ expect(treeMultiset.getHeight()).toBe(4);
337
+
338
+ const removed4 = treeMultiset.delete(4, undefined, true);
339
+ expect(removed4 instanceof Array);
340
+ expect(removed4[0]);
341
+ expect(removed4[0].deleted);
342
+ if (removed4[0].deleted) expect(removed4[0].deleted.key).toBe(4);
343
+
344
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
345
+ expect(treeMultiset.getHeight()).toBe(4);
346
+
347
+ const removed10 = treeMultiset.delete(10, undefined, true);
348
+ expect(removed10 instanceof Array);
349
+ expect(removed10[0]);
350
+ expect(removed10[0].deleted);
351
+ if (removed10[0].deleted) expect(removed10[0].deleted.key).toBe(10);
352
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
353
+
354
+ expect(treeMultiset.getHeight()).toBe(3);
355
+
356
+ const removed15 = treeMultiset.delete(15, undefined, true);
357
+ expect(removed15 instanceof Array);
358
+ expect(removed15[0]);
359
+ expect(removed15[0].deleted);
360
+ if (removed15[0].deleted) expect(removed15[0].deleted.key).toBe(15);
361
+
362
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
363
+ expect(treeMultiset.getHeight()).toBe(3);
364
+
365
+ const removed5 = treeMultiset.delete(5, undefined, true);
366
+ expect(removed5 instanceof Array);
367
+ expect(removed5[0]);
368
+ expect(removed5[0].deleted);
369
+ if (removed5[0].deleted) expect(removed5[0].deleted.key).toBe(5);
370
+
371
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
372
+ expect(treeMultiset.getHeight()).toBe(3);
373
+
374
+ const removed13 = treeMultiset.delete(13, undefined, true);
375
+ expect(removed13 instanceof Array);
376
+ expect(removed13[0]);
377
+ expect(removed13[0].deleted);
378
+ if (removed13[0].deleted) expect(removed13[0].deleted.key).toBe(13);
379
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
380
+ expect(treeMultiset.getHeight()).toBe(3);
381
+
382
+ const removed3 = treeMultiset.delete(3, undefined, true);
383
+ expect(removed3 instanceof Array);
384
+ expect(removed3[0]);
385
+ expect(removed3[0].deleted);
386
+ if (removed3[0].deleted) expect(removed3[0].deleted.key).toBe(3);
387
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
388
+ expect(treeMultiset.getHeight()).toBe(3);
389
+
390
+ const removed8 = treeMultiset.delete(8, undefined, true);
391
+ expect(removed8 instanceof Array);
392
+ expect(removed8[0]);
393
+ expect(removed8[0].deleted);
394
+ if (removed8[0].deleted) expect(removed8[0].deleted.key).toBe(8);
395
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
396
+ expect(treeMultiset.getHeight()).toBe(3);
397
+
398
+ const removed6 = treeMultiset.delete(6, undefined, true);
399
+ expect(removed6 instanceof Array);
400
+ expect(removed6[0]);
401
+ expect(removed6[0].deleted);
402
+ if (removed6[0].deleted) expect(removed6[0].deleted.key).toBe(6);
403
+ expect(treeMultiset.delete(6, undefined, true).length).toBe(0);
404
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
405
+
406
+ expect(treeMultiset.getHeight()).toBe(2);
407
+
408
+ const removed7 = treeMultiset.delete(7, undefined, true);
409
+ expect(removed7 instanceof Array);
410
+ expect(removed7[0]);
411
+ expect(removed7[0].deleted);
412
+ if (removed7[0].deleted) expect(removed7[0].deleted.key).toBe(7);
413
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
414
+ expect(treeMultiset.getHeight()).toBe(2);
415
+
416
+ const removed9 = treeMultiset.delete(9, undefined, true);
417
+ expect(removed9 instanceof Array);
418
+ expect(removed9[0]);
419
+ expect(removed9[0].deleted);
420
+ if (removed9[0].deleted) expect(removed9[0].deleted.key).toBe(9);
421
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
422
+ expect(treeMultiset.getHeight()).toBe(2);
423
+
424
+ const removed14 = treeMultiset.delete(14, undefined, true);
425
+ expect(removed14 instanceof Array);
426
+ expect(removed14[0]);
427
+ expect(removed14[0].deleted);
428
+ if (removed14[0].deleted) expect(removed14[0].deleted.key).toBe(14);
429
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
430
+ expect(treeMultiset.getHeight()).toBe(1);
431
+
432
+ expect(treeMultiset.isAVLBalanced()).toBe(true);
433
+
434
+ const bfsIDs = treeMultiset.bfs(node => node.key);
435
+
436
+ expect(bfsIDs[0]).toBe(12);
437
+ expect(bfsIDs[1]).toBe(2);
438
+ expect(bfsIDs[2]).toBe(16);
439
+
440
+ const bfsNodes = treeMultiset.bfs(node => node);
441
+
442
+ expect(bfsNodes[0].key).toBe(12);
443
+ expect(bfsNodes[1].key).toBe(2);
444
+ expect(bfsNodes[2].key).toBe(16);
445
+
446
+ expect(treeMultiset.count).toBe(9);
447
+ });
448
+
449
+ it('should perform various operations on a Binary Search Tree with object values', () => {
450
+ const objTreeMultiset = new TreeMultiset<{key: number; keyA: number}>();
451
+ expect(objTreeMultiset).toBeInstanceOf(TreeMultiset);
452
+ objTreeMultiset.add(11, {key: 11, keyA: 11});
453
+ objTreeMultiset.add(3, {key: 3, keyA: 3});
454
+ const values = [
455
+ {key: 15, keyA: 15},
456
+ {key: 1, keyA: 1},
457
+ {key: 8, keyA: 8},
458
+ {key: 13, keyA: 13},
459
+ {key: 16, keyA: 16},
460
+ {key: 2, keyA: 2},
461
+ {key: 6, keyA: 6},
462
+ {key: 9, keyA: 9},
463
+ {key: 12, keyA: 12},
464
+ {key: 14, keyA: 14},
465
+ {key: 4, keyA: 4},
466
+ {key: 7, keyA: 7},
467
+ {key: 10, keyA: 10},
468
+ {key: 5, keyA: 5}
469
+ ];
470
+
471
+ objTreeMultiset.addMany(
472
+ values.map(item => item.key),
473
+ values
474
+ );
475
+
476
+ expect(objTreeMultiset.root).toBeInstanceOf(TreeMultisetNode);
477
+
478
+ if (objTreeMultiset.root) expect(objTreeMultiset.root.key).toBe(11);
479
+
480
+ expect(objTreeMultiset.count).toBe(16);
481
+
482
+ expect(objTreeMultiset.has(6)).toBe(true);
483
+ });
484
+ });
485
+
486
+ describe('TreeMultiset Performance test', function () {
487
+ const treeMS = new TreeMultiset<TreeMultisetNode<number>>();
488
+ const inputSize = 100000; // Adjust input sizes as needed
489
+
490
+ beforeEach(() => {
491
+ treeMS.clear();
492
+ });
493
+ it(`Observe the time consumption of TreeMultiset.add fitting O(n log n)`, function () {
494
+ // // Create a benchmark suite
495
+ // const suite = new Benchmark.Suite();
496
+ // // Define a function to generate a random array of a given size
497
+ // function generateRandomArray(size: number): number[] {
498
+ // const arr: number[] = [];
499
+ // for (let i = 0; i < size; i++) {
500
+ // arr.push(Math.floor(Math.random() * size));
501
+ // }
502
+ // return arr;
503
+ // }
504
+ // const inputArray = generateRandomArray(inputSize[0]);
505
+ //
506
+ // suite.add(`TreeMultiset addMany (n=${inputSize[0]})`, () => {
507
+ // treeMS.addMany([...inputArray]);
508
+ // });
509
+ //
510
+ // // Run the benchmarks
511
+ // suite
512
+ // .on('cycle', (event: any) => {
513
+ // const benchmark = event.target;
514
+ // const n = parseInt(benchmark.name.split('=')[1]);
515
+ // const observedTime = benchmark.times.elapsed;
516
+ // const expected = expectedTime(n);
517
+ // console.log(`Input size (n): ${n}, Observed time: ${observedTime.toFixed(2)}ms, Expected time: ${expected.toFixed(2)}ms`);
518
+ // })
519
+ // .on('complete', () => {
520
+ // console.log(`Benchmark (n=${inputSize[0]}) completed.`);
521
+ // done(); // Call done to indicate the test is complete
522
+ // })
523
+ // .run({async: true});
524
+ });
525
+
526
+ it(`Observe the time consumption of TreeMultiset.dfs be good`, function () {
527
+ const startDFS = performance.now();
528
+ const dfs = treeMS.dfs(node => node);
529
+ isDebug && console.log('---bfs', performance.now() - startDFS, dfs.length);
530
+ });
531
+
532
+ it('Should the time consumption of lesserOrGreaterTraverse fitting O(n log n)', function () {
533
+ const start = performance.now();
534
+ for (let i = 0; i < inputSize; i++) {
535
+ treeMS.add(i);
536
+ }
537
+ isDebug && console.log('---add', performance.now() - start);
538
+ const startL = performance.now();
539
+ treeMS.lesserOrGreaterTraverse(node => (node.count += 1), CP.lt, inputSize / 2);
540
+ isDebug && console.log('---lesserOrGreaterTraverse', performance.now() - startL);
541
+ });
542
+ });
@@ -0,0 +1,100 @@
1
+ import {AbstractEdge, AbstractGraph, AbstractVertex, VertexKey} from '../../../../src';
2
+
3
+ class MyVertex<V = any> extends AbstractVertex<V> {
4
+ data?: V;
5
+
6
+ constructor(key: VertexKey, value?: V) {
7
+ super(key, value);
8
+ this.data = value;
9
+ }
10
+ }
11
+
12
+ class MyEdge<E = any> extends AbstractEdge<E> {
13
+ data?: E;
14
+ src: VertexKey;
15
+ dest: VertexKey;
16
+
17
+ constructor(srcOrV1: VertexKey, destOrV2: VertexKey, weight?: number, value?: E) {
18
+ super(weight, value);
19
+ this.src = srcOrV1;
20
+ this.dest = destOrV2;
21
+ this.data = value;
22
+ }
23
+ }
24
+
25
+ class MyGraph<
26
+ V = any,
27
+ E = any,
28
+ VO extends MyVertex<V> = MyVertex<V>,
29
+ EO extends MyEdge<E> = MyEdge<E>
30
+ > extends AbstractGraph<V, E, VO, EO> {
31
+ createVertex(key: VertexKey, value?: V): VO {
32
+ return new MyVertex(key, value) as VO;
33
+ }
34
+
35
+ createEdge(srcOrV1: VertexKey, destOrV2: VertexKey, weight?: number, value?: E): EO {
36
+ return new MyEdge(srcOrV1, destOrV2, weight, value) as EO;
37
+ }
38
+
39
+ deleteEdge(edge: EO): EO | null {
40
+ return edge;
41
+ }
42
+
43
+ getEdge(srcOrKey: VertexKey, destOrKey: VertexKey): EO | null {
44
+ return new MyEdge(srcOrKey, destOrKey) as EO;
45
+ }
46
+
47
+ degreeOf(vertexOrKey: VO | VertexKey): number {
48
+ return 1 ?? Number(vertexOrKey);
49
+ }
50
+
51
+ edgeSet(): EO[] {
52
+ return [new MyEdge('a', 'b') as EO];
53
+ }
54
+
55
+ edgesOf(vertexOrKey: VO | VertexKey): EO[] {
56
+ const a = typeof vertexOrKey === 'string' ? vertexOrKey : 'a';
57
+ return [new MyEdge(a, 'b') as EO];
58
+ }
59
+
60
+ getNeighbors(vertexOrKey: VO | VertexKey): VO[] {
61
+ const a = typeof vertexOrKey === 'string' ? vertexOrKey : 'a';
62
+ return [new MyVertex(a, 'b') as VO];
63
+ }
64
+
65
+ getEndsOfEdge(edge: EO): [VO, VO] | null {
66
+ return edge ? null : null;
67
+ }
68
+
69
+ protected _addEdgeOnly(edge: EO): boolean {
70
+ return edge ? true : true;
71
+ }
72
+ }
73
+
74
+ describe('AbstractGraph Operation Test', () => {
75
+ const myGraph: MyGraph<number, string> = new MyGraph<number, string>();
76
+
77
+ beforeEach(() => {});
78
+ it('should edge cases', function () {
79
+ myGraph.addVertex('A', 1);
80
+ myGraph.addVertex('B', 2);
81
+ myGraph.addVertex('C', 3);
82
+ myGraph.addVertex('D', 4);
83
+
84
+ const vA = myGraph.getVertex('A');
85
+ // const vB = myGraph.getVertex('B');
86
+ // const vC = myGraph.getVertex('C');
87
+ // const vD = myGraph.getVertex('D');
88
+
89
+ const eAB = new MyEdge('A', 'B');
90
+ // const eBC = new MyEdge('B', 'C');
91
+ // const eCD = new MyEdge('C', 'D');
92
+ vA!.key = vA?.key || 1;
93
+ vA!.value = vA?.value ?? 2;
94
+
95
+ eAB!.value = eAB.value;
96
+ const hs = eAB.hashCode;
97
+
98
+ expect(hs.length).toBe(36);
99
+ });
100
+ });