data-structure-typed 1.42.2 → 1.42.4

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 (57) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +12 -12
  3. package/benchmark/report.html +12 -12
  4. package/benchmark/report.json +104 -104
  5. package/dist/cjs/src/data-structures/binary-tree/avl-tree.d.ts +2 -2
  6. package/dist/cjs/src/data-structures/binary-tree/avl-tree.js +5 -3
  7. package/dist/cjs/src/data-structures/binary-tree/avl-tree.js.map +1 -1
  8. package/dist/cjs/src/data-structures/binary-tree/binary-tree.d.ts +57 -53
  9. package/dist/cjs/src/data-structures/binary-tree/binary-tree.js +116 -54
  10. package/dist/cjs/src/data-structures/binary-tree/binary-tree.js.map +1 -1
  11. package/dist/cjs/src/data-structures/binary-tree/bst.d.ts +42 -15
  12. package/dist/cjs/src/data-structures/binary-tree/bst.js +77 -21
  13. package/dist/cjs/src/data-structures/binary-tree/bst.js.map +1 -1
  14. package/dist/cjs/src/data-structures/binary-tree/rb-tree.d.ts +28 -51
  15. package/dist/cjs/src/data-structures/binary-tree/rb-tree.js +148 -180
  16. package/dist/cjs/src/data-structures/binary-tree/rb-tree.js.map +1 -1
  17. package/dist/cjs/src/data-structures/binary-tree/tree-multiset.d.ts +10 -10
  18. package/dist/cjs/src/data-structures/binary-tree/tree-multiset.js +20 -17
  19. package/dist/cjs/src/data-structures/binary-tree/tree-multiset.js.map +1 -1
  20. package/dist/cjs/src/data-structures/graph/abstract-graph.js.map +1 -1
  21. package/dist/cjs/src/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
  22. package/dist/cjs/src/types/data-structures/binary-tree/rb-tree.d.ts +4 -0
  23. package/dist/cjs/src/types/data-structures/binary-tree/rb-tree.js +0 -5
  24. package/dist/cjs/src/types/data-structures/binary-tree/rb-tree.js.map +1 -1
  25. package/dist/mjs/src/data-structures/binary-tree/avl-tree.d.ts +2 -2
  26. package/dist/mjs/src/data-structures/binary-tree/avl-tree.js +5 -3
  27. package/dist/mjs/src/data-structures/binary-tree/binary-tree.d.ts +57 -53
  28. package/dist/mjs/src/data-structures/binary-tree/binary-tree.js +117 -55
  29. package/dist/mjs/src/data-structures/binary-tree/bst.d.ts +42 -15
  30. package/dist/mjs/src/data-structures/binary-tree/bst.js +79 -21
  31. package/dist/mjs/src/data-structures/binary-tree/rb-tree.d.ts +28 -51
  32. package/dist/mjs/src/data-structures/binary-tree/rb-tree.js +148 -184
  33. package/dist/mjs/src/data-structures/binary-tree/tree-multiset.d.ts +10 -10
  34. package/dist/mjs/src/data-structures/binary-tree/tree-multiset.js +19 -17
  35. package/dist/mjs/src/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
  36. package/dist/mjs/src/types/data-structures/binary-tree/rb-tree.d.ts +4 -0
  37. package/dist/mjs/src/types/data-structures/binary-tree/rb-tree.js +0 -5
  38. package/dist/umd/data-structure-typed.min.js +1 -1
  39. package/dist/umd/data-structure-typed.min.js.map +1 -1
  40. package/package.json +2 -2
  41. package/src/data-structures/binary-tree/avl-tree.ts +5 -4
  42. package/src/data-structures/binary-tree/binary-tree.ts +227 -158
  43. package/src/data-structures/binary-tree/bst.ts +100 -34
  44. package/src/data-structures/binary-tree/rb-tree.ts +227 -236
  45. package/src/data-structures/binary-tree/tree-multiset.ts +24 -23
  46. package/src/data-structures/graph/abstract-graph.ts +18 -14
  47. package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
  48. package/src/types/data-structures/binary-tree/rb-tree.ts +5 -5
  49. package/test/performance/reportor.ts +1 -0
  50. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +20 -1
  51. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +38 -38
  52. package/test/unit/data-structures/binary-tree/bst.test.ts +13 -0
  53. package/test/unit/data-structures/binary-tree/rb-tree.test.ts +205 -159
  54. package/test/unit/data-structures/graph/directed-graph.test.ts +7 -8
  55. package/test/unit/data-structures/graph/salty-edges.json +875 -1
  56. package/test/unit/data-structures/graph/salty-vertexes.json +200 -1
  57. package/test/unit/data-structures/graph/undirected-graph.test.ts +15 -16
