data-structure-typed 2.2.6 → 2.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/CONTRIBUTING.md +47 -1
- package/README.md +19 -8
- package/README_CN.md +119 -275
- package/benchmark/report.html +1 -1
- package/benchmark/report.json +20 -324
- package/dist/cjs/index.cjs +109 -107
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +109 -107
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +109 -107
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +109 -107
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/leetcode/avl-tree-counter.mjs +2957 -0
- package/dist/leetcode/avl-tree-multi-map.mjs +2889 -0
- package/dist/leetcode/avl-tree.mjs +2720 -0
- package/dist/leetcode/binary-tree.mjs +1594 -0
- package/dist/leetcode/bst.mjs +2398 -0
- package/dist/leetcode/deque.mjs +683 -0
- package/dist/leetcode/directed-graph.mjs +1733 -0
- package/dist/leetcode/doubly-linked-list.mjs +709 -0
- package/dist/leetcode/hash-map.mjs +493 -0
- package/dist/leetcode/heap.mjs +542 -0
- package/dist/leetcode/max-heap.mjs +375 -0
- package/dist/leetcode/max-priority-queue.mjs +383 -0
- package/dist/leetcode/min-heap.mjs +363 -0
- package/dist/leetcode/min-priority-queue.mjs +371 -0
- package/dist/leetcode/priority-queue.mjs +363 -0
- package/dist/leetcode/queue.mjs +943 -0
- package/dist/leetcode/red-black-tree.mjs +2765 -0
- package/dist/leetcode/singly-linked-list.mjs +754 -0
- package/dist/leetcode/stack.mjs +217 -0
- package/dist/leetcode/tree-counter.mjs +3039 -0
- package/dist/leetcode/tree-multi-map.mjs +2913 -0
- package/dist/leetcode/trie.mjs +413 -0
- package/dist/leetcode/undirected-graph.mjs +1650 -0
- package/dist/types/data-structures/binary-tree/avl-tree-counter.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +2 -2
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +10 -10
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +22 -23
- package/dist/types/data-structures/binary-tree/bst.d.ts +11 -11
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/tree-counter.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +2 -2
- package/dist/umd/data-structure-typed.js +105 -103
- package/dist/umd/data-structure-typed.js.map +1 -1
- package/dist/umd/data-structure-typed.min.js +2 -2
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +48 -171
- package/src/data-structures/binary-tree/avl-tree-counter.ts +6 -6
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +13 -13
- package/src/data-structures/binary-tree/avl-tree.ts +15 -15
- package/src/data-structures/binary-tree/binary-tree.ts +53 -55
- package/src/data-structures/binary-tree/bst.ts +21 -22
- package/src/data-structures/binary-tree/red-black-tree.ts +3 -3
- package/src/data-structures/binary-tree/tree-counter.ts +4 -4
- package/src/data-structures/binary-tree/tree-multi-map.ts +13 -13
- package/test/performance/data-structures/binary-tree/red-black-tree.test.ts +1 -2
- package/test/unit/data-structures/binary-tree/avl-tree-counter.test.ts +30 -30
- package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +46 -46
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +43 -43
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +151 -151
- package/test/unit/data-structures/binary-tree/bst.test.ts +99 -99
- package/test/unit/data-structures/binary-tree/overall.test.ts +20 -20
- package/test/unit/data-structures/binary-tree/red-black-tree.test.ts +141 -141
- package/test/unit/data-structures/binary-tree/tree-counter.test.ts +37 -37
- package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +145 -145
- package/tsup.config.js +50 -21
- package/tsup.leetcode.config.js +1 -1
- package/tsup.umd.config.js +29 -0
- package/tsup.node.config.js +0 -83
|
@@ -89,11 +89,11 @@ describe('BinaryTreeNode', () => {
|
|
|
89
89
|
});
|
|
90
90
|
|
|
91
91
|
describe('BinaryTree.addMany', () => {
|
|
92
|
-
it('
|
|
92
|
+
it('setMany(): adds entries via toEntryFn and values override', () => {
|
|
93
93
|
const binTree = new BinaryTree<number, number, { id: number; name: number }>([], {
|
|
94
94
|
toEntryFn: ({ id, name }) => [id, name]
|
|
95
95
|
});
|
|
96
|
-
binTree.
|
|
96
|
+
binTree.setMany(
|
|
97
97
|
[
|
|
98
98
|
{ id: 1, name: 1 },
|
|
99
99
|
{ id: 2, name: 2 },
|
|
@@ -108,14 +108,14 @@ describe('BinaryTree.addMany', () => {
|
|
|
108
108
|
expect(binTree.get(binTree.getNode(1))).toBe(1);
|
|
109
109
|
});
|
|
110
110
|
|
|
111
|
-
it('
|
|
111
|
+
it('setMany(): handles undefined and null keys', () => {
|
|
112
112
|
const binaryTree = new BinaryTree<number, string>();
|
|
113
|
-
const addManyWithUndefined = binaryTree.
|
|
113
|
+
const addManyWithUndefined = binaryTree.setMany([1, undefined, 3]);
|
|
114
114
|
expect(addManyWithUndefined).toEqual([true, false, true]);
|
|
115
115
|
expect(binaryTree.get(undefined)).toBe(undefined);
|
|
116
|
-
const addManyWithNull = binaryTree.
|
|
116
|
+
const addManyWithNull = binaryTree.setMany([1, null, 3, 4]);
|
|
117
117
|
expect(addManyWithNull).toEqual([true, true, true, true]);
|
|
118
|
-
const addManyEntriesWithNull = binaryTree.
|
|
118
|
+
const addManyEntriesWithNull = binaryTree.setMany([
|
|
119
119
|
[1, '1'],
|
|
120
120
|
[null, 'null'],
|
|
121
121
|
[3, '3'],
|
|
@@ -126,7 +126,7 @@ describe('BinaryTree.addMany', () => {
|
|
|
126
126
|
expect(binaryTree.getNode(null)).toBe(undefined);
|
|
127
127
|
// // TODO should be null instead of undefined
|
|
128
128
|
// expect(binaryTree.getNode(null)).toBe(null);
|
|
129
|
-
const node0 = binaryTree.
|
|
129
|
+
const node0 = binaryTree.set(0, '0');
|
|
130
130
|
expect(node0).toBe(true);
|
|
131
131
|
expect(binaryTree.get(0)).toBe('0');
|
|
132
132
|
});
|
|
@@ -143,8 +143,8 @@ describe('BinaryTree', () => {
|
|
|
143
143
|
binTree.clear();
|
|
144
144
|
});
|
|
145
145
|
|
|
146
|
-
it('
|
|
147
|
-
const node = binTree.
|
|
146
|
+
it('set(): inserts a node and updates size', () => {
|
|
147
|
+
const node = binTree.set(1);
|
|
148
148
|
expect(node).not.toBeNull();
|
|
149
149
|
expect(binTree.size).toBe(1);
|
|
150
150
|
});
|
|
@@ -153,22 +153,22 @@ describe('BinaryTree', () => {
|
|
|
153
153
|
expect(binTree.getHeight(binTree.root, 'ITERATIVE')).toBe(-1);
|
|
154
154
|
expect(binTree.getMinHeight()).toBe(-1);
|
|
155
155
|
const node1 = binTree.createNode(1);
|
|
156
|
-
binTree.
|
|
156
|
+
binTree.set(node1);
|
|
157
157
|
expect(binTree.size).toBe(1);
|
|
158
158
|
|
|
159
159
|
const leftChild = new BinaryTreeNode<number>(2);
|
|
160
160
|
const rightChild = new BinaryTreeNode<number>(3);
|
|
161
|
-
binTree.
|
|
162
|
-
binTree.
|
|
161
|
+
binTree.set(leftChild);
|
|
162
|
+
binTree.set(rightChild);
|
|
163
163
|
const root = binTree.root;
|
|
164
164
|
|
|
165
165
|
expect(leftChild.familyPosition).toBe('LEFT');
|
|
166
|
-
binTree.
|
|
167
|
-
binTree.
|
|
166
|
+
binTree.set(null);
|
|
167
|
+
binTree.set(new BinaryTreeNode<number>(4));
|
|
168
168
|
expect(rightChild.familyPosition).toBe('RIGHT');
|
|
169
169
|
expect(root?.familyPosition).toBe('ROOT');
|
|
170
170
|
expect(leftChild.familyPosition).toBe('ROOT_LEFT');
|
|
171
|
-
binTree.
|
|
171
|
+
binTree.set(new BinaryTreeNode<number>(5));
|
|
172
172
|
expect(rightChild.familyPosition).toBe('ROOT_RIGHT');
|
|
173
173
|
|
|
174
174
|
binTree.delete(new BinaryTreeNode<number>(200));
|
|
@@ -182,11 +182,11 @@ describe('BinaryTree', () => {
|
|
|
182
182
|
}
|
|
183
183
|
});
|
|
184
184
|
|
|
185
|
-
it('
|
|
186
|
-
binTree.
|
|
187
|
-
binTree.
|
|
188
|
-
binTree.
|
|
189
|
-
binTree.
|
|
185
|
+
it('set()/has()/getNode(): find nodes by key and predicate', () => {
|
|
186
|
+
binTree.set([1, 1]);
|
|
187
|
+
binTree.set(undefined);
|
|
188
|
+
binTree.set([2, 2]);
|
|
189
|
+
binTree.set([3, 3]);
|
|
190
190
|
|
|
191
191
|
expect(binTree.has(1)).toBe(true);
|
|
192
192
|
expect(binTree.has(2)).toBe(true);
|
|
@@ -200,7 +200,7 @@ describe('BinaryTree', () => {
|
|
|
200
200
|
|
|
201
201
|
it('clone(): structural copy; subtree dfs with includeNull permutations', () => {
|
|
202
202
|
expect(binTree.isEmpty()).toBe(true);
|
|
203
|
-
binTree.
|
|
203
|
+
binTree.setMany([4, 2, 6, null, 1, 3, null, 5, null, 7]);
|
|
204
204
|
expect(binTree.root?.key).toBe(4);
|
|
205
205
|
expect(binTree.root?.left?.key).toBe(2);
|
|
206
206
|
expect(binTree.root?.left?.left).toBe(null);
|
|
@@ -253,10 +253,10 @@ describe('BinaryTree', () => {
|
|
|
253
253
|
});
|
|
254
254
|
|
|
255
255
|
it('isPerfectlyBalanced(): toggles with pointer tampering and skewed levels', () => {
|
|
256
|
-
binTree.
|
|
257
|
-
binTree.
|
|
258
|
-
binTree.
|
|
259
|
-
binTree.
|
|
256
|
+
binTree.set(3);
|
|
257
|
+
binTree.set(12);
|
|
258
|
+
binTree.setMany(getRandomIntArray(100, 1, 100));
|
|
259
|
+
binTree.set(10);
|
|
260
260
|
|
|
261
261
|
expect(binTree.isPerfectlyBalanced()).toBe(true);
|
|
262
262
|
const node3 = binTree.getNode(3);
|
|
@@ -265,39 +265,39 @@ describe('BinaryTree', () => {
|
|
|
265
265
|
expect(binTree.isPerfectlyBalanced()).toBe(false);
|
|
266
266
|
|
|
267
267
|
binTree.clear();
|
|
268
|
-
binTree.
|
|
268
|
+
binTree.setMany([1, null, 2, null, 3, null, 4, null, 5, null, 6, null]);
|
|
269
269
|
expect(binTree.isPerfectlyBalanced()).toBe(false);
|
|
270
270
|
});
|
|
271
271
|
|
|
272
272
|
it('getDepth(): returns correct depth with/without root parameter', () => {
|
|
273
|
-
binTree.
|
|
273
|
+
binTree.set(1);
|
|
274
274
|
expect(binTree.getDepth(1)).toBe(0);
|
|
275
|
-
binTree.
|
|
275
|
+
binTree.set(2);
|
|
276
276
|
expect(binTree.getDepth(2)).toBe(1);
|
|
277
|
-
binTree.
|
|
277
|
+
binTree.set(3);
|
|
278
278
|
expect(binTree.getDepth(3, 1)).toBe(1);
|
|
279
|
-
binTree.
|
|
279
|
+
binTree.set(4);
|
|
280
280
|
expect(binTree.getDepth(4, 1)).toBe(2);
|
|
281
281
|
expect(binTree.getDepth(4)).toBe(2);
|
|
282
282
|
expect(binTree.getDepth(4, 2)).toBe(1);
|
|
283
283
|
});
|
|
284
284
|
|
|
285
285
|
it('dfs(IN): returns in-order; height respects iterationType', () => {
|
|
286
|
-
binTree.
|
|
286
|
+
binTree.set(null);
|
|
287
287
|
binTree.delete(1);
|
|
288
288
|
expect(binTree.getHeight()).toBe(-1);
|
|
289
|
-
binTree.
|
|
290
|
-
binTree.
|
|
289
|
+
binTree.set(4);
|
|
290
|
+
binTree.set(2);
|
|
291
291
|
expect(binTree.getHeight()).toBe(1);
|
|
292
292
|
binTree.iterationType = 'RECURSIVE';
|
|
293
293
|
expect(binTree.getHeight()).toBe(1);
|
|
294
294
|
binTree.iterationType = 'ITERATIVE';
|
|
295
295
|
|
|
296
|
-
binTree.
|
|
297
|
-
binTree.
|
|
298
|
-
binTree.
|
|
299
|
-
binTree.
|
|
300
|
-
binTree.
|
|
296
|
+
binTree.set(6);
|
|
297
|
+
binTree.set(1);
|
|
298
|
+
binTree.set(new BinaryTreeNode(3));
|
|
299
|
+
binTree.set(5);
|
|
300
|
+
binTree.set(7);
|
|
301
301
|
|
|
302
302
|
const inOrder = binTree.dfs(node => node.key);
|
|
303
303
|
|
|
@@ -305,7 +305,7 @@ describe('BinaryTree', () => {
|
|
|
305
305
|
});
|
|
306
306
|
|
|
307
307
|
it('isBST(): returns true for subtree (iterative & recursive)', () => {
|
|
308
|
-
binTree.
|
|
308
|
+
binTree.setMany([
|
|
309
309
|
new BinaryTreeNode(4, 4),
|
|
310
310
|
new BinaryTreeNode(2, 2),
|
|
311
311
|
new BinaryTreeNode(6, 6),
|
|
@@ -322,7 +322,7 @@ describe('BinaryTree', () => {
|
|
|
322
322
|
|
|
323
323
|
it('isBST(): returns true for subtree (iterative & recursive)', () => {
|
|
324
324
|
expect(binTree.toVisual()).toBe('');
|
|
325
|
-
binTree.
|
|
325
|
+
binTree.setMany([4, 2, 6, 1, 3, 5, 7, 4]);
|
|
326
326
|
expect(binTree.toVisual()).toBe(
|
|
327
327
|
'N for null\n' +
|
|
328
328
|
' ___4___ \n' +
|
|
@@ -519,7 +519,7 @@ describe('BinaryTree', () => {
|
|
|
519
519
|
it('isLeaf(): detects leaves; null is treated as leaf', () => {
|
|
520
520
|
expect(binTree.getLeftMost()).toBe(undefined);
|
|
521
521
|
expect(binTree.getRightMost()).toBe(undefined);
|
|
522
|
-
binTree.
|
|
522
|
+
binTree.setMany([4, 2, 6, 1, 3, 5, 7, 4]);
|
|
523
523
|
const leftMost = binTree.getLeftMost();
|
|
524
524
|
expect(binTree.isLeaf(leftMost)).toBe(true);
|
|
525
525
|
expect(binTree.isLeaf(null)).toBe(true);
|
|
@@ -531,7 +531,7 @@ describe('BinaryTree', () => {
|
|
|
531
531
|
it('dfs/bfs on mixed-null level-order tree: expected orders (includeNull on/off)', () => {
|
|
532
532
|
expect(binTree.dfs()).toEqual([]);
|
|
533
533
|
expect([...binTree.values()]).toEqual([]);
|
|
534
|
-
binTree.
|
|
534
|
+
binTree.setMany([4, 2, 6, null, 1, 3, null, 5, null, 7]);
|
|
535
535
|
expect(binTree.dfs(node => node.key, 'PRE', false, undefined, 'ITERATIVE')).toEqual([4, 2, 1, 5, 6, 3, 7]);
|
|
536
536
|
expect(binTree.dfs(node => (node !== null ? node.key : null), 'PRE', false, undefined, 'ITERATIVE', false)).toEqual(
|
|
537
537
|
[4, 2, 1, 5, 6, 3, 7]
|
|
@@ -618,7 +618,7 @@ describe('BinaryTree', () => {
|
|
|
618
618
|
});
|
|
619
619
|
|
|
620
620
|
it('dfs on subtree (startNode): expected orders (includeNull on/off)', () => {
|
|
621
|
-
binTree.
|
|
621
|
+
binTree.setMany([4, 2, 6, null, 1, 3, null, 5, null, 7]);
|
|
622
622
|
expect(binTree.dfs(node => node.key, 'PRE', false, binTree.getNode(6), 'ITERATIVE')).toEqual([6, 3, 7]);
|
|
623
623
|
expect(
|
|
624
624
|
binTree.dfs(node => (node !== null ? node.key : null), 'PRE', false, binTree.getNode(6), 'ITERATIVE', false)
|
|
@@ -669,8 +669,8 @@ describe('BinaryTree', () => {
|
|
|
669
669
|
});
|
|
670
670
|
|
|
671
671
|
it('clear(): empties tree and resets root', () => {
|
|
672
|
-
binTree.
|
|
673
|
-
binTree.
|
|
672
|
+
binTree.set(1);
|
|
673
|
+
binTree.set(2);
|
|
674
674
|
|
|
675
675
|
expect(binTree.size).toBe(2);
|
|
676
676
|
|
|
@@ -683,7 +683,7 @@ describe('BinaryTree', () => {
|
|
|
683
683
|
it('duplicate keys: replace existing value; bfs includeNull snapshot', function () {
|
|
684
684
|
binTree.clear();
|
|
685
685
|
expect(binTree.bfs()).toEqual([]);
|
|
686
|
-
binTree.
|
|
686
|
+
binTree.setMany([-10, -10, -10, 9, 9, 20, null, null, 15, 7, 8, null, 2, null, 6, null, null, 8, 8, 8]);
|
|
687
687
|
|
|
688
688
|
expect(binTree.bfs(node => (node ? node.key : null), undefined, undefined, true)).toEqual([
|
|
689
689
|
-10,
|
|
@@ -739,21 +739,21 @@ describe('BinaryTree', () => {
|
|
|
739
739
|
// expect(bTree.keyValueNodeEntryRawToNodeAndValue({ obj: { id: 1 } })).toEqual([undefined, undefined]);
|
|
740
740
|
// });
|
|
741
741
|
|
|
742
|
-
it('
|
|
742
|
+
it('set(): duplicate key updates value (Map vs non-Map behavior)', () => {
|
|
743
743
|
const binTree = new BinaryTree<number, string>([4, 5, [1, '1'], 2, 3], { isMapMode: false });
|
|
744
744
|
expect(binTree.get(1)).toBe('1');
|
|
745
745
|
expect(binTree.getNode(1)?.value).toBe('1');
|
|
746
|
-
binTree.
|
|
746
|
+
binTree.set(1, 'a');
|
|
747
747
|
expect(binTree.get(1)).toBe('a');
|
|
748
|
-
binTree.
|
|
748
|
+
binTree.set([1, 'b']);
|
|
749
749
|
expect(binTree.getNode(1)?.value).toBe('b');
|
|
750
750
|
expect(binTree.get(1)).toBe('b');
|
|
751
751
|
const treeMap = new BinaryTree<number>([4, 5, [1, '1'], 2, 3]);
|
|
752
752
|
expect(treeMap.get(1)).toBe('1');
|
|
753
753
|
expect(treeMap.getNode(1)?.value).toBe(undefined);
|
|
754
|
-
treeMap.
|
|
754
|
+
treeMap.set(1, 'a');
|
|
755
755
|
expect(treeMap.get(1)).toBe('a');
|
|
756
|
-
treeMap.
|
|
756
|
+
treeMap.set([1, 'b']);
|
|
757
757
|
expect(treeMap.getNode(1)?.value).toBe(undefined);
|
|
758
758
|
expect(treeMap.get(1)).toBe('b');
|
|
759
759
|
});
|
|
@@ -769,7 +769,7 @@ describe('BinaryTree.ensureNode', () => {
|
|
|
769
769
|
name: string;
|
|
770
770
|
}
|
|
771
771
|
>([], { toEntryFn: rawElement => [rawElement.id, rawElement.name] });
|
|
772
|
-
binTree.
|
|
772
|
+
binTree.set([1, 'Pablo']);
|
|
773
773
|
const node = binTree.getNode(1);
|
|
774
774
|
// expect(binTree.ensureNode({ id: 1, name: 'Pablo' })).toBe(node);
|
|
775
775
|
expect(binTree.ensureNode([1, 'Pablo'])).toBe(node);
|
|
@@ -782,11 +782,11 @@ describe('BinaryTree.ensureNode', () => {
|
|
|
782
782
|
describe('BinaryTree - Morris traversal', () => {
|
|
783
783
|
// Create a binary binTree
|
|
784
784
|
const binTree = new BinaryTree<number>();
|
|
785
|
-
binTree.
|
|
786
|
-
binTree.
|
|
787
|
-
binTree.
|
|
788
|
-
binTree.
|
|
789
|
-
binTree.
|
|
785
|
+
binTree.set(1);
|
|
786
|
+
binTree.set(2);
|
|
787
|
+
binTree.set(3);
|
|
788
|
+
binTree.set(4);
|
|
789
|
+
binTree.set(5);
|
|
790
790
|
it('morris(IN): equals dfs(IN) (iterative/recursive)', () => {
|
|
791
791
|
// Perform in-order Morris traversal
|
|
792
792
|
const result = binTree.morris(node => node.key, 'IN');
|
|
@@ -841,11 +841,11 @@ describe('BinaryTree.toEntryFn', () => {
|
|
|
841
841
|
}).toThrow('toEntryFn must be a function type');
|
|
842
842
|
});
|
|
843
843
|
|
|
844
|
-
it('toEntryFn +
|
|
844
|
+
it('toEntryFn + setMany(): IN order equals dfs/Morris', () => {
|
|
845
845
|
const binTree = new BinaryTree<number, number, { obj: { id: number } }>([], {
|
|
846
846
|
toEntryFn: ele => [ele.obj.id, ele.obj.id]
|
|
847
847
|
});
|
|
848
|
-
binTree.
|
|
848
|
+
binTree.setMany([
|
|
849
849
|
{ obj: { id: 1 } },
|
|
850
850
|
{ obj: { id: 2 } },
|
|
851
851
|
{ obj: { id: 3 } },
|
|
@@ -1003,10 +1003,10 @@ describe('BinaryTree', () => {
|
|
|
1003
1003
|
expect(binTree.root).toBe(undefined);
|
|
1004
1004
|
});
|
|
1005
1005
|
|
|
1006
|
-
it('
|
|
1007
|
-
binTree.
|
|
1008
|
-
binTree.
|
|
1009
|
-
binTree.
|
|
1006
|
+
it('set(): inserts nodes and sets root', () => {
|
|
1007
|
+
binTree.set([5, 'A']);
|
|
1008
|
+
binTree.set([3, 'B']);
|
|
1009
|
+
binTree.set([7, 'C']);
|
|
1010
1010
|
|
|
1011
1011
|
expect(binTree.size).toBe(3);
|
|
1012
1012
|
expect(binTree.isEmpty()).toBe(false);
|
|
@@ -1014,9 +1014,9 @@ describe('BinaryTree', () => {
|
|
|
1014
1014
|
});
|
|
1015
1015
|
|
|
1016
1016
|
it('should clear the BinaryTree', () => {
|
|
1017
|
-
binTree.
|
|
1018
|
-
binTree.
|
|
1019
|
-
binTree.
|
|
1017
|
+
binTree.set([5, 'A']);
|
|
1018
|
+
binTree.set([3, 'B']);
|
|
1019
|
+
binTree.set([7, 'C']);
|
|
1020
1020
|
|
|
1021
1021
|
binTree.clear();
|
|
1022
1022
|
|
|
@@ -1026,9 +1026,9 @@ describe('BinaryTree', () => {
|
|
|
1026
1026
|
});
|
|
1027
1027
|
|
|
1028
1028
|
it('getNode()/get(): resolve nodes and values by key', () => {
|
|
1029
|
-
binTree.
|
|
1030
|
-
binTree.
|
|
1031
|
-
binTree.
|
|
1029
|
+
binTree.set([5, 'A']);
|
|
1030
|
+
binTree.set([3, 'B']);
|
|
1031
|
+
binTree.set([7, 'C']);
|
|
1032
1032
|
|
|
1033
1033
|
const nodeA = binTree.getNode(5);
|
|
1034
1034
|
const nodeB = binTree.getNode(3);
|
|
@@ -1040,7 +1040,7 @@ describe('BinaryTree', () => {
|
|
|
1040
1040
|
});
|
|
1041
1041
|
|
|
1042
1042
|
it('getNode(): returns undefined for missing key', () => {
|
|
1043
|
-
binTree.
|
|
1043
|
+
binTree.set([5, 'A']);
|
|
1044
1044
|
|
|
1045
1045
|
const node = binTree.getNode(3);
|
|
1046
1046
|
|
|
@@ -1048,9 +1048,9 @@ describe('BinaryTree', () => {
|
|
|
1048
1048
|
});
|
|
1049
1049
|
|
|
1050
1050
|
it('should get the depth of a node', () => {
|
|
1051
|
-
binTree.
|
|
1052
|
-
binTree.
|
|
1053
|
-
binTree.
|
|
1051
|
+
binTree.set([5, 'A']);
|
|
1052
|
+
binTree.set([3, 'B']);
|
|
1053
|
+
binTree.set([7, 'C']);
|
|
1054
1054
|
|
|
1055
1055
|
expect(binTree.getDepth(7)).toBe(1);
|
|
1056
1056
|
expect(binTree.getDepth(3)).toBe(1);
|
|
@@ -1058,9 +1058,9 @@ describe('BinaryTree', () => {
|
|
|
1058
1058
|
|
|
1059
1059
|
it('getHeight()/getMinHeight(): expected heights', () => {
|
|
1060
1060
|
expect(binTree.getMinHeight()).toBe(-1);
|
|
1061
|
-
binTree.
|
|
1062
|
-
binTree.
|
|
1063
|
-
binTree.
|
|
1061
|
+
binTree.set([5, 'A']);
|
|
1062
|
+
binTree.set(3, 'B');
|
|
1063
|
+
binTree.set([7, 'C']);
|
|
1064
1064
|
|
|
1065
1065
|
expect(binTree.getHeight()).toBe(1);
|
|
1066
1066
|
expect(binTree.getHeight(undefined, 'RECURSIVE')).toBe(1);
|
|
@@ -1068,17 +1068,17 @@ describe('BinaryTree', () => {
|
|
|
1068
1068
|
});
|
|
1069
1069
|
|
|
1070
1070
|
it('isBST(): returns true for valid tree', () => {
|
|
1071
|
-
binTree.
|
|
1072
|
-
binTree.
|
|
1073
|
-
binTree.
|
|
1071
|
+
binTree.set([5, 'A']);
|
|
1072
|
+
binTree.set([3, 'B']);
|
|
1073
|
+
binTree.set([7, 'C']);
|
|
1074
1074
|
|
|
1075
1075
|
expect(binTree.isBST()).toBe(true);
|
|
1076
1076
|
});
|
|
1077
1077
|
|
|
1078
1078
|
it('dfs(default IN): returns expected order', () => {
|
|
1079
|
-
binTree.
|
|
1080
|
-
binTree.
|
|
1081
|
-
binTree.
|
|
1079
|
+
binTree.set([5, 'A']);
|
|
1080
|
+
binTree.set([3, 'B']);
|
|
1081
|
+
binTree.set([7, 'C']);
|
|
1082
1082
|
|
|
1083
1083
|
const result = binTree.dfs();
|
|
1084
1084
|
expect(result).toEqual([3, 5, 7]);
|
|
@@ -1086,9 +1086,9 @@ describe('BinaryTree', () => {
|
|
|
1086
1086
|
});
|
|
1087
1087
|
|
|
1088
1088
|
it('bfs(): returns expected level-order', () => {
|
|
1089
|
-
binTree.
|
|
1090
|
-
binTree.
|
|
1091
|
-
binTree.
|
|
1089
|
+
binTree.set([5, 'A']);
|
|
1090
|
+
binTree.set([3, 'B']);
|
|
1091
|
+
binTree.set([7, 'C']);
|
|
1092
1092
|
|
|
1093
1093
|
const result = binTree.bfs(node => node.key);
|
|
1094
1094
|
expect(result).toEqual([5, 3, 7]);
|
|
@@ -1096,9 +1096,9 @@ describe('BinaryTree', () => {
|
|
|
1096
1096
|
});
|
|
1097
1097
|
|
|
1098
1098
|
it('listLevels(): returns keys by level', () => {
|
|
1099
|
-
binTree.
|
|
1100
|
-
binTree.
|
|
1101
|
-
binTree.
|
|
1099
|
+
binTree.set([5, 'A']);
|
|
1100
|
+
binTree.set([3, 'B']);
|
|
1101
|
+
binTree.set([7, 'C']);
|
|
1102
1102
|
|
|
1103
1103
|
const levels = binTree.listLevels();
|
|
1104
1104
|
expect(levels).toEqual([[5], [3, 7]]);
|
|
@@ -1106,9 +1106,9 @@ describe('BinaryTree', () => {
|
|
|
1106
1106
|
});
|
|
1107
1107
|
|
|
1108
1108
|
it('delete(): removes nodes and updates size', () => {
|
|
1109
|
-
binTree.
|
|
1110
|
-
binTree.
|
|
1111
|
-
binTree.
|
|
1109
|
+
binTree.set([5, 'A']);
|
|
1110
|
+
binTree.set([3, 'B']);
|
|
1111
|
+
binTree.set([7, 'C']);
|
|
1112
1112
|
|
|
1113
1113
|
binTree.delete(3);
|
|
1114
1114
|
|
|
@@ -1117,33 +1117,33 @@ describe('BinaryTree', () => {
|
|
|
1117
1117
|
});
|
|
1118
1118
|
|
|
1119
1119
|
it('getPathToRoot(): path from key to root; [] for missing', () => {
|
|
1120
|
-
binTree.
|
|
1121
|
-
binTree.
|
|
1122
|
-
binTree.
|
|
1120
|
+
binTree.set([5, 'A']);
|
|
1121
|
+
binTree.set([3, 'B']);
|
|
1122
|
+
binTree.set([7, 'C']);
|
|
1123
1123
|
|
|
1124
1124
|
expect(binTree.getPathToRoot(7)).toEqual([7, 5]);
|
|
1125
1125
|
expect(binTree.getPathToRoot(1)).toEqual([]);
|
|
1126
1126
|
});
|
|
1127
1127
|
|
|
1128
1128
|
it('isPerfectlyBalanced(): true for balanced tree', () => {
|
|
1129
|
-
binTree.
|
|
1130
|
-
binTree.
|
|
1131
|
-
binTree.
|
|
1129
|
+
binTree.set([5, 'A']);
|
|
1130
|
+
binTree.set([3, 'B']);
|
|
1131
|
+
binTree.set([7, 'C']);
|
|
1132
1132
|
|
|
1133
1133
|
expect(binTree.isPerfectlyBalanced()).toBe(true);
|
|
1134
1134
|
});
|
|
1135
1135
|
|
|
1136
1136
|
it('getNodes(predicate): returns matches (iterative & recursive)', () => {
|
|
1137
|
-
binTree.
|
|
1138
|
-
binTree.
|
|
1139
|
-
binTree.
|
|
1140
|
-
binTree.
|
|
1141
|
-
binTree.
|
|
1142
|
-
binTree.
|
|
1143
|
-
binTree.
|
|
1144
|
-
binTree.
|
|
1145
|
-
binTree.
|
|
1146
|
-
binTree.
|
|
1137
|
+
binTree.set([5, 'E']);
|
|
1138
|
+
binTree.set([4, 'D']);
|
|
1139
|
+
binTree.set([3, 'C']);
|
|
1140
|
+
binTree.set([7, 'G']);
|
|
1141
|
+
binTree.set([null, 'null']);
|
|
1142
|
+
binTree.set([1, 'A']);
|
|
1143
|
+
binTree.set([6, 'F']);
|
|
1144
|
+
binTree.set([null, 'null']);
|
|
1145
|
+
binTree.set([2, 'B']);
|
|
1146
|
+
binTree.set([null, 'null']);
|
|
1147
1147
|
|
|
1148
1148
|
const nodes = binTree.getNodes(node => node.key === 2);
|
|
1149
1149
|
|
|
@@ -1164,9 +1164,9 @@ describe('BinaryTree', () => {
|
|
|
1164
1164
|
});
|
|
1165
1165
|
|
|
1166
1166
|
it('morris(IN): equals dfs(IN); clear() => []', () => {
|
|
1167
|
-
binTree.
|
|
1168
|
-
binTree.
|
|
1169
|
-
binTree.
|
|
1167
|
+
binTree.set([5, 'A']);
|
|
1168
|
+
binTree.set([3, 'B']);
|
|
1169
|
+
binTree.set([7, 'C']);
|
|
1170
1170
|
|
|
1171
1171
|
binTree.iterationType = 'ITERATIVE';
|
|
1172
1172
|
expect([...binTree]).toEqual([
|
|
@@ -1189,9 +1189,9 @@ describe('BinaryTree', () => {
|
|
|
1189
1189
|
});
|
|
1190
1190
|
|
|
1191
1191
|
it('delete(): removes all nodes; height == -1', () => {
|
|
1192
|
-
binTree.
|
|
1193
|
-
binTree.
|
|
1194
|
-
binTree.
|
|
1192
|
+
binTree.set([5, 'A']);
|
|
1193
|
+
binTree.set([3, 'B']);
|
|
1194
|
+
binTree.set([7, 'C']);
|
|
1195
1195
|
|
|
1196
1196
|
binTree.delete(5);
|
|
1197
1197
|
binTree.delete(7);
|
|
@@ -1215,11 +1215,11 @@ describe('BinaryTree (non-Map mode)', () => {
|
|
|
1215
1215
|
binTree.clear();
|
|
1216
1216
|
});
|
|
1217
1217
|
|
|
1218
|
-
it('
|
|
1219
|
-
binTree.
|
|
1220
|
-
binTree.
|
|
1221
|
-
binTree.
|
|
1222
|
-
binTree.
|
|
1218
|
+
it('set()/has()/getNode(): find nodes by key and predicate', () => {
|
|
1219
|
+
binTree.set([1, '1']);
|
|
1220
|
+
binTree.set(undefined);
|
|
1221
|
+
binTree.set([2, '2']);
|
|
1222
|
+
binTree.set([3, '3']);
|
|
1223
1223
|
|
|
1224
1224
|
expect(binTree.has(1)).toBe(true);
|
|
1225
1225
|
expect(binTree.has(2)).toBe(true);
|
|
@@ -1232,7 +1232,7 @@ describe('BinaryTree (non-Map mode)', () => {
|
|
|
1232
1232
|
});
|
|
1233
1233
|
|
|
1234
1234
|
it('isBST(): returns true for subtree (iterative & recursive)', () => {
|
|
1235
|
-
binTree.
|
|
1235
|
+
binTree.setMany([
|
|
1236
1236
|
new BinaryTreeNode(4),
|
|
1237
1237
|
new BinaryTreeNode(2),
|
|
1238
1238
|
new BinaryTreeNode(6),
|
|
@@ -1248,9 +1248,9 @@ describe('BinaryTree (non-Map mode)', () => {
|
|
|
1248
1248
|
});
|
|
1249
1249
|
|
|
1250
1250
|
it('getNode()/get(): resolve nodes and values by key', () => {
|
|
1251
|
-
binTree.
|
|
1252
|
-
binTree.
|
|
1253
|
-
binTree.
|
|
1251
|
+
binTree.set([5, 'A']);
|
|
1252
|
+
binTree.set([3, 'B']);
|
|
1253
|
+
binTree.set([7, 'C']);
|
|
1254
1254
|
|
|
1255
1255
|
const nodeA = binTree.getNode(5);
|
|
1256
1256
|
const nodeB = binTree.getNode(3);
|
|
@@ -1262,16 +1262,16 @@ describe('BinaryTree (non-Map mode)', () => {
|
|
|
1262
1262
|
});
|
|
1263
1263
|
|
|
1264
1264
|
it('getNodes(predicate): returns matches (iterative & recursive)', () => {
|
|
1265
|
-
binTree.
|
|
1266
|
-
binTree.
|
|
1267
|
-
binTree.
|
|
1268
|
-
binTree.
|
|
1269
|
-
binTree.
|
|
1270
|
-
binTree.
|
|
1271
|
-
binTree.
|
|
1272
|
-
binTree.
|
|
1273
|
-
binTree.
|
|
1274
|
-
binTree.
|
|
1265
|
+
binTree.set([5, 'E']);
|
|
1266
|
+
binTree.set([4, 'D']);
|
|
1267
|
+
binTree.set([3, 'C']);
|
|
1268
|
+
binTree.set([7, 'G']);
|
|
1269
|
+
binTree.set([null, 'null']);
|
|
1270
|
+
binTree.set([1, 'A']);
|
|
1271
|
+
binTree.set([6, 'F']);
|
|
1272
|
+
binTree.set([null, 'null']);
|
|
1273
|
+
binTree.set([2, 'B']);
|
|
1274
|
+
binTree.set([null, 'null']);
|
|
1275
1275
|
|
|
1276
1276
|
const nodes = binTree.getNodes(node => node.key === 2);
|
|
1277
1277
|
|
|
@@ -1296,9 +1296,9 @@ describe('BinaryTree (map mode) - higher-order & iteration', () => {
|
|
|
1296
1296
|
let binaryTree: BinaryTree<number, string>;
|
|
1297
1297
|
beforeEach(() => {
|
|
1298
1298
|
binaryTree = new BinaryTree();
|
|
1299
|
-
binaryTree.
|
|
1300
|
-
binaryTree.
|
|
1301
|
-
binaryTree.
|
|
1299
|
+
binaryTree.set([1, 'a']);
|
|
1300
|
+
binaryTree.set(2, 'b');
|
|
1301
|
+
binaryTree.set([3, 'c']);
|
|
1302
1302
|
});
|
|
1303
1303
|
|
|
1304
1304
|
it('getNode(): returns BinaryTreeNode instance', () => {
|
|
@@ -1382,7 +1382,7 @@ describe('BinaryTree (map mode) - higher-order & iteration', () => {
|
|
|
1382
1382
|
|
|
1383
1383
|
it('bfs(includeNull=true, no callback): yields undefined placeholders', () => {
|
|
1384
1384
|
const binTree = new BinaryTree();
|
|
1385
|
-
binTree.
|
|
1385
|
+
binTree.setMany([-10, -10, -10, 9, 9, 20, null, null, 15, 7, 8, null, 2, null, 6, null, null, 8, 8, 8]);
|
|
1386
1386
|
const bfsResult = binTree.bfs(undefined, undefined, undefined, true);
|
|
1387
1387
|
expect(bfsResult).toEqual([
|
|
1388
1388
|
-10,
|
|
@@ -1407,9 +1407,9 @@ describe('BinaryTree (non-Map mode) - higher-order & iteration', () => {
|
|
|
1407
1407
|
let binaryTree: BinaryTree<number, string>;
|
|
1408
1408
|
beforeEach(() => {
|
|
1409
1409
|
binaryTree = new BinaryTree<number, string>([], { isMapMode: false });
|
|
1410
|
-
binaryTree.
|
|
1411
|
-
binaryTree.
|
|
1412
|
-
binaryTree.
|
|
1410
|
+
binaryTree.set([1, 'a']);
|
|
1411
|
+
binaryTree.set(2, 'b');
|
|
1412
|
+
binaryTree.set([3, 'c']);
|
|
1413
1413
|
});
|
|
1414
1414
|
|
|
1415
1415
|
it('clone(): preserves structure and allows get() by node', () => {
|
|
@@ -1485,14 +1485,14 @@ describe('Coverage boosters - merge/print/iterator/startNode/addMany-mismatch/de
|
|
|
1485
1485
|
it('addMany: edge cases when values iterator shorter/longer than keys', () => {
|
|
1486
1486
|
const t = new BinaryTree<number, number>([], { isMapMode: true } as any);
|
|
1487
1487
|
// values has only 1 item, keys has 3
|
|
1488
|
-
t.
|
|
1488
|
+
t.setMany([1, 2, 3], [10]);
|
|
1489
1489
|
expect(t.get(1)).toBe(10);
|
|
1490
1490
|
expect(t.get(2)).toBeUndefined(); // subsequent value not provided
|
|
1491
1491
|
expect(t.get(3)).toBeUndefined();
|
|
1492
1492
|
|
|
1493
1493
|
// reverse test: values longer (extra values should be ignored)
|
|
1494
1494
|
const t2 = new BinaryTree<number, number>([], { isMapMode: true } as any);
|
|
1495
|
-
t2.
|
|
1495
|
+
t2.setMany([7, 8], [70, 80, 90, 100]);
|
|
1496
1496
|
expect(t2.get(7)).toBe(70);
|
|
1497
1497
|
expect(t2.get(8)).toBe(80);
|
|
1498
1498
|
});
|
|
@@ -1524,7 +1524,7 @@ describe('Coverage boosters - merge/print/iterator/startNode/addMany-mismatch/de
|
|
|
1524
1524
|
);
|
|
1525
1525
|
const c = t.clone() as BinaryTree<number, string>;
|
|
1526
1526
|
// In the original tree, "replace" the value for the same key (Map mode triggers _store.set)
|
|
1527
|
-
t.
|
|
1527
|
+
t.set([2, 'B']);
|
|
1528
1528
|
// Because clone shares Map storage, the clone can also read the new value
|
|
1529
1529
|
expect(c.get(2)).toBe('B');
|
|
1530
1530
|
});
|
|
@@ -1585,7 +1585,7 @@ describe('Coverage boosters - close remaining uncovered branches', () => {
|
|
|
1585
1585
|
]);
|
|
1586
1586
|
});
|
|
1587
1587
|
|
|
1588
|
-
it('
|
|
1588
|
+
it('set(): build tree with no undefined child slot -> return false path', () => {
|
|
1589
1589
|
const t = new BinaryTree<number>();
|
|
1590
1590
|
const r = t.createNode(1)!;
|
|
1591
1591
|
// explicitly set left/right child pointers to null (not undefined) so BFS finds no insertion slot
|
|
@@ -1594,7 +1594,7 @@ describe('Coverage boosters - close remaining uncovered branches', () => {
|
|
|
1594
1594
|
(t as any)._root = r;
|
|
1595
1595
|
(t as any)._size = 1;
|
|
1596
1596
|
|
|
1597
|
-
expect(t.
|
|
1597
|
+
expect(t.set(2)).toBe(false); // no insertion position -> return false
|
|
1598
1598
|
});
|
|
1599
1599
|
});
|
|
1600
1600
|
|
|
@@ -1607,14 +1607,14 @@ describe('Coverage boosters v2 - hit remaining statements', () => {
|
|
|
1607
1607
|
expect(child.familyPosition).toBe('MAL_NODE');
|
|
1608
1608
|
});
|
|
1609
1609
|
|
|
1610
|
-
it('
|
|
1610
|
+
it('set(): returns false when tree has no undefined slots (all defined as null)', () => {
|
|
1611
1611
|
const t = new BinaryTree<number>();
|
|
1612
1612
|
const root = new BinaryTreeNode<number>(1);
|
|
1613
1613
|
(root as any).left = null;
|
|
1614
1614
|
(root as any).right = null;
|
|
1615
1615
|
(t as any)._root = root;
|
|
1616
1616
|
(t as any)._size = 1;
|
|
1617
|
-
expect(t.
|
|
1617
|
+
expect(t.set(2)).toBe(false); // no slot with left/right undefined after queue traversal
|
|
1618
1618
|
});
|
|
1619
1619
|
|
|
1620
1620
|
it('getSuccessor(): climb ancestors while x is a right child', () => {
|
|
@@ -1645,8 +1645,8 @@ describe('Coverage boosters v2 - hit remaining statements', () => {
|
|
|
1645
1645
|
|
|
1646
1646
|
it('_extractKey via Map mode: get/has on entry tuple + null/undefined keys', () => {
|
|
1647
1647
|
const t = new BinaryTree<number, string>([], { isMapMode: true } as any);
|
|
1648
|
-
t.
|
|
1649
|
-
t.
|
|
1648
|
+
t.set([1, 'a']);
|
|
1649
|
+
t.set([2, 'b']);
|
|
1650
1650
|
expect(t.get([2, 'anything'] as any)).toBe('b'); // entry tuple path
|
|
1651
1651
|
expect(t.has([1, 'x'] as any)).toBe(true);
|
|
1652
1652
|
expect(t.get([null as any, 'x'] as any)).toBeUndefined(); // null key
|
|
@@ -1655,7 +1655,7 @@ describe('Coverage boosters v2 - hit remaining statements', () => {
|
|
|
1655
1655
|
|
|
1656
1656
|
it('_setValue: value is undefined branch executes (Map mode)', () => {
|
|
1657
1657
|
const t = new BinaryTree<number, string>([], { isMapMode: true } as any);
|
|
1658
|
-
expect(t.
|
|
1658
|
+
expect(t.set([10, undefined] as any)).toBe(true); // trigger _setValue branch where value is undefined
|
|
1659
1659
|
expect(t.get(10)).toBeUndefined();
|
|
1660
1660
|
});
|
|
1661
1661
|
|
|
@@ -1700,7 +1700,7 @@ describe('Classic usage examples', () => {
|
|
|
1700
1700
|
expect(tree.size).toBe(9);
|
|
1701
1701
|
|
|
1702
1702
|
// Add new element
|
|
1703
|
-
tree.
|
|
1703
|
+
tree.set(10, 'ten');
|
|
1704
1704
|
expect(tree.size).toBe(10);
|
|
1705
1705
|
});
|
|
1706
1706
|
|
|
@@ -1903,7 +1903,7 @@ describe('Classic usage examples', () => {
|
|
|
1903
1903
|
expect(treeHeight).toBeGreaterThan(0);
|
|
1904
1904
|
|
|
1905
1905
|
// Add new file
|
|
1906
|
-
fileSystem.
|
|
1906
|
+
fileSystem.set(8, { id: 8, name: 'archive.zip', type: 'file', size: 300 });
|
|
1907
1907
|
expect(fileSystem.size).toBe(8);
|
|
1908
1908
|
|
|
1909
1909
|
// Verify complete binary tree structure
|