data-structure-typed 1.42.8 → 1.43.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 (108) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +18 -18
  3. package/benchmark/report.html +12 -12
  4. package/benchmark/report.json +106 -106
  5. package/dist/cjs/src/data-structures/binary-tree/avl-tree.d.ts +88 -23
  6. package/dist/cjs/src/data-structures/binary-tree/avl-tree.js +88 -23
  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 +180 -74
  9. package/dist/cjs/src/data-structures/binary-tree/binary-tree.js +415 -236
  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 +121 -66
  12. package/dist/cjs/src/data-structures/binary-tree/bst.js +121 -67
  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 +72 -5
  15. package/dist/cjs/src/data-structures/binary-tree/rb-tree.js +95 -18
  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-multimap.d.ts +82 -43
  18. package/dist/cjs/src/data-structures/binary-tree/tree-multimap.js +82 -43
  19. package/dist/cjs/src/data-structures/binary-tree/tree-multimap.js.map +1 -1
  20. package/dist/cjs/src/data-structures/graph/abstract-graph.d.ts +139 -36
  21. package/dist/cjs/src/data-structures/graph/abstract-graph.js +147 -36
  22. package/dist/cjs/src/data-structures/graph/abstract-graph.js.map +1 -1
  23. package/dist/cjs/src/data-structures/graph/directed-graph.d.ts +126 -0
  24. package/dist/cjs/src/data-structures/graph/directed-graph.js +126 -0
  25. package/dist/cjs/src/data-structures/graph/directed-graph.js.map +1 -1
  26. package/dist/cjs/src/data-structures/graph/undirected-graph.d.ts +63 -0
  27. package/dist/cjs/src/data-structures/graph/undirected-graph.js +63 -0
  28. package/dist/cjs/src/data-structures/graph/undirected-graph.js.map +1 -1
  29. package/dist/cjs/src/data-structures/heap/heap.d.ts +175 -12
  30. package/dist/cjs/src/data-structures/heap/heap.js +175 -12
  31. package/dist/cjs/src/data-structures/heap/heap.js.map +1 -1
  32. package/dist/cjs/src/data-structures/linked-list/doubly-linked-list.d.ts +203 -0
  33. package/dist/cjs/src/data-structures/linked-list/doubly-linked-list.js +203 -0
  34. package/dist/cjs/src/data-structures/linked-list/doubly-linked-list.js.map +1 -1
  35. package/dist/cjs/src/data-structures/linked-list/singly-linked-list.d.ts +182 -0
  36. package/dist/cjs/src/data-structures/linked-list/singly-linked-list.js +182 -0
  37. package/dist/cjs/src/data-structures/linked-list/singly-linked-list.js.map +1 -1
  38. package/dist/cjs/src/data-structures/linked-list/skip-linked-list.d.ts +64 -0
  39. package/dist/cjs/src/data-structures/linked-list/skip-linked-list.js +64 -0
  40. package/dist/cjs/src/data-structures/linked-list/skip-linked-list.js.map +1 -1
  41. package/dist/cjs/src/data-structures/queue/deque.d.ts +113 -3
  42. package/dist/cjs/src/data-structures/queue/deque.js +113 -3
  43. package/dist/cjs/src/data-structures/queue/deque.js.map +1 -1
  44. package/dist/cjs/src/data-structures/queue/queue.d.ts +87 -0
  45. package/dist/cjs/src/data-structures/queue/queue.js +87 -0
  46. package/dist/cjs/src/data-structures/queue/queue.js.map +1 -1
  47. package/dist/cjs/src/data-structures/stack/stack.d.ts +42 -0
  48. package/dist/cjs/src/data-structures/stack/stack.js +42 -0
  49. package/dist/cjs/src/data-structures/stack/stack.js.map +1 -1
  50. package/dist/cjs/src/data-structures/trie/trie.d.ts +76 -0
  51. package/dist/cjs/src/data-structures/trie/trie.js +76 -1
  52. package/dist/cjs/src/data-structures/trie/trie.js.map +1 -1
  53. package/dist/mjs/src/data-structures/binary-tree/avl-tree.d.ts +88 -23
  54. package/dist/mjs/src/data-structures/binary-tree/avl-tree.js +88 -23
  55. package/dist/mjs/src/data-structures/binary-tree/binary-tree.d.ts +180 -74
  56. package/dist/mjs/src/data-structures/binary-tree/binary-tree.js +415 -236
  57. package/dist/mjs/src/data-structures/binary-tree/bst.d.ts +121 -66
  58. package/dist/mjs/src/data-structures/binary-tree/bst.js +121 -67
  59. package/dist/mjs/src/data-structures/binary-tree/rb-tree.d.ts +72 -5
  60. package/dist/mjs/src/data-structures/binary-tree/rb-tree.js +95 -18
  61. package/dist/mjs/src/data-structures/binary-tree/tree-multimap.d.ts +82 -43
  62. package/dist/mjs/src/data-structures/binary-tree/tree-multimap.js +82 -43
  63. package/dist/mjs/src/data-structures/graph/abstract-graph.d.ts +139 -36
  64. package/dist/mjs/src/data-structures/graph/abstract-graph.js +147 -36
  65. package/dist/mjs/src/data-structures/graph/directed-graph.d.ts +126 -0
  66. package/dist/mjs/src/data-structures/graph/directed-graph.js +126 -0
  67. package/dist/mjs/src/data-structures/graph/undirected-graph.d.ts +63 -0
  68. package/dist/mjs/src/data-structures/graph/undirected-graph.js +63 -0
  69. package/dist/mjs/src/data-structures/heap/heap.d.ts +175 -12
  70. package/dist/mjs/src/data-structures/heap/heap.js +175 -12
  71. package/dist/mjs/src/data-structures/linked-list/doubly-linked-list.d.ts +203 -0
  72. package/dist/mjs/src/data-structures/linked-list/doubly-linked-list.js +203 -0
  73. package/dist/mjs/src/data-structures/linked-list/singly-linked-list.d.ts +182 -0
  74. package/dist/mjs/src/data-structures/linked-list/singly-linked-list.js +182 -0
  75. package/dist/mjs/src/data-structures/linked-list/skip-linked-list.d.ts +64 -0
  76. package/dist/mjs/src/data-structures/linked-list/skip-linked-list.js +64 -0
  77. package/dist/mjs/src/data-structures/queue/deque.d.ts +113 -3
  78. package/dist/mjs/src/data-structures/queue/deque.js +113 -3
  79. package/dist/mjs/src/data-structures/queue/queue.d.ts +87 -0
  80. package/dist/mjs/src/data-structures/queue/queue.js +87 -0
  81. package/dist/mjs/src/data-structures/stack/stack.d.ts +42 -0
  82. package/dist/mjs/src/data-structures/stack/stack.js +42 -0
  83. package/dist/mjs/src/data-structures/trie/trie.d.ts +76 -0
  84. package/dist/mjs/src/data-structures/trie/trie.js +76 -1
  85. package/dist/umd/data-structure-typed.min.js +1 -1
  86. package/dist/umd/data-structure-typed.min.js.map +1 -1
  87. package/package.json +1 -1
  88. package/src/data-structures/binary-tree/avl-tree.ts +97 -23
  89. package/src/data-structures/binary-tree/binary-tree.ts +465 -256
  90. package/src/data-structures/binary-tree/bst.ts +130 -68
  91. package/src/data-structures/binary-tree/rb-tree.ts +106 -19
  92. package/src/data-structures/binary-tree/tree-multimap.ts +88 -44
  93. package/src/data-structures/graph/abstract-graph.ts +133 -7
  94. package/src/data-structures/graph/directed-graph.ts +145 -1
  95. package/src/data-structures/graph/undirected-graph.ts +72 -0
  96. package/src/data-structures/heap/heap.ts +201 -12
  97. package/src/data-structures/linked-list/doubly-linked-list.ts +232 -0
  98. package/src/data-structures/linked-list/singly-linked-list.ts +208 -0
  99. package/src/data-structures/linked-list/skip-linked-list.ts +74 -0
  100. package/src/data-structures/queue/deque.ts +127 -3
  101. package/src/data-structures/queue/queue.ts +99 -0
  102. package/src/data-structures/stack/stack.ts +48 -0
  103. package/src/data-structures/trie/trie.ts +87 -4
  104. package/test/integration/index.html +24 -2
  105. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +2 -1
  106. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +73 -5
  107. package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +0 -1
  108. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +0 -1
