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,4 +1,4 @@
1
- import { BinaryTree, BinaryTreeNode } from '../../../../src';
1
+ import { BinaryTree, BinaryTreeNode, BTNEntry } from '../../../../src';
2
2
  import { getRandomIntArray } from '../../../utils';
3
3
  // import { isDebugTest } from '../../../config';
4
4
 
@@ -86,6 +86,27 @@ describe('BinaryTreeNode', () => {
86
86
  });
87
87
  });
88
88
 
89
+ describe('BinaryTree addMany', () => {
90
+ it('should addMany', () => {
91
+ const tree = new BinaryTree<number, number, { id: number; name: number }>([], {
92
+ toEntryFn: ({ id, name }) => [id, name]
93
+ });
94
+ tree.addMany(
95
+ [
96
+ { id: 1, name: 1 },
97
+ { id: 2, name: 2 },
98
+ { id: 4, name: 4 },
99
+ { id: 3, name: 3 }
100
+ ],
101
+ [undefined, 22, 44, 33]
102
+ );
103
+ expect(tree.getNodeByKey(2)?.value).toBe(22);
104
+ expect(tree.getNodeByKey(3)?.value).toBe(33);
105
+ expect(tree.getNodeByKey(4)?.value).toBe(44);
106
+ expect(tree.getNodeByKey(1)?.value).toBe(1);
107
+ });
108
+ });
109
+
89
110
  describe('BinaryTree', () => {
90
111
  let tree: BinaryTree<number>;
91
112
 
@@ -258,15 +279,6 @@ describe('BinaryTree', () => {
258
279
  expect(inOrder).toEqual([1, 2, 3, 4, 5, 6, 7]);
259
280
  });
260
281
 
261
- it('should getLeftMost', () => {
262
- tree.addMany([4, 2, 6, 1, 3, 5, 7]);
263
-
264
- const leftMost = tree.getLeftMost(tree.root, 'RECURSIVE');
265
- expect(leftMost?.key).toEqual(1);
266
- const rightMost = tree.getRightMost(tree.root, 'RECURSIVE');
267
- expect(rightMost?.key).toEqual(7);
268
- });
269
-
270
282
  it('should isSubtreeBST', () => {
271
283
  tree.addMany([
272
284
  new BinaryTreeNode(4, 4),
@@ -285,36 +297,359 @@ describe('BinaryTree', () => {
285
297
 
286
298
  it('should isSubtreeBST', () => {
287
299
  tree.addMany([4, 2, 6, 1, 3, 5, 7, 4]);
300
+ expect(tree.print()).toBe(
301
+ ' ___4___ \n' +
302
+ ' / \\ \n' +
303
+ ' _2_ _6_ \n' +
304
+ ' / \\ / \\ \n' +
305
+ ' 1 3 5 7 \n' +
306
+ ' \n'
307
+ );
288
308
 
289
309
  expect(tree.isBST(tree.getNode(4), 'RECURSIVE')).toBe(true);
290
310
  expect(tree.isBST(tree.getNode(4), 'ITERATIVE')).toBe(true);
291
311
  expect(tree.getNodes(2, undefined, false, null)).toEqual([]);
312
+ expect(tree.getNodes(undefined)).toEqual([]);
292
313
  expect(tree.getNodes(tree.getNodeByKey(2), undefined, false, tree.root)).toEqual([tree.getNodeByKey(2)]);
293
314
  });
294
315
 
316
+ describe('should isKey', () => {
317
+ describe('primitive types', () => {
318
+ it('numbers should be a key', () => {
319
+ expect(tree.isKey(42)).toBe(true);
320
+ expect(tree.isKey(0)).toBe(true);
321
+ expect(tree.isKey(-1)).toBe(true);
322
+ expect(tree.isKey(Infinity)).toBe(true);
323
+ expect(tree.isKey(-Infinity)).toBe(true);
324
+ });
325
+
326
+ it('NaN should not be a key', () => {
327
+ expect(tree.isKey(NaN)).toBe(false);
328
+ });
329
+
330
+ it('strings should be a key', () => {
331
+ expect(tree.isKey('hello')).toBe(true);
332
+ expect(tree.isKey('')).toBe(true);
333
+ expect(tree.isKey('123')).toBe(true);
334
+ });
335
+
336
+ it('BigInt should be a key', () => {
337
+ expect(tree.isKey(BigInt(42))).toBe(true);
338
+ expect(tree.isKey(BigInt(0))).toBe(true);
339
+ expect(tree.isKey(BigInt(-1))).toBe(true);
340
+ });
341
+
342
+ it('boolean should not be a key', () => {
343
+ expect(tree.isKey(true)).toBe(true);
344
+ expect(tree.isKey(false)).toBe(true);
345
+ });
346
+
347
+ it('null and undefined should not be a key', () => {
348
+ expect(tree.isKey(null)).toBe(true);
349
+ expect(tree.isKey(undefined)).toBe(false);
350
+ });
351
+
352
+ it('symbols should not be a key', () => {
353
+ expect(tree.isKey(Symbol('test'))).toBe(false);
354
+ expect(tree.isKey(Symbol.for('test'))).toBe(false);
355
+ });
356
+ });
357
+
358
+ describe('Date objects', () => {
359
+ it('valid Date objects should be a key', () => {
360
+ expect(tree.isKey(new Date())).toBe(true);
361
+ expect(tree.isKey(new Date('2024-01-01'))).toBe(true);
362
+ });
363
+
364
+ it('invalid Date objects should not be a key', () => {
365
+ expect(tree.isKey(new Date('invalid'))).toBe(false);
366
+ });
367
+ });
368
+
369
+ describe('arrays', () => {
370
+ it('arrays should be a key as they convert to string', () => {
371
+ expect(tree.isKey([])).toBe(true);
372
+ expect(tree.isKey([1, 2, 3])).toBe(true);
373
+ expect(tree.isKey(['a', 'b', 'c'])).toBe(true);
374
+ });
375
+ });
376
+
377
+ describe('plain objects', () => {
378
+ it('plain objects should not be a key', () => {
379
+ expect(tree.isKey({})).toBe(false);
380
+ expect(tree.isKey({ a: 1 })).toBe(false);
381
+ });
382
+ });
383
+
384
+ describe('custom objects', () => {
385
+ it('objects with numeric valueOf should be a key', () => {
386
+ expect(tree.isKey({ valueOf: () => 42 })).toBe(true);
387
+ });
388
+
389
+ it('objects with string valueOf should be a key', () => {
390
+ expect(tree.isKey({ valueOf: () => 'test' })).toBe(true);
391
+ });
392
+
393
+ it('objects with boolean valueOf should not be a key', () => {
394
+ expect(tree.isKey({ valueOf: () => true })).toBe(true);
395
+ });
396
+
397
+ it('objects with nested valueOf/toString should be a key', () => {
398
+ expect(
399
+ tree.isKey({
400
+ valueOf: () => ({ toString: () => '42' })
401
+ })
402
+ ).toBe(true);
403
+ });
404
+ });
405
+
406
+ describe('deeply nested objects', () => {
407
+ it('objects with deeply nested valueOf should be a key', () => {
408
+ const deeplyNested = {
409
+ valueOf: () => ({
410
+ valueOf: () => 42
411
+ })
412
+ };
413
+ expect(tree.isKey(deeplyNested)).toBe(true);
414
+ });
415
+
416
+ it('objects with very deeply nested conversion should be a key', () => {
417
+ const veryDeeplyNested = {
418
+ valueOf: () => ({
419
+ valueOf: () => ({
420
+ toString: () => '42'
421
+ })
422
+ })
423
+ };
424
+ expect(tree.isKey(veryDeeplyNested)).toBe(true);
425
+ });
426
+
427
+ it('objects with circular references should not be a key', () => {
428
+ const circular: any = {
429
+ valueOf: () => circular
430
+ };
431
+ expect(tree.isKey(circular)).toBe(false);
432
+ });
433
+ });
434
+
435
+ describe('edge cases', () => {
436
+ it('objects returning non-primitive values should be handled correctly', () => {
437
+ const complexObject = {
438
+ valueOf: () => ({
439
+ toString: () => ({
440
+ valueOf: () => 'valid'
441
+ })
442
+ })
443
+ };
444
+ expect(tree.isKey(complexObject)).toBe(false);
445
+ });
446
+
447
+ it('objects returning primitive values should be handled correctly', () => {
448
+ const complexObject = {
449
+ valueOf: () => ({
450
+ valueOf: () => ({
451
+ valueOf: () => ({
452
+ valueOf: () => ({
453
+ toString: () => `{
454
+ valueOf: () => 'valid'
455
+ }`
456
+ })
457
+ })
458
+ })
459
+ })
460
+ };
461
+ expect(tree.isKey(complexObject)).toBe(true);
462
+ });
463
+ });
464
+
465
+ describe('type checking', () => {
466
+ it('should work with type guard in array methods', () => {
467
+ const values: unknown[] = [42, 'test', true, null, undefined, new Date()];
468
+ const comparableValues = values.filter(item => tree.isKey(item));
469
+ expect(comparableValues.length).toBe(5);
470
+ });
471
+ });
472
+ });
473
+
474
+ it('should isLeaf', () => {
475
+ tree.addMany([4, 2, 6, 1, 3, 5, 7, 4]);
476
+ const leftMost = tree.getLeftMost();
477
+ expect(tree.isLeaf(leftMost)).toBe(true);
478
+ expect(tree.isLeaf(null)).toBe(true);
479
+ });
480
+
481
+ it('should tree traverse', () => {
482
+ tree.addMany([4, 2, 6, null, 1, 3, null, 5, null, 7]);
483
+ expect(tree.dfs(node => node.key, 'PRE', undefined, 'ITERATIVE')).toEqual([4, 2, 1, 5, 6, 3, 7]);
484
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'PRE', undefined, 'ITERATIVE', false)).toEqual([
485
+ 4, 2, 1, 5, 6, 3, 7
486
+ ]);
487
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'PRE', undefined, 'ITERATIVE', true)).toEqual([
488
+ 4,
489
+ 2,
490
+ null,
491
+ 1,
492
+ 5,
493
+ null,
494
+ 6,
495
+ 3,
496
+ 7,
497
+ null
498
+ ]);
499
+
500
+ expect(tree.dfs(node => node.key, 'PRE', undefined, 'RECURSIVE')).toEqual([4, 2, 1, 5, 6, 3, 7]);
501
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'PRE', undefined, 'RECURSIVE', false)).toEqual([
502
+ 4, 2, 1, 5, 6, 3, 7
503
+ ]);
504
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'PRE', undefined, 'RECURSIVE', true)).toEqual([
505
+ 4,
506
+ 2,
507
+ null,
508
+ 1,
509
+ 5,
510
+ null,
511
+ 6,
512
+ 3,
513
+ 7,
514
+ null
515
+ ]);
516
+
517
+ expect(tree.dfs(node => node.key, 'IN', undefined, 'ITERATIVE')).toEqual([2, 5, 1, 4, 7, 3, 6]);
518
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'IN', undefined, 'ITERATIVE', false)).toEqual([
519
+ 2, 5, 1, 4, 7, 3, 6
520
+ ]);
521
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'IN', undefined, 'ITERATIVE', true)).toEqual([
522
+ null,
523
+ 2,
524
+ 5,
525
+ 1,
526
+ null,
527
+ 4,
528
+ 7,
529
+ 3,
530
+ 6,
531
+ null
532
+ ]);
533
+
534
+ expect(tree.dfs(node => node.key, 'IN', undefined, 'RECURSIVE')).toEqual([2, 5, 1, 4, 7, 3, 6]);
535
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'IN', undefined, 'RECURSIVE', false)).toEqual([
536
+ 2, 5, 1, 4, 7, 3, 6
537
+ ]);
538
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'IN', undefined, 'RECURSIVE', true)).toEqual([
539
+ null,
540
+ 2,
541
+ 5,
542
+ 1,
543
+ null,
544
+ 4,
545
+ 7,
546
+ 3,
547
+ 6,
548
+ null
549
+ ]);
550
+
551
+ expect(tree.dfs(node => node.key, 'POST', undefined, 'ITERATIVE')).toEqual([5, 1, 2, 7, 3, 6, 4]);
552
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'POST', undefined, 'ITERATIVE', false)).toEqual([
553
+ 5, 1, 2, 7, 3, 6, 4
554
+ ]);
555
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'POST', undefined, 'ITERATIVE', true)).toEqual([
556
+ null,
557
+ 5,
558
+ null,
559
+ 1,
560
+ 2,
561
+ 7,
562
+ 3,
563
+ null,
564
+ 6,
565
+ 4
566
+ ]);
567
+
568
+ expect(tree.dfs(node => node.key, 'POST', undefined, 'RECURSIVE')).toEqual([5, 1, 2, 7, 3, 6, 4]);
569
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'POST', undefined, 'RECURSIVE', false)).toEqual([
570
+ 5, 1, 2, 7, 3, 6, 4
571
+ ]);
572
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'POST', undefined, 'RECURSIVE', true)).toEqual([
573
+ null,
574
+ 5,
575
+ null,
576
+ 1,
577
+ 2,
578
+ 7,
579
+ 3,
580
+ null,
581
+ 6,
582
+ 4
583
+ ]);
584
+ });
585
+
295
586
  it('should sub tree traverse', () => {
296
587
  tree.addMany([4, 2, 6, null, 1, 3, null, 5, null, 7]);
297
588
  expect(tree.dfs(node => node.key, 'PRE', tree.getNode(6), 'ITERATIVE')).toEqual([6, 3, 7]);
298
- expect(tree.dfs(node => node.key, 'PRE', tree.getNode(6), 'ITERATIVE', false)).toEqual([6, 3, 7]);
299
- expect(tree.dfs(node => node.key, 'PRE', tree.getNode(6), 'RECURSIVE')).toEqual([6, 3, 7]);
300
- expect(tree.dfs(node => (node ? node.key : null), 'PRE', tree.getNode(6), 'ITERATIVE', true)).toEqual([
589
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'PRE', tree.getNode(6), 'ITERATIVE', false)).toEqual([
590
+ 6, 3, 7
591
+ ]);
592
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'PRE', tree.getNode(6), 'ITERATIVE', true)).toEqual([
301
593
  6,
302
594
  3,
303
595
  7,
304
596
  null
305
597
  ]);