@@ -71,23 +71,24 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
71
71
  /**
72
72
  * The `add` function adds a new node to a binary search tree, updating the count if the key already
73
73
  * exists, and balancing the tree if necessary.
74
- * @param {BTNKey | N | null} keyOrNode - The `keyOrNode` parameter can be either a
74
+ * @param {BTNKey | N | undefined} keyOrNode - The `keyOrNode` parameter can be either a
75
75
  * `BTNKey` (which represents the key of the node to be added), a `N` (which represents a
76
- * node to be added), or `null` (which represents a null node).
76
+ * node to be added), or `undefined` (which represents a undefined node).
77
77
  * @param [value] - The `value` parameter represents the value associated with the key that is being
78
78
  * added to the binary tree.
79
79
  * @param [count=1] - The `count` parameter represents the number of occurrences of the key/value
80
80
  * pair that will be added to the binary tree. It has a default value of 1, which means that if no
81
81
  * count is specified, the default count will be 1.
82
- * @returns The function `add` returns a value of type `N | null | undefined`.
82
+ * @returns The function `add` returns a value of type `N | undefined | undefined`.
83
83
  */
84
- override add(keyOrNode: BTNKey | N | null, value?: V, count = 1): N | null | undefined {
85
- let inserted: N | null | undefined = undefined,
86
- newNode: N | null;
84
+ override add(keyOrNode: BTNKey | N | null | undefined, value?: V, count = 1): N | undefined {
85
+ if(keyOrNode === null) return undefined;
86
+ let inserted: N | undefined = undefined,
87
+ newNode: N | undefined;
87
88
  if (keyOrNode instanceof TreeMultisetNode) {
88
89
  newNode = this.createNode(keyOrNode.key, keyOrNode.value, keyOrNode.count);
89
- } else if (keyOrNode === null) {
90
- newNode = null;
90
+ } else if (keyOrNode === undefined) {
91
+ newNode = undefined;
91
92
  } else {
92
93
  newNode = this.createNode(keyOrNode, value, count);
93
94
  }
@@ -138,7 +139,7 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
138
139
  }
139
140
  }
140
141
  } else {
141
- // TODO may need to support null inserted
142
+ // TODO may need to support undefined inserted
142
143
  }
