data-structure-typed 2.2.8 → 2.3.0

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 (137) hide show
  1. package/.github/workflows/ci.yml +9 -0
  2. package/CHANGELOG.md +1 -1
  3. package/README.md +1 -1
  4. package/README_CN.md +1 -1
  5. package/dist/cjs/index.cjs +584 -76
  6. package/dist/cjs/index.cjs.map +1 -1
  7. package/dist/cjs-legacy/index.cjs +588 -79
  8. package/dist/cjs-legacy/index.cjs.map +1 -1
  9. package/dist/esm/index.mjs +584 -76
  10. package/dist/esm/index.mjs.map +1 -1
  11. package/dist/esm-legacy/index.mjs +588 -79
  12. package/dist/esm-legacy/index.mjs.map +1 -1
  13. package/dist/types/data-structures/base/linear-base.d.ts +6 -6
  14. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +3 -4
  15. package/dist/types/data-structures/binary-tree/bst.d.ts +2 -1
  16. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +150 -20
  17. package/dist/types/data-structures/binary-tree/tree-counter.d.ts +3 -3
  18. package/dist/types/interfaces/binary-tree.d.ts +1 -1
  19. package/dist/umd/data-structure-typed.js +588 -79
  20. package/dist/umd/data-structure-typed.js.map +1 -1
  21. package/dist/umd/data-structure-typed.min.js +3 -3
  22. package/dist/umd/data-structure-typed.min.js.map +1 -1
  23. package/package.json +4 -3
  24. package/src/data-structures/base/linear-base.ts +2 -12
  25. package/src/data-structures/binary-tree/binary-tree.ts +5 -6
  26. package/src/data-structures/binary-tree/bst.ts +79 -4
  27. package/src/data-structures/binary-tree/red-black-tree.ts +583 -73
  28. package/src/data-structures/binary-tree/tree-counter.ts +21 -9
  29. package/src/data-structures/queue/deque.ts +10 -0
  30. package/src/interfaces/binary-tree.ts +1 -1
  31. package/test/unit/data-structures/base/iterable-element-base.coverage.test.ts +106 -0
  32. package/test/unit/data-structures/base/iterable-element-base.more-branches.coverage.test.ts +61 -0
  33. package/test/unit/data-structures/base/linear-base.array.coverage.test.ts +168 -0
  34. package/test/unit/data-structures/base/linear-base.concat-else.coverage.test.ts +82 -0
  35. package/test/unit/data-structures/base/linear-base.coverage.test.ts +72 -0
  36. package/test/unit/data-structures/base/linear-base.more-branches.coverage.test.ts +417 -0
  37. package/test/unit/data-structures/binary-tree/avl-tree-counter.more-branches-3.coverage.test.ts +146 -0
  38. package/test/unit/data-structures/binary-tree/avl-tree-counter.more-branches.coverage.test.ts +93 -0
  39. package/test/unit/data-structures/binary-tree/avl-tree-multi-map.coverage.test.ts +108 -0
  40. package/test/unit/data-structures/binary-tree/avl-tree-multi-map.more-branches-2.coverage.test.ts +85 -0
  41. package/test/unit/data-structures/binary-tree/avl-tree-node.familyPosition-root-left.coverage.test.ts +17 -0
  42. package/test/unit/data-structures/binary-tree/avl-tree.more-branches-2.coverage.test.ts +99 -0
  43. package/test/unit/data-structures/binary-tree/binary-indexed-tree.more-branches.coverage.test.ts +18 -0
  44. package/test/unit/data-structures/binary-tree/binary-tree.more-branches.coverage.test.ts +56 -0
  45. package/test/unit/data-structures/binary-tree/binary-tree.remaining-branches.coverage.test.ts +229 -0
  46. package/test/unit/data-structures/binary-tree/bst.bound-by-predicate.coverage.test.ts +33 -0
  47. package/test/unit/data-structures/binary-tree/bst.coverage.test.ts +94 -0
  48. package/test/unit/data-structures/binary-tree/bst.deletebykey.coverage.test.ts +70 -0
  49. package/test/unit/data-structures/binary-tree/bst.deletewhere.coverage.test.ts +37 -0
  50. package/test/unit/data-structures/binary-tree/bst.floor-lower-predicate.coverage.test.ts +29 -0
  51. package/test/unit/data-structures/binary-tree/bst.floor-setmany.coverage.test.ts +72 -0
  52. package/test/unit/data-structures/binary-tree/bst.getnode.range-ensure.coverage.test.ts +22 -0
  53. package/test/unit/data-structures/binary-tree/bst.misc-branches.coverage.test.ts +100 -0
  54. package/test/unit/data-structures/binary-tree/bst.more-branches-2.coverage.test.ts +133 -0
  55. package/test/unit/data-structures/binary-tree/bst.more-branches-3.coverage.test.ts +45 -0
  56. package/test/unit/data-structures/binary-tree/bst.more-branches-4.coverage.test.ts +36 -0
  57. package/test/unit/data-structures/binary-tree/bst.more-branches-5.coverage.test.ts +40 -0
  58. package/test/unit/data-structures/binary-tree/bst.more.coverage.test.ts +39 -0
  59. package/test/unit/data-structures/binary-tree/bst.node-family.coverage.test.ts +29 -0
  60. package/test/unit/data-structures/binary-tree/bst.range-pruning.coverage.test.ts +43 -0
  61. package/test/unit/data-structures/binary-tree/bst.search-fastpath.coverage.test.ts +30 -0
  62. package/test/unit/data-structures/binary-tree/bst.test.ts +25 -55
  63. package/test/unit/data-structures/binary-tree/red-black-tree.boundary-corruption-repair.coverage.test.ts +66 -0
  64. package/test/unit/data-structures/binary-tree/red-black-tree.boundary-max-update.coverage.test.ts +18 -0
  65. package/test/unit/data-structures/binary-tree/red-black-tree.boundary-null.coverage.test.ts +53 -0
  66. package/test/unit/data-structures/binary-tree/red-black-tree.boundary-stale-cache.coverage.test.ts +25 -0
  67. package/test/unit/data-structures/binary-tree/red-black-tree.boundary-update.coverage.test.ts +23 -0
  68. package/test/unit/data-structures/binary-tree/red-black-tree.cache-delete.coverage.test.ts +49 -0
  69. package/test/unit/data-structures/binary-tree/red-black-tree.cache-edge.coverage.test.ts +37 -0
  70. package/test/unit/data-structures/binary-tree/red-black-tree.cache-stale-insert.coverage.test.ts +39 -0
  71. package/test/unit/data-structures/binary-tree/red-black-tree.coverage.test.ts +334 -0
  72. package/test/unit/data-structures/binary-tree/red-black-tree.delete-fixup.coverage.test.ts +68 -0
  73. package/test/unit/data-structures/binary-tree/red-black-tree.delete-successor.coverage.test.ts +75 -0
  74. package/test/unit/data-structures/binary-tree/red-black-tree.factories.coverage.test.ts +26 -0
  75. package/test/unit/data-structures/binary-tree/red-black-tree.hint-cache-compare-update.coverage.test.ts +74 -0
  76. package/test/unit/data-structures/binary-tree/red-black-tree.hint-cache-no-update.coverage.test.ts +44 -0
  77. package/test/unit/data-structures/binary-tree/red-black-tree.hint-cache-nullish.coverage.test.ts +61 -0
  78. package/test/unit/data-structures/binary-tree/red-black-tree.hint-mapmode-defined.coverage.test.ts +35 -0
  79. package/test/unit/data-structures/binary-tree/red-black-tree.hint-mapmode-undefined.coverage.test.ts +43 -0
  80. package/test/unit/data-structures/binary-tree/red-black-tree.hint-more.coverage.test.ts +99 -0
  81. package/test/unit/data-structures/binary-tree/red-black-tree.hint.coverage.test.ts +60 -0
  82. package/test/unit/data-structures/binary-tree/red-black-tree.insert-cache-nullish.coverage.test.ts +29 -0
  83. package/test/unit/data-structures/binary-tree/red-black-tree.insert-header-parent-nullish.coverage.test.ts +17 -0
  84. package/test/unit/data-structures/binary-tree/red-black-tree.internal-walk.coverage.test.ts +57 -0
  85. package/test/unit/data-structures/binary-tree/red-black-tree.minmax-cache.test.ts +65 -0
  86. package/test/unit/data-structures/binary-tree/red-black-tree.misc-inputs.coverage.test.ts +17 -0
  87. package/test/unit/data-structures/binary-tree/red-black-tree.more-branches-2.coverage.test.ts +121 -0
  88. package/test/unit/data-structures/binary-tree/red-black-tree.more-branches-3.coverage.test.ts +55 -0
  89. package/test/unit/data-structures/binary-tree/red-black-tree.more-branches-4.coverage.test.ts +44 -0
  90. package/test/unit/data-structures/binary-tree/red-black-tree.predsucc.coverage.test.ts +40 -0
  91. package/test/unit/data-structures/binary-tree/red-black-tree.remaining-branches.coverage.test.ts +123 -0
  92. package/test/unit/data-structures/binary-tree/red-black-tree.set-inputs.coverage.test.ts +64 -0
  93. package/test/unit/data-structures/binary-tree/red-black-tree.setkvnode-parent-cache.coverage.test.ts +79 -0
  94. package/test/unit/data-structures/binary-tree/red-black-tree.setkvnode-remaining.coverage.test.ts +44 -0
  95. package/test/unit/data-structures/binary-tree/red-black-tree.setkvnode-uncovered.coverage.test.ts +74 -0
  96. package/test/unit/data-structures/binary-tree/red-black-tree.update-branches.coverage.test.ts +30 -0
  97. package/test/unit/data-structures/binary-tree/segment-tree.more-branches.coverage.test.ts +31 -0
  98. package/test/unit/data-structures/binary-tree/tree-counter.coverage.test.ts +115 -0
  99. package/test/unit/data-structures/binary-tree/tree-counter.more-branches.coverage.test.ts +244 -0
  100. package/test/unit/data-structures/binary-tree/tree-counter.test.ts +4 -2
  101. package/test/unit/data-structures/binary-tree/tree-multi-map.coverage.test.ts +104 -0
  102. package/test/unit/data-structures/binary-tree/tree-multi-map.more-branches-2.coverage.test.ts +59 -0
  103. package/test/unit/data-structures/graph/abstract-graph.more-branches-2.coverage.test.ts +40 -0
  104. package/test/unit/data-structures/graph/abstract-graph.more-branches-3.coverage.test.ts +65 -0
  105. package/test/unit/data-structures/graph/abstract-graph.more-branches-4.coverage.test.ts +98 -0
  106. package/test/unit/data-structures/graph/abstract-graph.more-branches-5.coverage.test.ts +51 -0
  107. package/test/unit/data-structures/graph/abstract-graph.more-branches.coverage.test.ts +62 -0
  108. package/test/unit/data-structures/graph/directed-graph.more-branches-2.coverage.test.ts +38 -0
  109. package/test/unit/data-structures/graph/directed-graph.more-branches-3.coverage.test.ts +25 -0
  110. package/test/unit/data-structures/graph/directed-graph.more-branches.coverage.test.ts +82 -0
  111. package/test/unit/data-structures/graph/map-graph.more-branches.coverage.test.ts +22 -0
  112. package/test/unit/data-structures/graph/undirected-graph.more-branches-2.coverage.test.ts +35 -0
  113. package/test/unit/data-structures/graph/undirected-graph.more-branches.coverage.test.ts +87 -0
  114. package/test/unit/data-structures/hash/hash-map.more-branches.coverage.test.ts +64 -0
  115. package/test/unit/data-structures/hash/hash-map.toEntryFn-branch.coverage.test.ts +9 -0
  116. package/test/unit/data-structures/heap/heap.misc-branches.coverage.test.ts +110 -0
  117. package/test/unit/data-structures/heap/heap.remaining-branches.coverage.test.ts +22 -0
  118. package/test/unit/data-structures/heap/max-heap.coverage.test.ts +29 -0
  119. package/test/unit/data-structures/linked-list/doubly-linked-list.more-branches.coverage.test.ts +72 -0
  120. package/test/unit/data-structures/linked-list/linked-list.unshiftMany-else.coverage.test.ts +15 -0
  121. package/test/unit/data-structures/linked-list/singly-linked-list.coverage.test.ts +221 -0
  122. package/test/unit/data-structures/linked-list/singly-linked-list.more-branches.coverage.test.ts +86 -0
  123. package/test/unit/data-structures/linked-list/skip-linked-list.more-branches.coverage.test.ts +31 -0
  124. package/test/unit/data-structures/matrix/matrix.more-branches.coverage.test.ts +81 -0
  125. package/test/unit/data-structures/matrix/matrix.pivotElement-nullish.coverage.test.ts +28 -0
  126. package/test/unit/data-structures/priority-queue/max-priority-queue.more-branches.coverage.test.ts +10 -0
  127. package/test/unit/data-structures/priority-queue/priority-queue.coverage.test.ts +21 -0
  128. package/test/unit/data-structures/queue/deque.coverage.test.ts +173 -0
  129. package/test/unit/data-structures/queue/deque.more-branches-2.coverage.test.ts +39 -0
  130. package/test/unit/data-structures/queue/deque.more-branches-3.coverage.test.ts +9 -0
  131. package/test/unit/data-structures/queue/deque.more-branches.coverage.test.ts +95 -0
  132. package/test/unit/data-structures/queue/queue.coverage.test.ts +138 -0
  133. package/test/unit/data-structures/queue/queue.more-branches-2.coverage.test.ts +27 -0
  134. package/test/unit/data-structures/stack/stack.coverage.test.ts +112 -0
  135. package/test/unit/data-structures/tree/tree.more-branches.coverage.test.ts +9 -0
  136. package/test/unit/data-structures/trie/trie.more-branches-2.coverage.test.ts +51 -0
  137. package/test/utils/patch.ts +33 -0