306
- expect(tree.dfs(node => (node ? node.key : node), 'PRE', tree.getNode(6), 'ITERATIVE', true)).toEqual([
598
+
599
+ expect(tree.dfs(node => node.key, 'PRE', tree.getNode(6), 'RECURSIVE')).toEqual([6, 3, 7]);
600
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'PRE', tree.getNode(6), 'RECURSIVE', false)).toEqual([
601
+ 6, 3, 7
602
+ ]);
603
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'PRE', tree.getNode(6), 'RECURSIVE', true)).toEqual([
307
604
  6,
308
605
  3,
309
606
  7,
310
607
  null
311
608
  ]);
312
- expect(tree.dfs(node => (node ? node.key : null), 'PRE', tree.getNode(6), 'RECURSIVE', true)).toEqual([
313
- 6,
609
+
610
+ expect(tree.dfs(node => node.key, 'IN', tree.getNode(6), 'ITERATIVE')).toEqual([7, 3, 6]);
611
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'IN', tree.getNode(6), 'ITERATIVE', false)).toEqual([
612
+ 7, 3, 6
613
+ ]);
614
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'IN', tree.getNode(6), 'ITERATIVE', true)).toEqual([
615
+ 7,
314
616
  3,
617
+ 6,
618
+ null
619
+ ]);
620
+
621
+ expect(tree.dfs(node => node.key, 'IN', tree.getNode(6), 'RECURSIVE')).toEqual([7, 3, 6]);
622
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'IN', tree.getNode(6), 'RECURSIVE', false)).toEqual([
623
+ 7, 3, 6
624
+ ]);
625
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'IN', tree.getNode(6), 'RECURSIVE', true)).toEqual([
315
626
  7,
627
+ 3,
628
+ 6,
316
629
  null
317
630
  ]);