143
144
  } else {
144
145
  traversing = false;
@@ -151,17 +152,17 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
151
152
 
152
153
  /**
153
154
  * The function adds a new node to a binary tree if there is an available slot in the parent node.
154
- * @param {N | null} newNode - The `newNode` parameter represents the node that needs to be added to
155
- * the tree. It can be either a node object (`N`) or `null`.
155
+ * @param {N | undefined} newNode - The `newNode` parameter represents the node that needs to be added to
156
+ * the tree. It can be either a node object (`N`) or `undefined`.
156
157
  * @param {N} parent - The `parent` parameter represents the parent node to which the new node will
157
158
  * be added as a child.
158
159
  * @returns The method `_addTo` returns either the `parent.left`, `parent.right`, or `undefined`.
159
160
  */
160
- override _addTo(newNode: N | null, parent: N): N | null | undefined {
161
+ override _addTo(newNode: N | undefined, parent: N): N | undefined {
161
162
  if (parent) {
162
163
  if (parent.left === undefined) {
163
164
  parent.left = newNode;
164
- if (newNode !== null) {
165
+ if (newNode !== undefined) {
165
166
  this._size = this.size + 1;
166
167
  this._setCount(this.count + newNode.count);
167
168
  }
@@ -169,7 +170,7 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
169
170
  return parent.left;
170
171
  } else if (parent.right === undefined) {
171
172
  parent.right = newNode;
172
- if (newNode !== null) {
173
+ if (newNode !== undefined) {
173
174
  this._size = this.size + 1;
174
175
  this._setCount(this.count + newNode.count);
175
176
  }
@@ -185,15 +186,15 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
185
186
  /**
186
187
  * The `addMany` function adds multiple keys or nodes to a TreeMultiset and returns an array of the
187
188
  * inserted nodes.
188
- * @param {(BTNKey | null)[] | (N | null)[]} keysOrNodes - An array of keys or nodes to be
189
+ * @param {(BTNKey | undefined)[] | (N | undefined)[]} keysOrNodes - An array of keys or nodes to be
189
190
  * added to the multiset. Each element can be either a BTNKey or a TreeMultisetNode.
190
191
  * @param {V[]} [data] - The `data` parameter is an optional array of values that correspond
191
192
  * to the keys or nodes being added to the multiset. It is used to associate additional data with
192
193
  * each key or node.
193
- * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
194
+ * @returns The function `addMany` returns an array of `N`, `undefined`, or `undefined` values.
194
195
  */
195
- override addMany(keysOrNodes: (BTNKey | null)[] | (N | null)[], data?: V[]): (N | null | undefined)[] {
196
- const inserted: (N | null | undefined)[] = [];
196
+ override addMany(keysOrNodes: (BTNKey | undefined)[] | (N | undefined)[], data?: V[]): (N | undefined)[] {
197
+ const inserted: (N | undefined | undefined)[] = [];
197
198
 
198
199
  for (let i = 0; i < keysOrNodes.length; i++) {
199
200
  const keyOrNode = keysOrNodes[i];
@@ -203,7 +204,7 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
203
204
  continue;
204
205
  }
205
206
 
206
- if (keyOrNode === null) {
207
+ if (keyOrNode === undefined) {
207
208
  inserted.push(this.add(NaN, undefined, 0));
208
209
  continue;
209
210
  }
@@ -283,11 +284,11 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
283
284
  const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
284
285
  if (!this.root) return bstDeletedResult;
285
286
 
286
- const curr: N | null = this.getNode(identifier, callback);
287
+ const curr: N | undefined = this.getNode(identifier, callback) ?? undefined;
287
288
  if (!curr) return bstDeletedResult;
288
289
 
289
- const parent: N | null = curr?.parent ? curr.parent : null;
290
- let needBalanced: N | null = null,
290
+ const parent: N | undefined = curr?.parent ? curr.parent : undefined;
291
+ let needBalanced: N | undefined = undefined,
291
292
  orgCurrent = curr;
292
293
 
293
294
  if (curr.count > 1 && !ignoreCount) {
@@ -307,7 +308,7 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
307
308
  needBalanced = parent;
308
309
  }
309
310
  } else {
310
- const leftSubTreeRightMost = curr.left ? this.getRightMost(curr.left) : null;
311
+ const leftSubTreeRightMost = curr.left ? this.getRightMost(curr.left) : undefined;
311
312
  if (leftSubTreeRightMost) {
312
313
  const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
313
314
  orgCurrent = this._swap(curr, leftSubTreeRightMost);
@@ -64,7 +64,8 @@ export abstract class AbstractGraph<
64
64
  E = any,
65
65
  VO extends AbstractVertex<V> = AbstractVertex<V>,
66
66
  EO extends AbstractEdge<E> = AbstractEdge<E>
67
- > implements IGraph<V, E, VO, EO> {
67
+ > implements IGraph<V, E, VO, EO>
68
+ {
68
69
  protected _vertices: Map<VertexKey, VO> = new Map<VertexKey, VO>();
69
70
 
70
71
  get vertices(): Map<VertexKey, VO> {
@@ -234,7 +235,7 @@ export abstract class AbstractGraph<
234
235
  return [];
235
236
  }
236
237
 
237
- const stack: { vertex: VO, path: VO[] }[] = [];
238
+ const stack: {vertex: VO; path: VO[]}[] = [];
238
239
  stack.push({vertex: vertex1, path: [vertex1]});
239
240
 
240
241
  while (stack.length > 0) {
@@ -256,7 +257,6 @@ export abstract class AbstractGraph<
256
257
  return paths;
257
258
  }
258
259
 
259
-
260
260
  /**
261
261
  * The function calculates the sum of weights along a given path.
262
262
  * @param {VO[]} path - An array of vertices (VO) representing a path in a graph.
@@ -366,7 +366,6 @@ export abstract class AbstractGraph<
366
366
  } else {
367
367
  return this.dijkstra(v1, v2, true, true)?.minPath ?? [];
368
368
  }
369
-
370
369
  } else {
371
370
  // DFS
372
371
  let minPath: VO[] = [];
@@ -519,14 +518,14 @@ export abstract class AbstractGraph<
519
518
  }
520
519
 
521
520
  getMinDist &&
522
- distMap.forEach((d, v) => {
523
- if (v !== srcVertex) {
524
- if (d < minDist) {
525
- minDist = d;
526
- if (genPaths) minDest = v;
521
+ distMap.forEach((d, v) => {
522
+ if (v !== srcVertex) {
523
+ if (d < minDist) {
524
+ minDist = d;
525
+ if (genPaths) minDest = v;
526
+ }
527
527
  }
528
- }
529
- });
528
+ });
530
529
 
531
530
  genPaths && getPaths(minDest);
532
531
 
@@ -588,7 +587,7 @@ export abstract class AbstractGraph<
588
587
  if (vertexOrKey instanceof AbstractVertex) distMap.set(vertexOrKey, Infinity);
589
588
  }
590
589
 
591
- const heap = new PriorityQueue<{ key: number; value: VO }>({comparator: (a, b) => a.key - b.key});
590
+ const heap = new PriorityQueue<{key: number; value: VO}>({comparator: (a, b) => a.key - b.key});
592
591
  heap.add({key: 0, value: srcVertex});
593
592
 
594
593
  distMap.set(srcVertex, 0);
@@ -812,7 +811,7 @@ export abstract class AbstractGraph<
812
811
  * `predecessor` property is a 2D array of vertices (or `null`) representing the predecessor vertices in the shortest
813
812
  * path between vertices in the
814
813
  */
815
- floydWarshall(): { costs: number[][]; predecessor: (VO | null)[][] } {
814
+ floydWarshall(): {costs: number[][]; predecessor: (VO | null)[][]} {
816
815
  const idAndVertices = [...this._vertices];
817
816
  const n = idAndVertices.length;
818
817
 
@@ -876,7 +875,12 @@ export abstract class AbstractGraph<
876
875
  * are arrays of vertices that form cycles within the SCCs.
877
876
  * @returns The function `tarjan` returns an object with the following properties:
878
877
  */
879
- tarjan(needCutVertexes: boolean = false, needBridges: boolean = false, needSCCs: boolean = true, needCycles: boolean = false) {
878
+ tarjan(
879
+ needCutVertexes: boolean = false,
880
+ needBridges: boolean = false,
881
+ needSCCs: boolean = true,
882
+ needCycles: boolean = false
883
+ ) {
880
884
  // !! in undirected graph we will not let child visit parent when dfs
881
885
  // !! articulation point(in dfs search tree not in graph): (cur !== root && cur.has(child)) && (low(child) >= dfn(cur)) || (cur === root && cur.children() >= 2)
882
886
  // !! bridge: low(child) > dfn(cur)
@@ -24,7 +24,7 @@ export enum FamilyPosition {
24
24
 
25
25
  export type BTNKey = number;
26
26
 
27
- export type BinaryTreeDeletedResult<N> = { deleted: N | null | undefined; needBalanced: N | null };
27
+ export type BinaryTreeDeletedResult<N> = { deleted: N | null | undefined; needBalanced: N | null | undefined };
28
28
 
29
29
  export type BinaryTreeNodeNested<T> = BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
30
30
 
@@ -1,8 +1,8 @@
1
- // import {BinaryTreeOptions} from './binary-tree';
2
- // import {RBTreeNode} from '../../../data-structures';
1
+ import {RBTreeNode} from '../../../data-structures';
2
+ import {BSTOptions} from "./bst";
3
3
 
4
4
  export enum RBTNColor { RED = 1, BLACK = 0}
5
5
 
6
- // export type RBTreeNodeNested<T> = RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7
- //
8
- // export type RBTreeOptions = BinaryTreeOptions & {}
6
+ export type RBTreeNodeNested<T> = RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7
+
8
+ export type RBTreeOptions = BSTOptions & {};
@@ -107,6 +107,7 @@ const composeReport = () => {
107
107
  fs.writeFileSync(htmlFilePath, html);
108
108
  console.log(`Performance ${BOLD}${GREEN}report${END} file generated`);
109
109
  };
110
+
110
111
  function replaceMarkdownContent(startMarker: string, endMarker: string, newText: string) {
111
112
  const parentDirectory = path.resolve(__dirname, '../..'); // The path to the parent directory
112
113
  const filePath = path.join(parentDirectory, 'README.md'); // Path to README.md file
@@ -36,7 +36,6 @@ describe('AVL Tree Test', () => {
36
36
  const dfs = tree.dfs(node => node, 'in');
37
37
  expect(dfs[0].key).toBe(1);
38
38
  expect(dfs[dfs.length - 1].key).toBe(16);
39
-
40
39
  tree.perfectlyBalance();
41
40
  const bfs = tree.bfs(node => node);
42
41
  expect(tree.isPerfectlyBalanced()).toBe(true);
@@ -266,4 +265,24 @@ describe('AVLTree', () => {
266
265
 
267
266
  // You can add more specific assertions to check the tree's balance and structure.
268
267
  });
268
+
269
+ describe('BinaryTree APIs test', () => {
270
+ const avl = new AVLTree<{id: number; text: string}>();
271
+ beforeEach(() => {
272
+ avl.clear();
273
+ });
274
+
275
+ it('add', () => {
276
+ avl.add(1);
277
+ const node2 = new AVLTreeNode(2);
278
+ avl.add(node2);
279
+ const node3 = new AVLTreeNode(3, {id: 3, text: 'text3'});
280
+ avl.add(node3);
281
+ avl.add(node3, {id: 3, text: 'text33'});
282
+
283
+ const bfsRes = avl.bfs(node => node);
284
+ expect(bfsRes[0]?.key).toBe(2);
285
+ });
286
+ });
287
+
269
288
  });
@@ -1,4 +1,4 @@
1
- import {AVLTree, AVLTreeNode, BinaryTree, BinaryTreeNode, IterationType} from '../../../../src';
1
+ import {BinaryTree, BinaryTreeNode, IterationType} from '../../../../src';
2
2
  // import {isDebugTest} from '../../../config';
3
3
 
4
4
  // const isDebug = isDebugTest;
@@ -174,10 +174,14 @@ describe('BinaryTree', () => {
174
174
 
175
175
  it('should subTreeTraverse', () => {
176
176
  tree.addMany([4, 2, 6, null, 1, 3, null, 5, null, 7]);
177
- expect(tree.subTreeTraverse(node => node.key, tree.getNode(6), IterationType.ITERATIVE)).toEqual([6,3, 7]);
178
- expect(tree.subTreeTraverse(node => node.key, tree.getNode(6), IterationType.RECURSIVE)).toEqual([6,3, 7]);
179
- expect(tree.subTreeTraverse(node => node === null? null : node.key, tree.getNode(6), IterationType.ITERATIVE, true)).toEqual([6, 3, 7, null]);
180
- expect(tree.subTreeTraverse(node => node === null? null : node.key, tree.getNode(6), IterationType.RECURSIVE, true)).toEqual([6, 3, 7, null]);
177
+ expect(tree.subTreeTraverse(node => node.key, tree.getNode(6), IterationType.ITERATIVE)).toEqual([6, 3, 7]);
178
+ expect(tree.subTreeTraverse(node => node.key, tree.getNode(6), IterationType.RECURSIVE)).toEqual([6, 3, 7]);
179
+ expect(
180
+ tree.subTreeTraverse(node => (node ? node.key : null ), tree.getNode(6), IterationType.ITERATIVE, true)
181
+ ).toEqual([6, 3, 7, null]);
182
+ expect(
183
+ tree.subTreeTraverse(node => (node ? node.key : null ), tree.getNode(6), IterationType.RECURSIVE, true)
184
+ ).toEqual([6, 3, 7, null]);
181
185
  });
182
186
 
183
187
  it('should clear the tree', () => {
@@ -189,7 +193,7 @@ describe('BinaryTree', () => {
189
193
  tree.clear();
190
194
 
191
195
  expect(tree.size).toBe(0);
192
- expect(tree.root).toBeNull();
196
+ expect(tree.root).toBeUndefined();
193
197
  });
194
198
  });
195
199
 
@@ -244,41 +248,38 @@ describe('BinaryTree Morris Traversal', () => {
244
248
  });
245
249
  });
246
250
 
247
- describe('BinaryTree APIs test', () => {
248
- const avl = new AVLTree<{id: number; text: string}>();
249
- beforeEach(() => {
250
- avl.clear();
251
- });
252
-
253
- it('add', () => {
254
- avl.add(1);
255
- const node2 = new AVLTreeNode(2);
256
- avl.add(node2);
257
- const node3 = new AVLTreeNode(3, {id: 3, text: 'text3'});
258
- avl.add(node3);
259
- avl.add(node3, {id: 3, text: 'text33'});
260
-
261
- const bfsRes = avl.bfs(node => node);
262
- expect(bfsRes[0]?.key).toBe(2);
263
- });
264
- });
265
-
266
251
  describe('BinaryTree traversals', () => {
267
252
  const tree = new BinaryTree<number>();
268
253
 
269
254
  const arr = [35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55];
270
255
  tree.refill(arr);
271
- expect(tree.bfs(node => node , tree.root, IterationType.ITERATIVE, true).map(node => node === null ? null : node.key)).toEqual([35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55]);
272
- expect(tree.bfs(node => node , tree.root, IterationType.RECURSIVE, true).map(node => node === null ? null : node.key)).toEqual([35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55]);
273
- expect(tree.bfs(node => node , tree.root, IterationType.ITERATIVE).map(node => node === null ? null : node.key)).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
274
- expect(tree.bfs(node => node , tree.root, IterationType.RECURSIVE).map(node => node === null ? null : node.key)).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
256
+ expect(
257
+ tree.bfs(node => node, tree.root, IterationType.ITERATIVE, true).map(node => (node ? node.key : null ))
258
+ ).toEqual([35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55]);
259
+ expect(
260
+ tree.bfs(node => node, tree.root, IterationType.RECURSIVE, true).map(node => (node ? node.key : null ))
261
+ ).toEqual([35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55]);
262
+ expect(
263
+ tree.bfs(node => node, tree.root, IterationType.ITERATIVE).map(node => (node === null ? null : node.key))
264
+ ).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
265
+ expect(
266
+ tree.bfs(node => node, tree.root, IterationType.RECURSIVE).map(node => (node === null ? null : node.key))
267
+ ).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
275
268
 
276
269
  expect(tree.dfs(node => node.key, 'pre')).toEqual([35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55]);
277
270
  expect(tree.dfs(node => node.key, 'pre', tree.root, IterationType.RECURSIVE)).toEqual([
278
271
  35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55
279
272
  ]);
280
- expect(tree.dfs(node => node, 'pre', tree.root, IterationType.ITERATIVE, true).map(node => node === null ? null : node.key)).toEqual([35, 20, 15, null, 16, 29, 28, 30, 40, null, 50, 45, 55]);
281
- expect(tree.dfs(node => node, 'pre', tree.root, IterationType.RECURSIVE, true).map(node => node === null ? null : node.key)).toEqual([35, 20, 15, null, 16, 29, 28, 30, 40, null, 50, 45, 55]);
273
+ expect(
274
+ tree
275
+ .dfs(node => node, 'pre', tree.root, IterationType.ITERATIVE, true)
276
+ .map(node => (node ? node.key : null ))
277
+ ).toEqual([35, 20, 15, null, 16, 29, 28, 30, 40, null, 50, 45, 55]);
278
+ expect(
279
+ tree
280
+ .dfs(node => node, 'pre', tree.root, IterationType.RECURSIVE, true)
281
+ .map(node => (node ? node.key : null ))
282
+ ).toEqual([35, 20, 15, null, 16, 29, 28, 30, 40, null, 50, 45, 55]);
282
283
 
283
284
  expect(tree.dfs(node => node.key, 'in')).toEqual([15, 16, 20, 28, 29, 30, 35, 40, 45, 50, 55]);
284
285
  expect(tree.dfs(node => node.key, 'post')).toEqual([16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35]);
@@ -300,21 +301,20 @@ describe('BinaryTree traversals', () => {
300
301
  [15, 29, 50],
301
302
  [16, 28, 30, 45, 55]
302
303
  ]);
303
- expect(tree.listLevels(node => node === null ? null :node.key, tree.root, IterationType.ITERATIVE, true)).toEqual([
304
+ expect(tree.listLevels(node => (node ? node.key : null ), tree.root, IterationType.ITERATIVE, true)).toEqual([
304
305
  [35],
305
306
  [20, 40],
306
- [15, 29, null,50],
307
+ [15, 29, null, 50],
307
308
  [null, 16, 28, 30, 45, 55]
308
309
  ]);
309
- expect(tree.listLevels(node => node === null ? null :node.key, tree.root, IterationType.RECURSIVE, true)).toEqual([
310
+ expect(tree.listLevels(node => ( node ? node.key : null ), tree.root, IterationType.RECURSIVE, true)).toEqual([
310
311
  [35],
311
312
  [20, 40],
312
- [15, 29, null,50],
313
+ [15, 29, null, 50],
313
314
  [null, 16, 28, 30, 45, 55]
314
315
  ]);
315
316
  });
316
317
 
317
-
318
318
  describe('BinaryTree', () => {
319
319
  let tree: BinaryTree<string>;
320
320
 
@@ -329,7 +329,7 @@ describe('BinaryTree', () => {
329
329
  it('should create an empty BinaryTree', () => {
330
330
  expect(tree.size).toBe(0);
331
331
  expect(tree.isEmpty()).toBe(true);
332
- expect(tree.root).toBe(null);
332
+ expect(tree.root).toBe(undefined);
333
333
  });
334
334
 
335
335
  it('should add nodes to the tree', () => {
@@ -351,7 +351,7 @@ describe('BinaryTree', () => {
351
351
 
352
352
  expect(tree.size).toBe(0);
353
353
  expect(tree.isEmpty()).toBe(true);
354
- expect(tree.root).toBe(null);
354
+ expect(tree.root).toBe(undefined);
355
355
  });
356
356
 
357
357
  it('should get nodes by key', () => {
@@ -837,4 +837,17 @@ describe('BST Performance test', function () {
837
837
  bst.addMany([9, 8, 7, 3, 1, 2, 5, 4, 6], undefined, false);
838
838
  expect(bst.lastKey()).toBe(9);
839
839
  });
840
+
841
+ it('should subTreeTraverse, null should be ignored', () => {
842
+ const bst = new BST();
843
+ bst.addMany([4, 2, 6, 1, 3, 5, 7]);
844
+ expect(bst.subTreeTraverse(node => node.key, bst.getNode(6), IterationType.ITERATIVE)).toEqual([6, 5, 7]);
845
+ expect(bst.subTreeTraverse(node => node.key, bst.getNode(6), IterationType.RECURSIVE)).toEqual([6, 5, 7]);
846
+ expect(
847
+ bst.subTreeTraverse(node => (node?.key ?? undefined), bst.getNode(6), IterationType.ITERATIVE, true)
848
+ ).toEqual([6, 5, 7]);
849
+ expect(
850
+ bst.subTreeTraverse(node => (node?.key ?? undefined), bst.getNode(6), IterationType.RECURSIVE, true)
851
+ ).toEqual([6, 5, 7]);
852
+ });
840
853
  });