@@ -132,33 +132,40 @@ class BinaryTree {
132
132
  return new BinaryTreeNode(key, value);
133
133
  }
134
134
  /**
135
- * Add a node with the given key and value to the binary tree.
136
- * @param {BTNKey | N | null} keyOrNode - The key or node to add to the binary tree.
137
- * @param {V} value - The value for the new node (optional).
138
- * @returns {N | null | undefined} - The inserted node, or null if nothing was inserted, or undefined if the operation failed.
135
+ * Time Complexity: O(n)
136
+ * Space Complexity: O(1)
137
+ * Comments: The time complexity for adding a node depends on the depth of the tree. In the best case (when the tree is empty), it's O(1). In the worst case (when the tree is a degenerate tree), it's O(n). The space complexity is constant.
138
+ */
139
+ /**
140
+ * Time Complexity: O(n)
141
+ * Space Complexity: O(1)
142
+ *
143
+ * The `add` function adds a new node with a key and value to a binary tree, or updates the value of
144
+ * an existing node with the same key.
145
+ * @param {BTNKey | N | null | undefined} keyOrNode - The `keyOrNode` parameter can be one of the
146
+ * following types:
147
+ * @param {V} [value] - The value to be associated with the key or node being added to the binary
148
+ * tree.
149
+ * @returns The function `add` returns a node (`N`) if it was successfully inserted into the binary
150
+ * tree, or `null` or `undefined` if the insertion was not successful.
139
151
  */