631
+
632
+ expect(tree.dfs(node => node.key, 'POST', tree.getNode(6), 'ITERATIVE')).toEqual([7, 3, 6]);
633
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'POST', tree.getNode(6), 'ITERATIVE', false)).toEqual([
634
+ 7, 3, 6
635
+ ]);
636
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'POST', tree.getNode(6), 'ITERATIVE', true)).toEqual([
637
+ 7,
638
+ 3,
639
+ null,
640
+ 6
641
+ ]);
642
+
643
+ expect(tree.dfs(node => node.key, 'POST', tree.getNode(6), 'RECURSIVE')).toEqual([7, 3, 6]);
644
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'POST', tree.getNode(6), 'RECURSIVE', false)).toEqual([
645
+ 7, 3, 6
646
+ ]);
647
+ expect(tree.dfs(node => (node !== null ? node.key : null), 'POST', tree.getNode(6), 'RECURSIVE', true)).toEqual([
648
+ 7,
649
+ 3,
650
+ null,
651
+ 6
652
+ ]);
318
653
  });
319
654
 
320
655
  it('should clear the tree', () => {
@@ -350,6 +685,56 @@ describe('BinaryTree', () => {
350
685
  null
351
686
  ]);
352
687
  });
688
+
689
+ it('should keyValueOrEntryOrRawElementToNode', () => {
690
+ const tree = new BinaryTree<number>();
691
+ const node0 = tree.keyValueOrEntryOrRawElementToNode(0);
692
+ expect(node0).toEqual({
693
+ _left: undefined,
694
+ _right: undefined,
695
+ key: 0,
696
+ parent: undefined,
697
+ value: undefined
698
+ });
699
+
700
+ const nodeUndefined = tree.keyValueOrEntryOrRawElementToNode(undefined);
701
+ expect(nodeUndefined).toBe(undefined);
702
+
703
+ const nodeNull = tree.keyValueOrEntryOrRawElementToNode(null);
704
+ expect(nodeNull).toBe(null);
705
+
706
+ const nodeWithSeparateValue = tree.keyValueOrEntryOrRawElementToNode(7, 77);
707
+ expect(nodeWithSeparateValue?.value).toBe(77);
708
+
709
+ expect(tree.keyValueOrEntryOrRawElementToNode([undefined, 2])).toBe(undefined);
710
+
711
+ expect(tree.keyValueOrEntryOrRawElementToNode(Symbol('test') as unknown as number)).toBe(undefined);
712
+
713
+ const bTree = new BinaryTree<number, number, { obj: { id: number } }>([], {
714
+ toEntryFn: (ele: { obj: { id: number } }) => [Symbol('test') as unknown as number, ele.obj.id]
715
+ });
716
+ expect(bTree.keyValueOrEntryOrRawElementToNode({ obj: { id: 1 } })).toBe(undefined);
717
+ });
718
+ });
719
+
720
+ describe('BinaryTree ensureNode', () => {
721
+ it('should ensureNode with toEntryFn', () => {
722
+ const tree = new BinaryTree<
723
+ number,
724
+ string,
725
+ {
726
+ id: number;
727
+ name: string;
728
+ }
729
+ >([], { toEntryFn: rawElement => [rawElement.id, rawElement.name] });
730
+ tree.add({ id: 1, name: 'Pablo' });
731
+ const node = tree.getNode(1);
732
+ expect(tree.ensureNode({ id: 1, name: 'Pablo' })).toBe(node);
733
+ expect(tree.ensureNode([1, 'Pablo'])).toBe(node);
734
+ expect(tree.ensureNode([null, 'Pablo'])).toBe(null);
735
+ expect(tree.ensureNode([undefined, 'Pablo'])).toBe(undefined);
736
+ expect(tree.ensureNode(Symbol('test') as unknown as number)).toBe(undefined);
737
+ });
353
738
  });