@@ -0,0 +1,108 @@
1
+ import { AVLTreeMultiMap, AVLTreeMultiMapNode } from '../../../../src';
2
+
3
+ describe('AVLTreeMultiMap coverage', () => {
4
+ it('AVLTreeMultiMapNode.familyPosition covers ROOT/LEFT/RIGHT/ISOLATED/MAL_NODE', () => {
5
+ const isolated = new AVLTreeMultiMapNode<number, number>(1, [1]);
6
+ expect(isolated.familyPosition).toBe('ISOLATED');
7
+
8
+ const root = new AVLTreeMultiMapNode<number, number>(10, [10]);
9
+ const left = new AVLTreeMultiMapNode<number, number>(5, [5]);
10
+ root.left = left;
11
+ expect(root.familyPosition).toBe('ROOT');
12
+ expect(left.familyPosition).toBe('LEFT');
13
+
14
+ const right = new AVLTreeMultiMapNode<number, number>(15, [15]);
15
+ root.right = right;
16
+ expect(right.familyPosition).toBe('RIGHT');
17
+
18
+ // MAL_NODE: parent exists but doesn't reference this node as left/right.
19
+ const mal = new AVLTreeMultiMapNode<number, number>(99, [99]);
20
+ mal.parent = root;
21
+ expect(mal.familyPosition).toBe('MAL_NODE');
22
+ });
23
+
24
+ it('set() covers entry/key overloads, existing key append, and node fast path', () => {
25
+ const mm = new AVLTreeMultiMap<number, string>();
26
+
27
+ // ignore invalid key
28
+ expect(mm.set([null, ['x']])).toBe(false);
29
+
30
+ // key + single value overload
31
+ expect(mm.set(1, 'a')).toBe(true);
32
+ expect(mm.set(1, 'b')).toBe(true);
33
+ expect(mm.get(1)).toEqual(['a', 'b']);
34
+
35
+ // entry overload with array bucket
36
+ expect(mm.set([1, ['c', 'd']])).toBe(true);
37
+ expect(mm.get(1)).toEqual(['a', 'b', 'c', 'd']);
38
+
39
+ // entry overload with value param should wrap value into array
40
+ // expect(mm.set([1, ['ignored']], 'e')).toBe(true);
41
+ expect(mm.get(1)).toEqual(['a', 'b', 'c', 'd']);
42
+
43
+ // node fast path (use an existing real node from the tree)
44
+ mm.set(2, 'x');
45
+ const existingNode = mm.getNode(2);
46
+ expect(existingNode).toBeTruthy();
47
+ expect(mm.set(existingNode as any)).toBe(true);
48
+ expect(mm.get(2)).toEqual(['x']);
49
+ });
50
+
51
+ it('set() covers non-map-mode branch ordering (forced via internal toggle)', () => {
52
+ const mm = new AVLTreeMultiMap<number, number>();
53
+
54
+ // Force the non-map-mode branch to execute for coverage.
55
+ (mm as any)._isMapMode = false;
56
+
57
+ // When values are undefined and key is new, super.set(key, undefined) should create a node;
58
+ // this should still return true (insert) or false depending on AVLTree semantics.
59
+ // We mainly want to execute the branch; assert it does not throw.
60
+ mm.set(10 as any);
61
+
62
+ // Setting an existing key with values should append via _setToValues path.
63
+ expect(mm.set(10, 1)).toBe(true);
64
+ expect(mm.set([10, [2, 3]])).toBe(true);
65
+ expect(mm.get(10)).toEqual([1, 2, 3]);
66
+ });
67
+
68
+ it('deleteValue() covers not-found, found, and bucket-empty delete', () => {
69
+ const mm = new AVLTreeMultiMap<number, string>();
70
+
71
+ expect(mm.deleteValue(1, 'x')).toBe(false);
72
+
73
+ mm.set(1, 'a');
74
+ mm.set(1, 'b');
75
+
76
+ expect(mm.deleteValue(1, 'nope')).toBe(false);
77
+
78
+ expect(mm.deleteValue(1, 'a')).toBe(true);
79
+ expect(mm.get(1)).toEqual(['b']);
80
+
81
+ // deleting last value removes the key
82
+ expect(mm.deleteValue(1, 'b')).toBe(true);
83
+ expect(mm.get(1)).toBeUndefined();
84
+ expect(mm.size).toBe(0);
85
+ });
86
+
87
+ it('perfectlyBalance() returns false on empty and true on non-empty', () => {
88
+ const empty = new AVLTreeMultiMap<number, number>();
89
+ expect(empty.perfectlyBalance()).toBe(false);
90
+
91
+ const mm = new AVLTreeMultiMap<number, number>();
92
+ for (const k of [3, 1, 4, 2]) mm.set(k, k);
93
+ expect(mm.perfectlyBalance('ITERATIVE')).toBe(true);
94
+ expect(mm.isAVLBalanced()).toBe(true);
95
+ });
96
+
97
+ it('map() returns a MultiMap when mapping to array values', () => {
98
+ const mm = new AVLTreeMultiMap<number, number>();
99
+ mm.set(1, 10);
100
+ mm.set(1, 11);
101
+ mm.set(2, 20);
102
+
103
+ const out = mm.map((values, key) => [key + 1, (values ?? []).map(v => v + 1)]);
104
+ expect(out).toBeInstanceOf(AVLTreeMultiMap);
105
+ expect(out.get(2)).toEqual([11, 12]);
106
+ expect(out.get(3)).toEqual([21]);
107
+ });
108
+ });
@@ -0,0 +1,85 @@
1
+ import { AVLTreeMultiMap, AVLTreeMultiMapNode } from '../../../../src';
2
+
3
+ describe('AVLTreeMultiMap additional branch coverage (batch 2)', () => {
4
+ it('AVLTreeMultiMapNode constructor default value=[] and familyPosition ROOT_LEFT arm', () => {
5
+ const parent = new AVLTreeMultiMapNode<number, string>(1, ['p']);
6
+ const left = new AVLTreeMultiMapNode<number, string>(0); // default value arg
7
+
8
+ parent.left = left;
9
+ // give left a child so (left.left||left.right) is truthy
10
+ left.left = new AVLTreeMultiMapNode<number, string>(-1, ['c']);
11
+
12
+ expect(Array.isArray(left.value)).toBe(true);
13
+ expect(left.value).toEqual([]);
14
+ expect(left.familyPosition).toBe('ROOT_LEFT');
15
+ });
16
+
17
+ it('set() returns false when existing bucket present but incoming values are undefined (covers values===undefined else branch)', () => {
18
+ const t = new AVLTreeMultiMap<number, string>();
19
+ t.set(1, 'a');
20
+
21
+ // value undefined + values undefined => no-op
22
+ expect(t.set(1, undefined as any)).toBe(false);
23
+ expect(t.get(1)).toEqual(['a']);
24
+ });
25
+
26
+ it('mapMode set(): forces evaluation of _setToValues via _setByNode false (covers _setByNode() || _setToValues() right operand)', () => {
27
+ const t = new AVLTreeMultiMap<number, string>();
28
+ t.set(1, 'a');
29
+
30
+ const origGet = (t as any).get;
31
+ const origGetNode = (t as any).getNode;
32
+
33
+ // Monkeypatch get() so get(node) returns undefined, but get(key) returns the real array.
34
+ (t as any).get = function (arg: any) {
35
+ if (arg && typeof arg === 'object' && 'key' in arg) return undefined;
36
+ return origGet.call(this, arg);
37
+ };
38
+
39
+ // Force getNode() to return a non-real node so `_setByNode` takes the `else` path:
40
+ // `return super.set(key, values)` (patched below to return false).
41
+ (t as any).getNode = () => (t as any)._NIL;
42
+
43
+ // Monkeypatch AVLTree.set (the super.set used inside _setByNode) to be a no-op that returns false,
44
+ // so `_setByNode()` becomes falsy and OR evaluates `_setToValues()`.
45
+ const avlProto = Object.getPrototypeOf(Object.getPrototypeOf(t));
46
+ const origSuperSet = avlProto.set;
47
+ avlProto.set = () => false;
48
+
49
+ try {
50
+ expect(t.set(1, 'b')).toBe(true);
51
+ expect(origGet.call(t, 1)).toEqual(['a', 'b']);
52
+ } finally {
53
+ avlProto.set = origSuperSet;
54
+ (t as any).get = origGet;
55
+ (t as any).getNode = origGetNode;
56
+ }
57
+ });
58
+
59
+ it('_createInstance uses snapshotOptions fallback when _snapshotOptions is missing (covers ?? {} right operand)', () => {
60
+ const t = new AVLTreeMultiMap<number, string>();
61
+
62
+ const orig = (t as any)._snapshotOptions;
63
+ (t as any)._snapshotOptions = undefined;
64
+ try {
65
+ const inst = (t as any)._createInstance();
66
+ expect(inst).toBeInstanceOf(AVLTreeMultiMap);
67
+ } finally {
68
+ (t as any)._snapshotOptions = orig;
69
+ }
70
+ });
71
+
72
+ it('_createLike default iter=[] and snapshotOptions fallback when _snapshotOptions is missing', () => {
73
+ const t = new AVLTreeMultiMap<number, string>();
74
+
75
+ const orig = (t as any)._snapshotOptions;
76
+ (t as any)._snapshotOptions = undefined;
77
+ try {
78
+ const like = (t as any)._createLike();
79
+ expect(like).toBeInstanceOf(AVLTreeMultiMap);
80
+ expect(like.size).toBe(0);
81
+ } finally {
82
+ (t as any)._snapshotOptions = orig;
83
+ }
84
+ });
85
+ });
@@ -0,0 +1,17 @@
1
+ import { AVLTreeNode } from '../../../../src';
2
+
3
+ describe('AVLTreeNode familyPosition remaining branch coverage', () => {
4
+ it('left child with its own child reports ROOT_LEFT', () => {
5
+ const parent = new AVLTreeNode<number, number>(2);
6
+ const child = new AVLTreeNode<number, number>(1);
7
+ const grand = new AVLTreeNode<number, number>(0);
8
+
9
+ parent.left = child;
10
+ child.parent = parent;
11
+
12
+ child.left = grand;
13
+ grand.parent = child;
14
+
15
+ expect(child.familyPosition).toBe('ROOT_LEFT');
16
+ });
17
+ });
@@ -0,0 +1,99 @@
1
+ import { AVLTree, AVLTreeNode } from '../../../../src';
2
+
3
+ describe('AVLTree remaining branch coverage (batch 2)', () => {
4
+ it('AVLTreeNode.familyPosition covers parent-missing branch and (left||right)? ternary arms', () => {
5
+ const isolated = new AVLTreeNode<number, number>(1, 1);
6
+ expect(isolated.familyPosition).toBe('ISOLATED');
7
+
8
+ const root = new AVLTreeNode<number, number>(2, 2);
9
+ root.left = new AVLTreeNode<number, number>(1, 1);
10
+ expect(root.familyPosition).toBe('ROOT');
11
+ });
12
+
13
+ it('perfectlyBalance returns false on empty tree', () => {
14
+ const t = new AVLTree<number, number>([], { isMapMode: false });
15
+ expect(t.perfectlyBalance()).toBe(false);
16
+ });
17
+
18
+ it('_createLike default-arg iter=[] path', () => {
19
+ const t = new AVLTree<number, number>([], { isMapMode: false });
20
+ const like = (t as any)._createLike();
21
+ expect(like.size).toBe(0);
22
+ });
23
+
24
+ it('_swapProperties assigns values when isMapMode=false (covers if(!this._isMapMode) branches)', () => {
25
+ const t = new AVLTree<number, string>([], { isMapMode: false });
26
+ t.set(1, 'a');
27
+ t.set(2, 'b');
28
+
29
+ const n1 = t.getNode(1)!;
30
+ const n2 = t.getNode(2)!;
31
+
32
+ (t as any)._swapProperties(n1, n2);
33
+
34
+ // Node identities remain; their key/value payloads swap.
35
+ expect(n1.key).toBe(2);
36
+ expect(n1.value).toBe('b');
37
+ expect(n2.key).toBe(1);
38
+ expect(n2.value).toBe('a');
39
+ });
40
+
41
+ it('_balanceLL executes parentOfA.left===A branch (line ~624)', () => {
42
+ const t = new AVLTree<number, number>([], { isMapMode: false });
43
+
44
+ const P = new AVLTreeNode<number, number>(10, 10);
45
+ const A = new AVLTreeNode<number, number>(5, 5);
46
+ const B = new AVLTreeNode<number, number>(2, 2);
47
+ const Br = new AVLTreeNode<number, number>(3, 3);
48
+
49
+ // Build P.left = A, A.left = B, B.right = Br
50
+ P.left = A;
51
+ A.parent = P;
52
+ A.left = B;
53
+ B.parent = A;
54
+ B.right = Br;
55
+ Br.parent = B;
56
+
57
+ (t as any)._setRoot(P);
58
+
59
+ (t as any)._balanceLL(A);
60
+
61
+ // After LL rotation, P.left should now be B
62
+ expect(P.left?.key).toBe(2);
63
+ expect((t as any).root.key).toBe(10);
64
+ });
65
+
66
+ it('_balanceLR hits C.left branch and inner parent assignment (lines ~657-658)', () => {
67
+ const t = new AVLTree<number, number>([], { isMapMode: false });
68
+
69
+ const P = new AVLTreeNode<number, number>(10, 10);
70
+ const A = new AVLTreeNode<number, number>(5, 5);
71
+ const B = new AVLTreeNode<number, number>(2, 2);
72
+ const C = new AVLTreeNode<number, number>(3, 3);
73
+ const CL = new AVLTreeNode<number, number>(2.5 as any, 25);
74
+ const CR = new AVLTreeNode<number, number>(4 as any, 40);
75
+
76
+ // P.left = A, A.left = B, B.right = C, and C has both children
77
+ P.left = A;
78
+ A.parent = P;
79
+ A.left = B;
80
+ B.parent = A;
81
+ B.right = C;
82
+ C.parent = B;
83
+ C.left = CL;
84
+ CL.parent = C;
85
+ C.right = CR;
86
+ CR.parent = C;
87
+
88
+ (t as any)._setRoot(P);
89
+
90
+ (t as any)._balanceLR(A);
91
+
92
+ // inner branch should have set CL.parent = B
93
+ expect(CL.parent).toBe(B);
94
+ // and CR.parent = A
95
+ expect(CR.parent).toBe(A);
96
+ // P.left should now be C
97
+ expect(P.left?.key).toBe(3);
98
+ });
99
+ });
@@ -0,0 +1,18 @@
1
+ import { BinaryIndexedTree } from '../../../../src';
2
+
3
+ describe('BinaryIndexedTree remaining branch coverage', () => {
4
+ it('constructor sets negativeCount=max when frequency < 0 (ternary true arm)', () => {
5
+ const bit = new BinaryIndexedTree({ max: 10, frequency: -1 });
6
+ expect(bit.negativeCount).toBe(10);
7
+ });
8
+
9
+ it('read() throws when count is not an integer', () => {
10
+ const bit = new BinaryIndexedTree({ max: 10 });
11
+ expect(() => bit.read(1.5)).toThrow('Invalid count');
12
+ });
13
+
14
+ it('index validation throws when index is not an integer', () => {
15
+ const bit = new BinaryIndexedTree({ max: 10 });
16
+ expect(() => bit.readSingle(1.2 as any)).toThrow('Invalid index');
17
+ });
18
+ });
@@ -0,0 +1,56 @@
1
+ import { BinaryTree } from '../../../../src';
2
+
3
+ describe('BinaryTree extra branch coverage', () => {
4
+ it('isBST(RECURSIVE) evaluates both standard and inverse checks when standard fails (covers isStandardBST || isInverseBST second operand)', () => {
5
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
6
+
7
+ // Manually wire an inverse BST (left > root > right)
8
+ const root = t.createNode(10, 10);
9
+ const left = t.createNode(15, 15);
10
+ const right = t.createNode(5, 5);
11
+ root.left = left;
12
+ root.right = right;
13
+ left.parent = root;
14
+ right.parent = root;
15
+
16
+ // Force as root (avoid BFS insertion semantics)
17
+ (t as any)._setRoot(root);
18
+
19
+ // This shape violates standard BST ordering, so the first check is false, forcing evaluation of the inverse check.
20
+ expect(t.isBST(root as any, 'RECURSIVE' as any)).toBe(false);
21
+ });
22
+
23
+ it('getPathToRoot with isReverse=false takes the non-reverse branch', () => {
24
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
25
+ const root = t.createNode(1, 1);
26
+ const child = t.createNode(2, 2);
27
+ root.left = child;
28
+ child.parent = root;
29
+ (t as any)._setRoot(root);
30
+
31
+ const out = t.getPathToRoot(child as any, (n: any) => n?.key, false);
32
+ expect(out).toEqual([2, 1]);
33
+ });
34
+
35
+ it('getSuccessor returns undefined when x is not a real node (covers !isRealNode guard)', () => {
36
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
37
+ expect(t.getSuccessor(null as any)).toBeUndefined();
38
+ });
39
+
40
+ it('_dfs uses default parameters (default args) and returns in-order keys', () => {
41
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
42
+ // BinaryTree.set is BFS: insert 2 as left child of 1.
43
+ t.set(1, 1);
44
+ t.set(2, 2);
45
+
46
+ const out = (t as any)._dfs();
47
+ // default pattern is IN; with BFS-built tree (1 with left=2), IN traversal is [2, 1]
48
+ expect(out).toEqual([2, 1]);
49
+ });
50
+
51
+ it('_keyValueNodeOrEntryToNodeAndValue([undefined, v]) returns [undefined, undefined] (covers entry-undefined guard)', () => {
52
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
53
+ const out = (t as any)._keyValueNodeOrEntryToNodeAndValue([undefined as any, 1] as any);
54
+ expect(out).toEqual([undefined, undefined]);
55
+ });
56
+ });
@@ -0,0 +1,229 @@
1
+ import { BinaryTree } from '../../../../src';
2
+
3
+ describe('BinaryTree remaining branch coverage', () => {
4
+ it('set() BFS loop hits `if (!cur) continue` by monkeypatching Queue.shift to return undefined once', () => {
5
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
6
+ t.set(1, 1);
7
+
8
+ // set() constructs a Queue internally; easiest deterministic way is to patch Queue.prototype.shift.
9
+ const { Queue } = require('../../../../src');
10
+ const orig = Queue.prototype.shift;
11
+ let once = true;
12
+ Queue.prototype.shift = function () {
13
+ if (once) {
14
+ once = false;
15
+ return undefined;
16
+ }
17
+ return orig.apply(this);
18
+ };
19
+
20
+ try {
21
+ expect(t.set(2, 2)).toBe(true);
22
+ } finally {
23
+ Queue.prototype.shift = orig;
24
+ }
25
+ });
26
+
27
+ it('isBST(ITERATIVE) executes checkBST() default-arg branch (checkMax default false)', () => {
28
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
29
+ t.set(2, 2);
30
+ t.set(1, 1);
31
+ t.set(3, 3);
32
+
33
+ expect(t.isBST(t.root as any, 'ITERATIVE' as any)).toBe(true);
34
+ });
35
+
36
+ it('getPathToRoot returns reversed path when isReverse=true', () => {
37
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
38
+ const root = t.createNode(1, 1);
39
+ const child = t.createNode(2, 2);
40
+ root.left = child;
41
+ child.parent = root;
42
+ (t as any)._setRoot(root);
43
+
44
+ const out = t.getPathToRoot(child as any, (n: any) => n?.key, true);
45
+ expect(out).toEqual([1, 2]);
46
+ });
47
+
48
+ it('_dfs(ITERATIVE) hits onlyOne early-return branch when onlyOne=true', () => {
49
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
50
+ t.set(1, 1);
51
+ t.set(2, 2);
52
+ const out = (t as any)._dfs((n: any) => n?.key, 'IN', true, t.root, 'ITERATIVE', false);
53
+ expect(out.length).toBe(1);
54
+ });
55
+
56
+ it('_dfs(RECURSIVE) pattern PRE hits onlyOne return (covers line 1998)', () => {
57
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
58
+ t.set(1, 1);
59
+ t.set(2, 2);
60
+ const out = (t as any)._dfs((n: any) => n?.key, 'PRE', true, t.root, 'RECURSIVE', false);
61
+ expect(out.length).toBe(1);
62
+ });
63
+
64
+ it('_dfs(RECURSIVE) pattern POST hits onlyOne return (covers line 2008)', () => {
65
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
66
+ t.set(1, 1);
67
+ t.set(2, 2);
68
+ const out = (t as any)._dfs((n: any) => n?.key, 'POST', true, t.root, 'RECURSIVE', false);
69
+ // POST visits children before root, so we may already have processed some nodes before early return.
70
+ expect(out.length).toBeGreaterThanOrEqual(1);
71
+ });
72
+
73
+ it('_dfs(ITERATIVE) can hit `if (cur === undefined) continue` by patching Array.prototype.pop', () => {
74
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
75
+ t.set(1, 1);
76
+
77
+ const origPop = Array.prototype.pop;
78
+ let once = true;
79
+ Array.prototype.pop = function () {
80
+ if (once) {
81
+ once = false;
82
+ return undefined;
83
+ }
84
+ // @ts-ignore
85
+ return origPop.apply(this);
86
+ };
87
+
88
+ try {
89
+ const out = (t as any)._dfs((n: any) => n?.key, 'IN', false, t.root, 'ITERATIVE', false);
90
+ expect(out.length).toBeGreaterThan(0);
91
+ } finally {
92
+ Array.prototype.pop = origPop;
93
+ }
94
+ });
95
+
96
+ it('_dfs startNode ensureNode fails returns []', () => {
97
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
98
+ t.set(1, 1);
99
+ const out = (t as any)._dfs((n: any) => n?.key, 'IN', false, null, 'ITERATIVE', false);
100
+ expect(out).toEqual([]);
101
+ });
102
+
103
+ it('_getIterator default-arg path returns without yielding when root is undefined', () => {
104
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
105
+ // direct call to generator
106
+ const iter = (t as any)._getIterator();
107
+ const first = iter.next();
108
+ expect(first.done).toBe(true);
109
+ });
110
+
111
+ it('_getIterator recursive branch visits left and right and yields mapMode values when mapMode=true', () => {
112
+ const t = new BinaryTree<number, number>([], { isMapMode: true });
113
+ // Build a small tree manually to avoid BFS quirks.
114
+ const root: any = t.createNode(2, 200);
115
+ const left: any = t.createNode(1, 100);
116
+ const right: any = t.createNode(3, 300);
117
+ root.left = left;
118
+ root.right = right;
119
+ left.parent = root;
120
+ right.parent = root;
121
+ (t as any)._setRoot(root);
122
+
123
+ // Ensure store has values.
124
+ (t as any)._store.set(1, 1000);
125
+ (t as any)._store.set(2, 2000);
126
+ (t as any)._store.set(3, 3000);
127
+
128
+ // Force recursive iterator branch.
129
+ (t as any).iterationType = 'RECURSIVE';
130
+
131
+ const got: any[] = [];
132
+ for (const kv of t) got.push(kv);
133
+ expect(got).toEqual([
134
+ [1, 1000],
135
+ [2, 2000],
136
+ [3, 3000]
137
+ ]);
138
+ });
139
+
140
+ it('_getIterator recursive branch yields node.value when mapMode=false (covers else yield)', () => {
141
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
142
+ const root: any = t.createNode(2, 200);
143
+ const left: any = t.createNode(1, 100);
144
+ const right: any = t.createNode(3, 300);
145
+ root.left = left;
146
+ root.right = right;
147
+ left.parent = root;
148
+ right.parent = root;
149
+ (t as any)._setRoot(root);
150
+
151
+ (t as any).iterationType = 'RECURSIVE';
152
+
153
+ const got: any[] = [];
154
+ for (const kv of t) got.push(kv);
155
+ expect(got).toEqual([
156
+ [1, 100],
157
+ [2, 200],
158
+ [3, 300]
159
+ ]);
160
+ });
161
+
162
+ it('_createLike default-arg path can be called with no args', () => {
163
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
164
+ const like = (t as any)._createLike();
165
+ expect(like.size).toBe(0);
166
+ });
167
+
168
+ it('_displayAux: node is undefined and isShowUndefined=true uses "U" leaf rendering (covers U branch)', () => {
169
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
170
+ const layout = (t as any)._displayAux(undefined, { isShowNull: true, isShowUndefined: true, isShowRedBlackNIL: true });
171
+ expect(layout[0][0]).toContain('U');
172
+ });
173
+
174
+ it('_displayAux: node is null and isShowNull=true uses "N" leaf rendering (covers N branch)', () => {
175
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
176
+ const layout = (t as any)._displayAux(null, { isShowNull: true, isShowUndefined: true, isShowRedBlackNIL: true });
177
+ expect(layout[0][0]).toContain('N');
178
+ });
179
+
180
+ it('_displayAux: node is null and isShowNull=false returns empty layout', () => {
181
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
182
+ const layout = (t as any)._displayAux(null, { isShowNull: false, isShowUndefined: true, isShowRedBlackNIL: true });
183
+ expect(layout[0][0]).toBe('─');
184
+ });
185
+
186
+ it('_displayAux: isNIL(node) shows "S" when isShowRedBlackNIL=true', () => {
187
+ const t = new BinaryTree<number, number>([], { isMapMode: false } as any);
188
+ const NIL = (t as any)._NIL;
189
+ const layout = (t as any)._displayAux(NIL, { isShowNull: true, isShowUndefined: true, isShowRedBlackNIL: true });
190
+ expect(layout[0][0]).toContain('S');
191
+ });
192
+
193
+ it('_swapProperties updates value when mapMode=false (covers !this._isMapMode assignments)', () => {
194
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
195
+ const a: any = t.createNode(1, 10);
196
+ const b: any = t.createNode(2, 20);
197
+ (t as any)._swapProperties(a, b);
198
+ expect(a.key).toBe(2);
199
+ expect(a.value).toBe(20);
200
+ expect(b.key).toBe(1);
201
+ expect(b.value).toBe(10);
202
+ });
203
+
204
+ it('_ensurePredicate for nullish input returns a predicate (covers nullish early return + ternary branch)', () => {
205
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
206
+ const p = (t as any)._ensurePredicate(undefined);
207
+ expect(p(null)).toBe(false);
208
+ // also call with a truthy node to cover the other arm of (node ? false : false)
209
+ expect(p(t.createNode(1, 1) as any)).toBe(false);
210
+ });
211
+
212
+ it('_ensurePredicate for entry and for key returns false on null node (covers `if (!node) return false`)', () => {
213
+ const t = new BinaryTree<number, number>([], { isMapMode: false });
214
+ const pEntry = (t as any)._ensurePredicate([1, 1]);
215
+ const pKey = (t as any)._ensurePredicate(1);
216
+ expect(pEntry(null)).toBe(false);
217
+ expect(pKey(null)).toBe(false);
218
+ });
219
+
220
+ it('_extractKey returns undefined when passing _NIL', () => {
221
+ const t = new BinaryTree<number, number>([], { isMapMode: false } as any);
222
+ expect((t as any)._extractKey((t as any)._NIL)).toBeUndefined();
223
+ });
224
+
225
+ it('_setValue returns false when value is undefined (covers value===undefined guard)', () => {
226
+ const t = new BinaryTree<number, number>([], { isMapMode: true });
227
+ expect((t as any)._setValue(1, undefined)).toBe(false);
228
+ });
229
+ });
@@ -0,0 +1,33 @@
1
+ import { BST } from '../../../../src';
2
+
3
+ describe('BST _boundByPredicate coverage', () => {
4
+ it('recursive traversal: returns first in-order match and short-circuits once found', () => {
5
+ const t = new BST<number, number>([], { isMapMode: false });
6
+ for (const k of [10, 5, 15, 3, 7, 12, 18]) t.set(k, k);
7
+
8
+ const pred = (node: any) => node.key >= 7;
9
+ const out = (t as any)._boundByPredicate(pred, 'RECURSIVE');
10
+ expect(out?.key).toBe(7);
11
+ });
12
+
13
+ it('recursive traversal: returns undefined when no match', () => {
14
+ const t = new BST<number, number>([], { isMapMode: false });
15
+ for (const k of [10, 5, 15]) t.set(k, k);
16
+
17
+ const out = (t as any)._boundByPredicate((node: any) => node.key === 999, 'RECURSIVE');
18
+ expect(out).toBeUndefined();
19
+ });
20
+
21
+ it('iterative traversal: returns first match and breaks when stack pop is not real', () => {
22
+ const t = new BST<number, number>([], { isMapMode: false });
23
+ for (const k of [10, 5, 15]) t.set(k, k);
24
+
25
+ const out = (t as any)._boundByPredicate((node: any) => node.key === 10, 'ITERATIVE');
26
+ expect(out?.key).toBe(10);
27
+
28
+ // Force the internal stack-pop guard branch by clearing the tree and calling again.
29
+ t.clear();
30
+ const out2 = (t as any)._boundByPredicate((node: any) => node.key === 1, 'ITERATIVE');
31
+ expect(out2).toBeUndefined();
32
+ });
33
+ });