140
152
  add(keyOrNode, value) {
141
153
  const _bfs = (root, newNode) => {
142
154
  const queue = new queue_1.Queue([root]);
143
155
  while (queue.size > 0) {
144
156
  const cur = queue.shift();
145
- if (cur) {
146
- if (newNode && cur.key === newNode.key) {
147
- cur.value = newNode.value;
148
- return;
149
- }
150
- const inserted = this._addTo(newNode, cur);
151
- if (inserted !== undefined)
152
- return inserted;
153
- if (cur.left)
154
- queue.push(cur.left);
155
- if (cur.right)
156
- queue.push(cur.right);
157
- }
158
- else
157
+ if (newNode && cur.key === newNode.key) {
158
+ cur.value = newNode.value;
159
159
  return;
160
+ }
161
+ const inserted = this._addTo(newNode, cur);
162
+ if (inserted !== undefined)
163
+ return inserted;
164
+ if (cur.left)
165
+ queue.push(cur.left);
166
+ if (cur.right)
167
+ queue.push(cur.right);
160
168
  }
161
- return;
162
169
  };
163
170
  let inserted, needInsert;
164
171
  if (keyOrNode === null) {
@@ -189,13 +196,21 @@ class BinaryTree {
189
196
  return inserted;
190
197
  }
191
198
  /**
192
- * The `addMany` function takes an array of binary tree node IDs or nodes, and optionally an array of corresponding data
193
- * values, and adds them to the binary tree.
194
- * @param {(BTNKey | null)[] | (N | null)[]} keysOrNodes - An array of BTNKey or BinaryTreeNode
195
- * objects, or null values.
196
- * @param {V[]} [values] - The `values` parameter is an optional array of values (`V[]`) that corresponds to
197
- * the nodes or node IDs being added. It is used to set the value of each node being added. If `values` is not provided,
198
- * the value of the nodes will be `undefined`.
199
+ * Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
200
+ * Space Complexity: O(1)
201
+ */
202
+ /**
203
+ * Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
204
+ * Space Complexity: O(1)
205
+ *
206
+ * The `addMany` function takes an array of keys or nodes and an optional array of values, and adds
207
+ * each key-value pair to a data structure.
208
+ * @param {(BTNKey | N |null | undefined)[]} keysOrNodes - An array of keys or nodes to be added to
209
+ * the binary search tree. Each element can be of type `BTNKey` (a key value), `N` (a node), `null`,
210
+ * or `undefined`.
211
+ * @param {(V | undefined)[]} [values] - The `values` parameter is an optional array of values that
212
+ * correspond to the keys or nodes being added. If provided, the values will be associated with the
213
+ * keys or nodes during the add operation.
199
214
  * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
200
215
  */
201
216
  addMany(keysOrNodes, values) {
@@ -212,6 +227,13 @@ class BinaryTree {
212
227
  });
213
228
  }
214
229
  /**
230
+ * Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
231
+ * Space Complexity: O(1)
232
+ */
233
+ /**
234
+ * Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
235
+ * Space Complexity: O(1)
236
+ *
215
237
  * The `refill` function clears the binary tree and adds multiple nodes with the given IDs or nodes and optional data.
216
238
  * @param {(BTNKey | N)[]} keysOrNodes - The `keysOrNodes` parameter is an array that can contain either
217
239
  * `BTNKey` or `N` values.
@@ -225,24 +247,29 @@ class BinaryTree {
225
247
  return keysOrNodes.length === this.addMany(keysOrNodes, values).length;
226
248
  }
227
249
  /**
228
- * The `delete` function removes a node from a binary search tree and returns the deleted node along
229
- * with the parent node that needs to be balanced.
230
- * a key (`BTNKey`). If it is a key, the function will find the corresponding node in the
231
- * binary tree.
232
- * @returns an array of `BiTreeDeleteResult<N>` objects.
233
- * @param {ReturnType<C>} identifier - The `identifier` parameter is either a
234
- * `BTNKey` or a generic type `N`. It represents the property of the node that we are
235
- * searching for. It can be a specific key value or any other property of the node.
236
- * @param callback - The `callback` parameter is a function that takes a node as input and returns a
237
- * value. This value is compared with the `identifier` parameter to determine if the node should be
238
- * included in the result. The `callback` parameter has a default value of
239
- * `this._defaultOneParamCallback`, which
250
+ * Time Complexity: O(n)
251
+ * Space Complexity: O(1)
252
+ */
253
+ /**
254
+ * Time Complexity: O(n)
255
+ * Space Complexity: O(1)
256
+ *
257
+ * The function deletes a node from a binary tree and returns an array of the deleted nodes along
258
+ * with the nodes that need to be balanced.
259
+ * @param {ReturnType<C> | null | undefined} identifier - The identifier parameter is the value or
260
+ * object that you want to delete from the binary tree. It can be of any type that is compatible with
261
+ * the callback function's return type. It can also be null or undefined if you want to delete a
262
+ * specific node based on its value or object.
263
+ * @param {C} callback - The `callback` parameter is a function that is used to determine the
264
+ * identifier of the node to be deleted. It is optional and has a default value of
265
+ * `this._defaultOneParamCallback`. The `callback` function should return the identifier of the node.
266
+ * @returns an array of `BiTreeDeleteResult<N>`.
240
267
  */
241
268
  delete(identifier, callback = this._defaultOneParamCallback) {
242
269
  const deletedResult = [];
243
270
  if (!this.root)
244
271
  return deletedResult;
245
- if (identifier instanceof BinaryTreeNode)
272
+ if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
246
273
  callback = (node => node);
247
274
  const curr = this.getNode(identifier, callback);
248
275
  if (!curr)
@@ -267,16 +294,18 @@ class BinaryTree {
267
294
  }
268
295
  }
269
296
  else {
270
- const leftSubTreeRightMost = curr.left ? this.getRightMost(curr.left) : null;
271
- if (leftSubTreeRightMost) {
272
- const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
273
- orgCurrent = this._swap(curr, leftSubTreeRightMost);
274
- if (parentOfLeftSubTreeMax) {
275
- if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
276
- parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
277
- else
278
- parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left;
279
- needBalanced = parentOfLeftSubTreeMax;
297
+ if (curr.left) {
298
+ const leftSubTreeRightMost = this.getRightMost(curr.left);
299
+ if (leftSubTreeRightMost) {
300
+ const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
301
+ orgCurrent = this._swap(curr, leftSubTreeRightMost);
302
+ if (parentOfLeftSubTreeMax) {
303
+ if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
304
+ parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
305
+ else
306
+ parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left;
307
+ needBalanced = parentOfLeftSubTreeMax;
308
+ }
280
309
  }
281
310
  }
282
311
  }
@@ -285,15 +314,20 @@ class BinaryTree {
285
314
  return deletedResult;
286
315
  }
287
316
  /**
288
- * The function `getDepth` calculates the depth of a given node in a binary tree relative to a
289
- * specified root node.
290
- * @param {BTNKey | N | null | undefined} distNode - The `distNode` parameter represents the node
291
- * whose depth we want to find in the binary tree. It can be either a node object (`N`), a key value
292
- * of the node (`BTNKey`), or `null`.
293
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
294
- * starting node from which we want to calculate the depth. It can be either a node object or the key
295
- * of a node in the binary tree. If no value is provided for `beginRoot`, it defaults to the root
296
- * node of the binary tree.
317
+ * Time Complexity: O(n)
318
+ * Space Complexity: O(1)
319
+ */
320
+ /**
321
+ * Time Complexity: O(n)
322
+ * Space Complexity: O(1)
323
+ *
324
+ * The function calculates the depth of a given node in a binary tree.
325
+ * @param {BTNKey | N | null | undefined} distNode - The `distNode` parameter represents the node in
326
+ * the binary tree whose depth we want to find. It can be of type `BTNKey`, `N`, `null`, or
327
+ * `undefined`.
328
+ * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
329
+ * from which we want to calculate the depth. It can be either a `BTNKey` (binary tree node key) or
330
+ * `N` (binary tree node) or `null` or `undefined`. If no value is provided for `beginRoot
297
331
  * @returns the depth of the `distNode` relative to the `beginRoot`.
298
332
  */
299
333
  getDepth(distNode, beginRoot = this.root) {
@@ -310,15 +344,22 @@ class BinaryTree {
310
344
  return depth;
311
345
  }
312
346
  /**
313
- * The `getHeight` function calculates the maximum height of a binary tree using either recursive or
314
- * iterative approach.
347
+ * Time Complexity: O(n)
348
+ * Space Complexity: O(log n)
349
+ * Best Case - O(log n) (when using recursive iterationType), Worst Case - O(n) (when using iterative iterationType)
350
+ */
351
+ /**
352
+ * Time Complexity: O(n)
353
+ * Space Complexity: O(log n)
354
+ *
355
+ * The function `getHeight` calculates the maximum height of a binary tree using either recursive or
356
+ * iterative traversal.
315
357
  * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
316
- * starting node from which the height of the binary tree is calculated. It can be either a node
317
- * object (`N`), a key value of a node in the tree (`BTNKey`), or `null` if no starting
318
- * node is specified. If `
358
+ * starting node of the binary tree from which we want to calculate the height. It can be of type
359
+ * `BTNKey`, `N`, `null`, or `undefined`. If not provided, it defaults to `this.root`.
319
360
  * @param iterationType - The `iterationType` parameter is used to determine whether to calculate the
320
- * height of the binary tree using a recursive approach or an iterative approach. It can have two
321
- * possible values:
361
+ * height of the tree using a recursive approach or an iterative approach. It can have two possible
362
+ * values:
322
363
  * @returns the height of the binary tree.
323
364
  */
324
365
  getHeight(beginRoot = this.root, iterationType = this.iterationType) {
@@ -336,9 +377,6 @@ class BinaryTree {
336
377
  return _getMaxHeight(beginRoot);
337
378
  }
338
379
  else {
339
- if (!beginRoot) {
340
- return -1;
341
- }
342
380
  const stack = [{ node: beginRoot, depth: 0 }];
343
381
  let maxHeight = 0;
344
382
  while (stack.length > 0) {
@@ -353,11 +391,19 @@ class BinaryTree {
353
391
  }
354
392
  }
355
393
  /**
394
+ * Time Complexity: O(n)
395
+ * Space Complexity: O(log n)
396
+ * Best Case - O(log n) (when using recursive iterationType), Worst Case - O(n) (when using iterative iterationType)
397
+ */
398
+ /**
399
+ * Time Complexity: O(n)
400
+ * Space Complexity: O(log n)
401
+ *
356
402
  * The `getMinHeight` function calculates the minimum height of a binary tree using either a
357
403
  * recursive or iterative approach.
358
- * @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node from which we want to
359
- * calculate the minimum height of the tree. It is optional and defaults to the root of the tree if
360
- * not provided.
404
+ * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
405
+ * starting node of the binary tree from which we want to calculate the minimum height. It can be of
406
+ * type `BTNKey`, `N`, `null`, or `undefined`. If no value is provided, it defaults to `this.root`.
361
407
  * @param iterationType - The `iterationType` parameter is used to determine the method of iteration
362
408
  * to calculate the minimum height of a binary tree. It can have two possible values:
363
409
  * @returns The function `getMinHeight` returns the minimum height of a binary tree.
@@ -407,40 +453,54 @@ class BinaryTree {
407
453
  }
408
454
  }
409
455
  /**
456
+ * Time Complexity: O(n)
457
+ * Space Complexity: O(log n)
458
+ */
459
+ /**
460
+ * Time Complexity: O(n)
461
+ * Space Complexity: O(log n)
462
+ *
410
463
  * The function checks if a binary tree is perfectly balanced by comparing the minimum height and the
411
464
  * height of the tree.
412
- * @param {N | null | undefined} beginRoot - The parameter `beginRoot` is of type `N | null | undefined`, which means it can
413
- * either be of type `N` (representing a node in a tree) or `null` (representing an empty tree).
414
- * @returns The method is returning a boolean value.
465
+ * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
466
+ * for calculating the height and minimum height of a binary tree. It can be either a `BTNKey` (a key
467
+ * value of a binary tree node), `N` (a node of a binary tree), `null`, or `undefined`. If
468
+ * @returns a boolean value.
415
469
  */
416
470
  isPerfectlyBalanced(beginRoot = this.root) {
417
471
  return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
418
472
  }
419
473
  /**
420
- * The function `getNodes` returns an array of nodes that match a given node property, using either
421
- * recursive or iterative traversal.
422
- * @param {ReturnType<C>} identifier - The `identifier` parameter is either a
423
- * `BTNKey` or a generic type `N`. It represents the property of the node that we are
424
- * searching for. It can be a specific key value or any other property of the node.
425
- * @param callback - The `callback` parameter is a function that takes a node as input and returns a
426
- * value. This value is compared with the `identifier` parameter to determine if the node should be
427
- * included in the result. The `callback` parameter has a default value of
428
- * `this._defaultOneParamCallback`, which
429
- * @param [onlyOne=false] - A boolean value indicating whether to stop searching after finding the
430
- * first node that matches the identifier. If set to true, the function will return an array with
431
- * only one element (or an empty array if no matching node is found). If set to false (default), the
432
- * function will continue searching for all
433
- * @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node from which the
434
- * traversal of the binary tree will begin. It is optional and defaults to the root of the binary
435
- * tree.
474
+ * Time Complexity: O(n)
475
+ * Space Complexity: O(log n).
476
+ */
477
+ /**
478
+ * Time Complexity: O(n)
479
+ * Space Complexity: O(log n).
480
+ *
481
+ * The function `getNodes` retrieves nodes from a binary tree based on a given identifier and
482
+ * callback function.
483
+ * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
484
+ * that you want to search for in the binary tree. It can be of any type that is returned by the
485
+ * callback function `C`. It can also be `null` or `undefined` if you don't want to search for a
486
+ * specific value.
487
+ * @param {C} callback - The `callback` parameter is a function that takes a node of type `N` as
488
+ * input and returns a value of type `C`. It is used to determine if a node matches the given
489
+ * identifier. If no callback is provided, the `_defaultOneParamCallback` function is used as the
490
+ * default
491
+ * @param [onlyOne=false] - A boolean value indicating whether to only return the first node that
492
+ * matches the identifier. If set to true, the function will stop iterating once it finds a matching
493
+ * node and return that node. If set to false (default), the function will continue iterating and
494
+ * return all nodes that match the identifier.
495
+ * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
496
+ * starting node for the traversal. It can be either a key, a node object, or `null`/`undefined`. If
497
+ * it is `null` or `undefined`, an empty array will be returned.
436
498
  * @param iterationType - The `iterationType` parameter determines the type of iteration used to
437
499
  * traverse the binary tree. It can have two possible values:
438
- * @returns The function `getNodes` returns an array of nodes (`N[]`).
500
+ * @returns an array of nodes of type `N`.
439
501
  */
440
502
  getNodes(identifier, callback = this._defaultOneParamCallback, onlyOne = false, beginRoot = this.root, iterationType = this.iterationType) {
441
- if (!beginRoot)
442
- return [];
443
- if (identifier instanceof BinaryTreeNode)
503
+ if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
444
504
  callback = (node => node);
445
505
  beginRoot = this.ensureNotKey(beginRoot);
446
506
  if (!beginRoot)
@@ -478,48 +538,72 @@ class BinaryTree {
478
538
  return ans;
479
539
  }
480
540
  /**
481
- * The function checks if a binary tree has a node with a given property or key.
482
- * @param {BTNKey | N} identifier - The `identifier` parameter is the key or value of
483
- * the node that you want to find in the binary tree. It can be either a `BTNKey` or a
484
- * generic type `N`.
485
- * @param callback - The `callback` parameter is a function that is used to determine whether a node
486
- * matches the desired criteria. It takes a node as input and returns a boolean value indicating
487
- * whether the node matches the criteria or not. The default callback function
488
- * `this._defaultOneParamCallback` is used if no callback function is
489
- * @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
490
- * the node from which the search should begin. By default, it is set to `this.root`, which means the
491
- * search will start from the root node of the binary tree. However, you can provide a different node
492
- * as
493
- * @param iterationType - The `iterationType` parameter specifies the type of iteration to be
494
- * performed when searching for nodes in the binary tree. It can have one of the following values:
541
+ * Time Complexity: O(n)
542
+ * Space Complexity: O(log n).
543
+ */
544
+ /**
545
+ * Time Complexity: O(n)
546
+ *
547
+ * The function checks if a Binary Tree Node with a specific identifier exists in the tree.
548
+ * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
549
+ * that you want to search for in the binary tree. It can be of any type that is returned by the
550
+ * callback function `C`. It can also be `null` or `undefined` if you don't want to specify a
551
+ * specific identifier.
552
+ * @param {C} callback - The `callback` parameter is a function that will be called for each node in
553
+ * the binary tree. It is used to filter the nodes based on certain conditions. The `callback`
554
+ * function should return a boolean value indicating whether the node should be included in the
555
+ * result or not.
556
+ * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
557
+ * for the search in the binary tree. It can be specified as a `BTNKey` (a unique identifier for a
558
+ * node in the binary tree), a node object (`N`), or `null`/`undefined` to start the search from
559
+ * @param iterationType - The `iterationType` parameter is a variable that determines the type of
560
+ * iteration to be performed on the binary tree. It is used to specify whether the iteration should
561
+ * be performed in a pre-order, in-order, or post-order manner.
495
562
  * @returns a boolean value.
496
563
  */
497
564
  has(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
498
- if (identifier instanceof BinaryTreeNode)
565
+ if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
499
566
  callback = (node => node);
500
567
  return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
501
568
  }
502
569
  /**
503
- * The function `get` returns the first node in a binary tree that matches the given property or key.
504
- * @param {BTNKey | N} identifier - The `identifier` parameter is the key or value of
505
- * the node that you want to find in the binary tree. It can be either a `BTNKey` or `N`
506
- * type.
507
- * @param callback - The `callback` parameter is a function that is used to determine whether a node
508
- * matches the desired criteria. It takes a node as input and returns a boolean value indicating
509
- * whether the node matches the criteria or not. The default callback function
510
- * (`this._defaultOneParamCallback`) is used if no callback function is
511
- * @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
512
- * the root node from which the search should begin.
513
- * @param iterationType - The `iterationType` parameter specifies the type of iteration to be
514
- * performed when searching for a node in the binary tree. It can have one of the following values:
515
- * @returns either the found node (of type N) or null if no node is found.
570
+ * Time Complexity: O(n)
571
+ * Space Complexity: O(log n)
572
+ */
573
+ /**
574
+ * Time Complexity: O(n)
575
+ * Space Complexity: O(log n)
576
+ *
577
+ * The function `getNode` returns the first node that matches the given identifier and callback
578
+ * function.
579
+ * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
580
+ * used to identify the node you want to retrieve. It can be of any type that is returned by the
581
+ * callback function `C`. It can also be `null` or `undefined` if you don't have a specific
582
+ * identifier.
583
+ * @param {C} callback - The `callback` parameter is a function that will be called for each node in
584
+ * the binary tree. It is used to determine if a node matches the given identifier. The `callback`
585
+ * function should take a single parameter of type `N` (the type of the nodes in the binary tree) and
586
+ * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
587
+ * for searching the binary tree. It can be either a key value, a node object, or `null`/`undefined`.
588
+ * If `null` or `undefined` is passed, the search will start from the root of the binary tree.
589
+ * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
590
+ * be performed when searching for nodes in the binary tree. It determines the order in which the
591
+ * nodes are visited during the search.
592
+ * @returns a value of type `N | null | undefined`.
516
593
  */
517
594
  getNode(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
518
- if (identifier instanceof BinaryTreeNode)
595
+ if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
519
596
  callback = (node => node);
520
597
  return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;
521
598
  }
522
599
  /**
600
+ * Time Complexity: O(n)
601
+ * Space Complexity: O(log n)
602
+ */
603
+ /**
604
+ * Time Complexity: O(n)
605
+ * Space Complexity: O(log n)
606
+ *
523
607
  * The function `getNodeByKey` searches for a node in a binary tree by its key, using either
524
608
  * recursive or iterative iteration.
525
609
  * @param {BTNKey} key - The `key` parameter is the key value that we are searching for in the tree.
@@ -574,22 +658,33 @@ class BinaryTree {
574
658
  return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key;
575
659
  }
576
660
  /**
577
- * The function `get` returns the first node value in a binary tree that matches the given property or key.
578
- * @param {BTNKey | N} identifier - The `identifier` parameter is the key or value of
579
- * the node that you want to find in the binary tree. It can be either a `BTNKey` or `N`
580
- * type.
581
- * @param callback - The `callback` parameter is a function that is used to determine whether a node
582
- * matches the desired criteria. It takes a node as input and returns a boolean value indicating
583
- * whether the node matches the criteria or not. The default callback function
584
- * (`this._defaultOneParamCallback`) is used if no callback function is
585
- * @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
586
- * the root node from which the search should begin.
587
- * @param iterationType - The `iterationType` parameter specifies the type of iteration to be
588
- * performed when searching for a node in the binary tree. It can have one of the following values:
589
- * @returns either the found value (of type V) or undefined if no node value is found.
661
+ * Time Complexity: O(n)
662
+ * Space Complexity: O(log n)
663
+ */
664
+ /**
665
+ * Time Complexity: O(n)
666
+ * Space Complexity: O(log n)
667
+ *
668
+ * The function `get` retrieves the value of a node in a binary tree based on the provided identifier
669
+ * and callback function.
670
+ * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
671
+ * used to identify the node in the binary tree. It can be of any type that is the return type of the
672
+ * callback function `C`. It can also be `null` or `undefined` if no identifier is provided.
673
+ * @param {C} callback - The `callback` parameter is a function that will be called with each node in
674
+ * the binary tree. It is used to determine whether a node matches the given identifier. The callback
675
+ * function should return a value that can be compared to the identifier to determine if it is a
676
+ * match.
677
+ * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
678
+ * for the search in the binary tree. It can be specified as a `BTNKey` (a unique identifier for a
679
+ * node), a node object of type `N`, or `null`/`undefined` to start the search from the root of
680
+ * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
681
+ * be performed when searching for a node in the binary tree. It is an optional parameter with a
682
+ * default value specified by `this.iterationType`.
683
+ * @returns The value of the node with the given identifier is being returned. If the node is not
684
+ * found, `undefined` is returned.
590
685
  */
591
686
  get(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
592
- if (identifier instanceof BinaryTreeNode)
687
+ if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
593
688
  callback = (node => node);
594
689
  return this.getNode(identifier, callback, beginRoot, iterationType)?.value ?? undefined;
595
690
  }
@@ -608,14 +703,22 @@ class BinaryTree {
608
703
  return this.size === 0;
609
704
  }
610
705
  /**
611
- * The function `getPathToRoot` returns an array of nodes starting from a given node and traversing
612
- * up to the root node, with the option to reverse the order of the nodes.
613
- * @param {N} beginRoot - The `beginRoot` parameter represents the starting node from which you want
614
- * to find the path to the root node.
706
+ * Time Complexity: O(log n)
707
+ * Space Complexity: O(log n)
708
+ */
709
+ /**
710
+ * Time Complexity: O(log n)
711
+ * Space Complexity: O(log n)
712
+ *
713
+ * The function `getPathToRoot` returns an array of nodes from a given node to the root of a tree
714
+ * structure, with the option to reverse the order of the nodes.
715
+ * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
716
+ * starting node from which you want to find the path to the root. It can be of type `BTNKey`, `N`,
717
+ * `null`, or `undefined`.
615
718
  * @param [isReverse=true] - The `isReverse` parameter is a boolean flag that determines whether the
616
719
  * resulting path should be reversed or not. If `isReverse` is set to `true`, the path will be
617
- * reversed before returning it. If `isReverse` is set to `false` or not provided, the path will
618
- * @returns The function `getPathToRoot` returns an array of type `N[]`.
720
+ * reversed before returning it. If `isReverse` is set to `false`, the path will be returned as is
721
+ * @returns The function `getPathToRoot` returns an array of nodes (`N[]`).
619
722
  */
620
723
  getPathToRoot(beginRoot, isReverse = true) {
621
724
  // TODO to support get path through passing key
@@ -633,15 +736,22 @@ class BinaryTree {
633
736
  return isReverse ? result.reverse() : result;
634
737
  }
635
738
  /**
636
- * The function `getLeftMost` returns the leftmost node in a binary tree, either using recursive or
637
- * iterative traversal.
739
+ * Time Complexity: O(log n)
740
+ * Space Complexity: O(1)
741
+ */
742
+ /**
743
+ * Time Complexity: O(log n)
744
+ * Space Complexity: O(1)
745
+ *
746
+ * The function `getLeftMost` returns the leftmost node in a binary tree, either recursively or
747
+ * iteratively.
638
748
  * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
639
- * for finding the leftmost node in a binary tree. It can be either a node object (`N`), a key value
640
- * of a node (`BTNKey`), or `null` if the tree is empty.
749
+ * for finding the leftmost node in a binary tree. It can be either a `BTNKey` (a key value), `N` (a
750
+ * node), `null`, or `undefined`. If not provided, it defaults to `this.root`,
641
751
  * @param iterationType - The `iterationType` parameter is used to determine the type of iteration to
642
752
  * be performed when finding the leftmost node in a binary tree. It can have two possible values:
643
- * @returns The function `getLeftMost` returns the leftmost node (`N`) in a binary tree. If there is
644
- * no leftmost node, it returns `null`.
753
+ * @returns The function `getLeftMost` returns the leftmost node (`N`) in the binary tree. If there
754
+ * is no leftmost node, it returns `null` or `undefined` depending on the input.
645
755
  */
646
756
  getLeftMost(beginRoot = this.root, iterationType = this.iterationType) {
647
757
  beginRoot = this.ensureNotKey(beginRoot);
@@ -666,15 +776,23 @@ class BinaryTree {
666
776
  }
667
777
  }
668
778
  /**
779
+ * Time Complexity: O(log n)
780
+ * Space Complexity: O(1)
781
+ */
782
+ /**
783
+ * Time Complexity: O(log n)
784
+ * Space Complexity: O(1)
785
+ *
669
786
  * The function `getRightMost` returns the rightmost node in a binary tree, either recursively or
670
787
  * iteratively.
671
- * @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node from which we want to
672
- * find the rightmost node. It is of type `N | null | undefined`, which means it can either be a node of type `N`
673
- * or `null`. If it is `null`, it means there is no starting node
674
- * @param iterationType - The `iterationType` parameter is used to determine the type of iteration to
675
- * be performed when finding the rightmost node in a binary tree. It can have two possible values:
676
- * @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If the
677
- * `beginRoot` parameter is `null`, it returns `null`.
788
+ * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
789
+ * starting node from which we want to find the rightmost node. It can be of type `BTNKey`, `N`,
790
+ * `null`, or `undefined`. If not provided, it defaults to `this.root`, which is a property of the
791
+ * current object.
792
+ * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
793
+ * type of iteration to use when finding the rightmost node. It can have one of two values:
794
+ * @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If there
795
+ * is no rightmost node, it returns `null` or `undefined`, depending on the input.
678
796
  */
679
797
  getRightMost(beginRoot = this.root, iterationType = this.iterationType) {
680
798
  // TODO support get right most by passing key in
@@ -700,13 +818,20 @@ class BinaryTree {
700
818
  }
701
819
  }
702
820
  /**
821
+ * Time Complexity: O(n)
822
+ * Space Complexity: O(1)
823
+ */
824
+ /**
825
+ * Time Complexity: O(n)
826
+ * Space Complexity: O(1)
827
+ *
703
828
  * The function `isSubtreeBST` checks if a given binary tree is a valid binary search tree.
704
- * @param {N} beginRoot - The `beginRoot` parameter is the root node of the binary tree that you want
705
- * to check if it is a binary search tree (BST) subtree.
829
+ * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the root
830
+ * node of the binary search tree (BST) that you want to check if it is a subtree of another BST.
706
831
  * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
707
832
  * type of iteration to use when checking if a subtree is a binary search tree (BST). It can have two
708
833
  * possible values:
709
- * @returns The function `isSubtreeBST` returns a boolean value.
834
+ * @returns a boolean value.
710
835
  */
711
836
  isSubtreeBST(beginRoot, iterationType = this.iterationType) {
712
837
  // TODO there is a bug
@@ -741,11 +866,18 @@ class BinaryTree {
741
866
  }
742
867
  }
743
868
  /**
869
+ * Time Complexity: O(n)
870
+ * Space Complexity: O(1)
871
+ */
872
+ /**
873
+ * Time Complexity: O(n)
874
+ * Space Complexity: O(1)
875
+ *
744
876
  * The function checks if a binary tree is a binary search tree.
745
877
  * @param iterationType - The parameter "iterationType" is used to specify the type of iteration to
746
878
  * be used when checking if the binary tree is a binary search tree (BST). It is an optional
747
- * parameter with a default value of "this.iterationType". The value of "this.iterationType" is not
748
- * provided in
879
+ * parameter with a default value of "this.iterationType". The value of "this.iterationType" is
880
+ * expected to be
749
881
  * @returns a boolean value.
750
882
  */
751
883
  isBST(iterationType = this.iterationType) {
@@ -754,19 +886,30 @@ class BinaryTree {
754
886
  return this.isSubtreeBST(this.root, iterationType);
755
887
  }
756
888
  /**
889
+ * Time complexity: O(n)
890
+ * Space complexity: O(log n)
891
+ */
892
+ /**
893
+ * Time complexity: O(n)
894
+ * Space complexity: O(log n)
895
+ *
757
896
  * The function `subTreeTraverse` traverses a binary tree and applies a callback function to each
758
897
  * node, either recursively or iteratively.
759
- * @param callback - The `callback` parameter is a function that will be called on each node in the
760
- * subtree traversal. It takes a single argument, which is the current node being traversed, and
761
- * returns a value. The return values from each callback invocation will be collected and returned as
762
- * an array.
763
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
764
- * for traversing the subtree. It can be either a node object, a key value of a node, or `null` to
765
- * start from the root of the tree.
898
+ * @param {C} callback - The `callback` parameter is a function that will be called for each node in
899
+ * the subtree traversal. It takes a single parameter, which is the current node being traversed, and
900
+ * returns a value of any type.
901
+ * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
902
+ * starting node or key from which the subtree traversal should begin. It can be of type `BTNKey`,
903
+ * `N`, `null`, or `undefined`. If not provided, the `root` property of the current object is used as
904
+ * the default value.
766
905
  * @param iterationType - The `iterationType` parameter determines the type of traversal to be
767
- * performed on the binary tree. It can have two possible values:
768
- * @param includeNull - The choice to output null values during binary tree traversal should be provided.
769
- * @returns The function `subTreeTraverse` returns an array of `ReturnType<BTNCallback<N>>`.
906
+ * performed on the subtree. It can have two possible values:
907
+ * @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines
908
+ * whether or not to include null values in the traversal. If `includeNull` is set to `true`, the
909
+ * traversal will include null values, otherwise it will skip them.
910
+ * @returns The function `subTreeTraverse` returns an array of values that are the result of invoking
911
+ * the `callback` function on each node in the subtree. The type of the array elements is determined
912
+ * by the return type of the `callback` function.
770
913
  */
771
914
  subTreeTraverse(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
772
915
  beginRoot = this.ensureNotKey(beginRoot);
@@ -843,20 +986,31 @@ class BinaryTree {
843
986
  return typeof potentialKey === 'number';
844
987
  }
845
988
  /**
846
- * The `dfs` function performs a depth-first search traversal on a binary tree, executing a callback
847
- * function on each node according to a specified order pattern.
848
- * @param callback - The `callback` parameter is a function that will be called on each node during
849
- * the depth-first search traversal. It takes a node as input and returns a value. The default value
850
- * is `this._defaultOneParamCallback`, which is a callback function defined elsewhere in the code.
989
+ * Time complexity: O(n)
990
+ * Space complexity: O(n)
991
+ */
992
+ /**
993
+ * Time complexity: O(n)
994
+ * Space complexity: O(n)
995
+ *
996
+ * The `dfs` function performs a depth-first search traversal on a binary tree or graph, based on the
997
+ * specified pattern and iteration type, and returns an array of values obtained from applying a
998
+ * callback function to each visited node.
999
+ * @param {C} callback - The `callback` parameter is a function that will be called for each node in
1000
+ * the tree during the depth-first search. It takes a single parameter, which can be of type `N`,
1001
+ * `null`, or `undefined`, and returns a value of any type. The default value for this parameter is
851
1002
  * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter determines the order in which the
852
- * nodes are visited during the depth-first search. There are three possible values for `pattern`:
853
- * @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node for the depth-first
854
- * search. It determines where the search will begin in the tree or graph structure. If `beginRoot`
855
- * is `null`, an empty array will be returned.
1003
+ * nodes are traversed during the depth-first search. It can have one of the following values:
1004
+ * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
1005
+ * for the depth-first search traversal. It can be specified as a key, a node object, or
1006
+ * `null`/`undefined`. If not provided, the `beginRoot` will default to the root node of the tree.
856
1007
  * @param {IterationType} iterationType - The `iterationType` parameter determines the type of
857
- * iteration used in the depth-first search algorithm. It can have two possible values:
858
- * @param includeNull - The choice to output null values during binary tree traversal should be provided.
859
- * @returns The function `dfs` returns an array of `ReturnType<BTNCallback<N>>` values.
1008
+ * iteration to use when traversing the tree. It can have one of the following values:
1009
+ * @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines
1010
+ * whether null or undefined nodes should be included in the traversal. If `includeNull` is set to
1011
+ * `true`, null or undefined nodes will be included in the traversal. If `includeNull` is set to
1012
+ * `false`, null or undefined
1013
+ * @returns an array of values that are the return values of the callback function.
860
1014
  */
861
1015
  dfs(callback = this._defaultOneParamCallback, pattern = 'in', beginRoot = this.root, iterationType = types_1.IterationType.ITERATIVE, includeNull = false) {
862
1016
  beginRoot = this.ensureNotKey(beginRoot);
@@ -965,18 +1119,29 @@ class BinaryTree {
965
1119
  return ans;
966
1120
  }
967
1121
  /**
968
- * The bfs function performs a breadth-first search traversal on a binary tree, executing a callback
969
- * function on each node.
970
- * @param callback - The `callback` parameter is a function that will be called for each node in the
971
- * breadth-first search. It takes a node of type `N` as its argument and returns a value of type
972
- * `ReturnType<BTNCallback<N>>`. The default value for this parameter is `this._defaultOneParamCallback
973
- * @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node for the breadth-first
974
- * search. It determines from which node the search will begin. If `beginRoot` is `null`, the search
975
- * will not be performed and an empty array will be returned.
976
- * @param iterationType - The `iterationType` parameter determines the type of iteration to be used
977
- * in the breadth-first search (BFS) algorithm. It can have two possible values:
978
- * @param includeNull - The choice to output null values during binary tree traversal should be provided.
979
- * @returns The function `bfs` returns an array of `ReturnType<BTNCallback<N>>[]`.
1122
+ * Time complexity: O(n)
1123
+ * Space complexity: O(n)
1124
+ */
1125
+ /**
1126
+ * Time complexity: O(n)
1127
+ * Space complexity: O(n)
1128
+ *
1129
+ * The `bfs` function performs a breadth-first search traversal on a binary tree, executing a
1130
+ * callback function on each node.
1131
+ * @param {C} callback - The `callback` parameter is a function that will be called for each node in
1132
+ * the breadth-first search traversal. It takes a single parameter, which is the current node being
1133
+ * visited, and returns a value of any type.
1134
+ * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
1135
+ * starting node for the breadth-first search traversal. It can be specified as a key, a node object,
1136
+ * or `null`/`undefined` to indicate the root of the tree. If not provided, the `root` property of
1137
+ * the class is used as
1138
+ * @param iterationType - The `iterationType` parameter determines the type of iteration to be
1139
+ * performed during the breadth-first search (BFS). It can have two possible values:
1140
+ * @param [includeNull=false] - The `includeNull` parameter is a boolean flag that determines whether
1141
+ * or not to include null values in the breadth-first search traversal. If `includeNull` is set to
1142
+ * `true`, null values will be included in the traversal, otherwise they will be skipped.
1143
+ * @returns an array of values that are the result of invoking the callback function on each node in
1144
+ * the breadth-first traversal of a binary tree.
980
1145
  */
981
1146
  bfs(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
982
1147
  beginRoot = this.ensureNotKey(beginRoot);
@@ -1031,20 +1196,29 @@ class BinaryTree {
1031
1196
  return ans;
1032
1197
  }
1033
1198
  /**
1034
- * The `listLevels` function takes a binary tree node and a callback function, and returns an array
1035
- * of arrays representing the levels of the tree.
1036
- * @param {C} callback - The `callback` parameter is a function that will be called on each node in
1037
- * the tree. It takes a node as input and returns a value. The return type of the callback function
1038
- * is determined by the generic type `C`.
1039
- * @param {N | null | undefined} beginRoot - The `beginRoot` parameter represents the starting node of the binary tree
1040
- * traversal. It can be any node in the binary tree. If no node is provided, the traversal will start
1041
- * from the root node of the binary tree.
1042
- * @param iterationType - The `iterationType` parameter determines whether the tree traversal is done
1043
- * recursively or iteratively. It can have two possible values:
1044
- * @param includeNull - The choice to output null values during binary tree traversal should be provided.
1045
- * @returns The function `listLevels` returns an array of arrays, where each inner array represents a
1046
- * level in a binary tree. Each inner array contains the return type of the provided callback
1047
- * function `C` applied to the nodes at that level.
1199
+ * Time complexity: O(n)
1200
+ * Space complexity: O(n)
1201
+ */
1202
+ /**
1203
+ * Time complexity: O(n)
1204
+ * Space complexity: O(n)
1205
+ *
1206
+ * The `listLevels` function returns an array of arrays, where each inner array represents a level in
1207
+ * a binary tree and contains the values returned by a callback function applied to the nodes at that
1208
+ * level.
1209
+ * @param {C} callback - The `callback` parameter is a function that will be called for each node in
1210
+ * the tree. It takes a single parameter, which can be of type `N`, `null`, or `undefined`, and
1211
+ * returns a value of any type.
1212
+ * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
1213
+ * starting node for traversing the tree. It can be either a node object (`N`), a key value
1214
+ * (`BTNKey`), `null`, or `undefined`. If not provided, it defaults to the root node of the tree.
1215
+ * @param iterationType - The `iterationType` parameter determines the type of iteration to be
1216
+ * performed on the tree. It can have two possible values:
1217
+ * @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines
1218
+ * whether or not to include null values in the resulting levels. If `includeNull` is set to `true`,
1219
+ * null values will be included in the levels. If `includeNull` is set to `false`, null values will
1220
+ * be excluded
1221
+ * @returns The function `listLevels` returns a two-dimensional array of type `ReturnType<C>[][]`.
1048
1222
  */
1049
1223
  listLevels(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
1050
1224
  beginRoot = this.ensureNotKey(beginRoot);
@@ -1096,9 +1270,10 @@ class BinaryTree {
1096
1270
  return levelsNodes;
1097
1271
  }
1098
1272
  /**
1099
- * The function returns the predecessor node of a given node in a binary tree.
1100
- * @param {N} node - The parameter "node" represents a node in a binary tree.
1101
- * @returns The function `getPredecessor` returns the predecessor node of the given node `node`.
1273
+ * The function `getPredecessor` returns the predecessor node of a given node in a binary tree.
1274
+ * @param {BTNKey | N | null | undefined} node - The `node` parameter can be of type `BTNKey`, `N`,
1275
+ * `null`, or `undefined`.
1276
+ * @returns The function `getPredecessor` returns a value of type `N | undefined`.
1102
1277
  */
1103
1278
  getPredecessor(node) {
1104
1279
  node = this.ensureNotKey(node);
@@ -1118,11 +1293,10 @@ class BinaryTree {
1118
1293
  }
1119
1294
  }
1120
1295
  /**
1121
- * The function `getSuccessor` returns the next node in a binary tree given a node `x`, or `null` if
1122
- * `x` is the last node.
1123
- * @param {N} x - N - a node in a binary tree
1124
- * @returns The function `getSuccessor` returns a value of type `N` (the successor node), or `null`
1125
- * if there is no successor, or `undefined` if the input `x` is `undefined`.
1296
+ * The function `getSuccessor` returns the next node in a binary tree given a current node.
1297
+ * @param {BTNKey | N | null} [x] - The parameter `x` can be of type `BTNKey`, `N`, or `null`.
1298
+ * @returns the successor of the given node or key. The successor is the node that comes immediately
1299
+ * after the given node in the inorder traversal of the binary tree.
1126
1300
  */
1127
1301
  getSuccessor(x) {
1128
1302
  x = this.ensureNotKey(x);
@@ -1139,18 +1313,26 @@ class BinaryTree {
1139
1313
  return y;
1140
1314
  }
1141
1315
  /**
1142
- * The `morris` function performs a depth-first traversal of a binary tree using the Morris traversal
1143
- * algorithm and returns an array of values obtained by applying a callback function to each node.
1144
- * @param callback - The `callback` parameter is a function that will be called on each node in the
1145
- * tree. It takes a node of type `N` as input and returns a value of type `ReturnType<BTNCallback<N>>`. The
1146
- * default value for this parameter is `this._defaultOneParamCallback`.
1316
+ * Time complexity: O(n)
1317
+ * Space complexity: O(1)
1318
+ */
1319
+ /**
1320
+ * Time complexity: O(n)
1321
+ * Space complexity: O(1)
1322
+ * The `morris` function performs a depth-first traversal on a binary tree using the Morris traversal
1323
+ * algorithm.
1324
+ * @param {C} callback - The `callback` parameter is a function that will be called for each node in
1325
+ * the tree. It takes a single parameter of type `N` (the type of the nodes in the tree) and returns
1326
+ * a value of any type.
1147
1327
  * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter in the `morris` function
1148
1328
  * determines the order in which the nodes of a binary tree are traversed. It can have one of the
1149
1329
  * following values:
1150
- * @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node for the Morris
1151
- * traversal. It specifies the root node of the tree from which the traversal should begin. If
1152
- * `beginRoot` is `null`, an empty array will be returned.
1153
- * @returns The `morris` function returns an array of `ReturnType<BTNCallback<N>>` values.
1330
+ * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
1331
+ * for the traversal. It can be specified as a key, a node object, or `null`/`undefined` to indicate
1332
+ * the root of the tree. If no value is provided, the default value is the root of the tree.
1333
+ * @returns The function `morris` returns an array of values that are the result of invoking the
1334
+ * `callback` function on each node in the binary tree. The type of the array elements is determined
1335
+ * by the return type of the `callback` function.
1154
1336
  */
1155
1337
  morris(callback = this._defaultOneParamCallback, pattern = 'in', beginRoot = this.root) {
1156
1338
  beginRoot = this.ensureNotKey(beginRoot);
@@ -1237,7 +1419,6 @@ class BinaryTree {
1237
1419
  }
1238
1420
  return ans;
1239
1421
  }
1240
- // --- start additional methods ---
1241
1422
  /**
1242
1423
  * The above function is an iterator for a binary tree that can be used to traverse the tree in
1243
1424
  * either an iterative or recursive manner.
@@ -1268,12 +1449,10 @@ class BinaryTree {
1268
1449
  }
1269
1450
  else {
1270
1451
  if (node.left) {
1271
- // @ts-ignore
1272
1452
  yield* this[Symbol.iterator](node.left);
1273
1453
  }
1274
1454
  yield node.key;
1275
1455
  if (node.right) {
1276
- // @ts-ignore
1277
1456
  yield* this[Symbol.iterator](node.right);
1278
1457
  }
1279
1458
  }
@@ -1354,9 +1533,9 @@ class BinaryTree {
1354
1533
  }
1355
1534
  /**
1356
1535
  * The `print` function is used to display a binary tree structure in a visually appealing way.
1357
- * @param {N | null | undefined} root - The `root` parameter in the `print` function represents the
1358
- * root node of a binary tree. It can have one of the following types: `BTNKey`, `N`, `null`, or
1359
- * `undefined`. The default value is `this.root`, which suggests that `this.root` is the
1536
+ * @param {N | null | undefined} root - The `root` parameter is of type `BTNKey | N | null |
1537
+ * undefined`. It represents the root node of a binary tree. The root node can have one of the
1538
+ * following types:
1360
1539
  */
1361
1540
  print(beginRoot = this.root) {
1362
1541
  beginRoot = this.ensureNotKey(beginRoot);
@@ -1369,17 +1548,17 @@ class BinaryTree {
1369
1548
  }
1370
1549
  };
1371
1550
  const _displayAux = (node) => {
1372
- if (node === undefined || node === null) {
1551
+ if (!this.isRealNode(node)) {
1373
1552
  return [[], 0, 0, 0];
1374
1553
  }
1375
- if (node && node.right === undefined && node.left === undefined) {
1554
+ if (this.isRealNode(node) && !this.isRealNode(node.right) && !this.isRealNode(node.left)) {
1376
1555
  const line = `${node.key}`;
1377
1556
  const width = line.length;
1378
1557
  const height = 1;
1379
1558
  const middle = Math.floor(width / 2);
1380
1559
  return [[line], width, height, middle];
1381
1560
  }
1382
- if (node && node.right === undefined) {
1561
+ if (this.isRealNode(node) && !this.isRealNode(node.right)) {
1383
1562
  const [lines, n, p, x] = _displayAux(node.left);
1384
1563
  const s = `${node.key}`;
1385
1564
  const u = s.length;
@@ -1388,7 +1567,7 @@ class BinaryTree {
1388
1567
  const shifted_lines = lines.map(line => line + ' '.repeat(u));
1389
1568
  return [[first_line, second_line, ...shifted_lines], n + u, p + 2, n + Math.floor(u / 2)];
1390
1569
  }
1391
- if (node && node.left === undefined) {
1570
+ if (this.isRealNode(node) && !this.isRealNode(node.left)) {
1392
1571
  const [lines, n, p, u] = _displayAux(node.right);
1393
1572
  const s = `${node.key}`;
1394
1573
  const x = s.length;