354
739
 
355
740
  describe('BinaryTree Morris Traversal', () => {
@@ -404,25 +789,35 @@ describe('BinaryTree Morris Traversal', () => {
404
789
  });
405
790
 
406
791
  describe('BinaryTree toEntryFn', () => {
407
- it('should toEntryFn 1', () => {
408
- const tree = new BinaryTree<number, number, { obj: { id: number } }>([], {
792
+ it('should toEntryFn throw', () => {
793
+ expect(() => {
794
+ new BinaryTree<number, number, { obj: { id: number } }>([], {
795
+ toEntryFn: `ele => [ele.obj.id, ele.obj.id]` as unknown as (rawElement: {
796
+ obj: { id: number };
797
+ }) => BTNEntry<number, number>
798
+ });
799
+ }).toThrow('toEntryFn must be a function type');
800
+ });
801
+
802
+ it('should toEntryFn with add', () => {
803
+ const binTree = new BinaryTree<number, number, { obj: { id: number } }>([], {
409
804
  toEntryFn: ele => [ele.obj.id, ele.obj.id]
410
805
  });
411
- tree.add({ obj: { id: 1 } });
412
- tree.add({ obj: { id: 2 } });
413
- tree.add({ obj: { id: 3 } });
414
- tree.add({ obj: { id: 4 } });
415
- tree.add({ obj: { id: 5 } });
806
+ binTree.add({ obj: { id: 1 } });
807
+ binTree.add({ obj: { id: 2 } });
808
+ binTree.add({ obj: { id: 3 } });
809
+ binTree.add({ obj: { id: 4 } });
810
+ binTree.add({ obj: { id: 5 } });
416
811
 
417
812
  const expected = [4, 2, 5, 1, 3];
418
813
 
419
- expect(tree.morris(node => node.key, 'IN')).toEqual(expected);
420
- expect(tree.dfs(node => node.key, 'IN')).toEqual(expected);
421
- expect(tree.dfs(node => node.key, 'IN', tree.root, 'RECURSIVE')).toEqual(expected);
814
+ expect(binTree.morris(node => node.key, 'IN')).toEqual(expected);
815
+ expect(binTree.dfs(node => node.key, 'IN')).toEqual(expected);
816
+ expect(binTree.dfs(node => node.key, 'IN', binTree.root, 'RECURSIVE')).toEqual(expected);
422
817
  });
423
818
 
424
- it('should toEntryFn 2', () => {
425
- const tree = new BinaryTree<number, number, { obj: { id: number } }>(
819
+ it('should toEntryFn with initial', () => {
820
+ const binTree = new BinaryTree<number, number, { obj: { id: number } }>(
426
821
  [{ obj: { id: 1 } }, { obj: { id: 2 } }, { obj: { id: 3 } }, { obj: { id: 4 } }, { obj: { id: 5 } }],
427
822
  {
428
823
  toEntryFn: ele => [ele.obj.id, ele.obj.id]
@@ -431,31 +826,24 @@ describe('BinaryTree toEntryFn', () => {
431
826
 
432
827
  const expected = [4, 2, 5, 1, 3];
433
828
 
434
- expect(tree.morris(node => node.key, 'IN')).toEqual(expected);
435
- expect(tree.dfs(node => node.key, 'IN')).toEqual(expected);
436
- expect(tree.dfs(node => node.key, 'IN', tree.root, 'RECURSIVE')).toEqual(expected);
829
+ expect(binTree.morris(node => node.key, 'IN')).toEqual(expected);
830
+ expect(binTree.dfs(node => node.key, 'IN')).toEqual(expected);
831
+ expect(binTree.dfs(node => node.key, 'IN', binTree.root, 'RECURSIVE')).toEqual(expected);
437
832
  });
438
833
 
439
- it('should toEntryFn 3', () => {
440
- const tree = new BinaryTree<{ obj: { id: number } }, number>([
441
- { obj: { id: 1 } },
442
- { obj: { id: 2 } },
443
- { obj: { id: 3 } },
444
- { obj: { id: 4 } },
445
- { obj: { id: 5 } }
446
- ]);
447
-
448
- const expected = [
449
- { obj: { id: 4 } },
450
- { obj: { id: 2 } },
451
- { obj: { id: 5 } },
452
- { obj: { id: 1 } },
453
- { obj: { id: 3 } }
834
+ it('should no toEntryFn', () => {
835
+ const data = [
836
+ { obj: { id: 4 }, valueOf: () => 4 },
837
+ { obj: { id: 2 }, valueOf: () => 2 },
838
+ { obj: { id: 5 }, valueOf: () => 5 },
839
+ { obj: { id: 1 }, valueOf: () => 1 },
840
+ { obj: { id: 3 }, valueOf: () => 3 }
454
841
  ];
842
+ const tree = new BinaryTree<{ obj: { id: number }; valueOf: () => number }, number>(data);
455
843
 
456
- expect(tree.morris(node => node.key, 'IN')).toEqual(expected);
457
- expect(tree.dfs(node => node.key, 'IN')).toEqual(expected);
458
- expect(tree.dfs(node => node.key, 'IN', tree.root, 'RECURSIVE')).toEqual(expected);
844
+ expect(tree.morris(node => node.key, 'IN')).toEqual(data.sort((a, b) => a.obj.id - b.obj.id));
845
+ expect(tree.dfs(node => node.key, 'IN')).toEqual(data);
846
+ expect(tree.dfs(node => node.key, 'IN', tree.root, 'RECURSIVE')).toEqual(data);
459
847
  });
460
848
  });
461
849
 
@@ -706,19 +1094,33 @@ describe('BinaryTree', () => {
706
1094
  });
707
1095
 
708
1096
  it('should get nodes by a custom callback', () => {
709
- tree.add([5, 'A']);
710
- tree.add([3, 'B']);
711
- tree.add([7, 'C']);
1097
+ tree.add([5, 'E']);
1098
+ tree.add([4, 'D']);
1099
+ tree.add([3, 'C']);
1100
+ tree.add([7, 'G']);
1101
+ tree.add([null, 'null']);
1102
+ tree.add([1, 'A']);
1103
+ tree.add([6, 'F']);
1104
+ tree.add([null, 'null']);
1105
+ tree.add([2, 'B']);
1106
+ tree.add([null, 'null']);
712
1107
 
713
1108
  const nodes = tree.getNodes('B', node => node.value);
714
1109
 
715
1110
  expect(nodes.length).toBe(1);
716
- expect(nodes[0].key).toBe(3);
1111
+ expect(nodes[0].key).toBe(2);
717
1112
 
718
1113
  const nodesRec = tree.getNodes('B', node => node.value, false, tree.root, 'RECURSIVE');
719
1114
 
720
1115
  expect(nodesRec.length).toBe(1);
721
- expect(nodesRec[0].key).toBe(3);
1116
+ expect(nodesRec[0].key).toBe(2);
1117
+
1118
+ const nodesItr = tree.getNodes('B', node => node.value, false, tree.root, 'ITERATIVE');
1119
+
1120
+ expect(nodesItr.length).toBe(1);
1121
+ expect(nodesItr[0].key).toBe(2);
1122
+
1123
+ expect(nodesItr).toEqual(nodesRec);
722
1124
  });
723
1125
 
724
1126
  it('should perform Morris traversal', () => {
@@ -767,12 +1169,12 @@ describe('BinaryTree iterative methods test', () => {
767
1169
  binaryTree.add([3, 'c']);
768
1170
  });
769
1171
 
770
- test('The node obtained by get Node should match the node type', () => {
1172
+ it('The node obtained by get Node should match the node type', () => {
771
1173
  const node3 = binaryTree.getNode(3);
772
1174
  expect(node3).toBeInstanceOf(BinaryTreeNode);
773
1175
  });
774
1176
 
775
- test('forEach should iterate over all elements', () => {
1177
+ it('forEach should iterate over all elements', () => {
776
1178
  const mockCallback = jest.fn();
777
1179
  binaryTree.forEach((value, key) => {
778
1180
  mockCallback(value, key);
@@ -784,7 +1186,7 @@ describe('BinaryTree iterative methods test', () => {
784
1186
  expect(mockCallback.mock.calls[2]).toEqual(['c', 3]);
785
1187
  });
786
1188
 
787
- test('filter should return a new tree with filtered elements', () => {
1189
+ it('filter should return a new tree with filtered elements', () => {
788
1190
  const filteredTree = binaryTree.filter((value, key) => key > 1);
789
1191
  expect(filteredTree.size).toBe(2);
790
1192
  expect([...filteredTree]).toEqual([
@@ -793,7 +1195,7 @@ describe('BinaryTree iterative methods test', () => {
793
1195
  ]);
794
1196
  });
795
1197
 
796
- test('map should return a new tree with modified elements', () => {
1198
+ it('map should return a new tree with modified elements', () => {
797
1199
  const mappedTree = binaryTree.map((value, key) => (key * 2).toString());
798
1200
  expect(mappedTree.size).toBe(3);
799
1201
  expect([...mappedTree]).toEqual([
@@ -803,12 +1205,12 @@ describe('BinaryTree iterative methods test', () => {
803
1205
  ]);
804
1206
  });
805
1207
 
806
- test('reduce should accumulate values', () => {
1208
+ it('reduce should accumulate values', () => {
807
1209
  const sum = binaryTree.reduce((acc, currentValue, currentKey) => acc + currentKey, 0);
808
1210
  expect(sum).toBe(6);
809
1211
  });
810
1212
 
811
- test('[Symbol.iterator] should provide an iterator', () => {
1213
+ it('[Symbol.iterator] should provide an iterator', () => {
812
1214
  const entries = [];
813
1215
  for (const entry of binaryTree) {
814
1216
  entries.push(entry);
@@ -822,23 +1224,28 @@ describe('BinaryTree iterative methods test', () => {
822
1224
  ]);
823
1225
  });
824
1226
 
825
- test('should clone work well', () => {
1227
+ it('should clone work well', () => {
826
1228
  const cloned = binaryTree.clone();
827
1229
  expect(cloned.root?.left?.key).toBe(2);
828
1230
  expect(cloned.root?.right?.value).toBe('c');
829
1231
  });
830
1232
 
831
- test('should keys', () => {
1233
+ it('should keys', () => {
832
1234
  const keys = binaryTree.keys();
833
1235
  expect([...keys]).toEqual([2, 1, 3]);
834
1236
  });
835
1237
 
836
- test('should values', () => {
1238
+ it('should values', () => {
837
1239
  const values = binaryTree.values();
838
1240
  expect([...values]).toEqual(['b', 'a', 'c']);
839
1241
  });
840
1242
 
841
- test('should iterative method return undefined when the node is null', () => {
1243
+ it('should leaves', () => {
1244
+ const leaves = binaryTree.leaves();
1245
+ expect(leaves).toEqual([2, 3]);
1246
+ });
1247
+
1248
+ it('should iterative method return undefined when the node is null', () => {
842
1249
  const tree = new BinaryTree();
843
1250
  tree.addMany([-10, -10, -10, 9, 9, 20, null, null, 15, 7, 8, null, 2, null, 6, null, null, 8, 8, 8]);
844
1251
  const bfsResult = tree.bfs(undefined, undefined, undefined, true);