avl-tree-typed 1.49.4 → 1.49.6

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 (69) hide show
  1. package/dist/data-structures/base/iterable-base.d.ts +1 -1
  2. package/dist/data-structures/binary-tree/avl-tree.d.ts +53 -48
  3. package/dist/data-structures/binary-tree/avl-tree.js +55 -49
  4. package/dist/data-structures/binary-tree/binary-tree.d.ts +154 -143
  5. package/dist/data-structures/binary-tree/binary-tree.js +211 -198
  6. package/dist/data-structures/binary-tree/bst.d.ts +83 -71
  7. package/dist/data-structures/binary-tree/bst.js +113 -89
  8. package/dist/data-structures/binary-tree/rb-tree.d.ts +37 -35
  9. package/dist/data-structures/binary-tree/rb-tree.js +62 -59
  10. package/dist/data-structures/binary-tree/tree-multimap.d.ts +46 -55
  11. package/dist/data-structures/binary-tree/tree-multimap.js +59 -94
  12. package/dist/data-structures/graph/abstract-graph.d.ts +1 -1
  13. package/dist/data-structures/graph/abstract-graph.js +3 -2
  14. package/dist/data-structures/hash/hash-map.d.ts +1 -1
  15. package/dist/data-structures/hash/hash-map.js +2 -2
  16. package/dist/data-structures/heap/heap.js +2 -3
  17. package/dist/data-structures/linked-list/singly-linked-list.d.ts +2 -2
  18. package/dist/data-structures/matrix/index.d.ts +0 -2
  19. package/dist/data-structures/matrix/index.js +0 -2
  20. package/dist/data-structures/matrix/matrix.d.ts +128 -10
  21. package/dist/data-structures/matrix/matrix.js +400 -15
  22. package/dist/data-structures/queue/deque.d.ts +2 -2
  23. package/dist/data-structures/queue/deque.js +5 -7
  24. package/dist/data-structures/queue/queue.d.ts +1 -1
  25. package/dist/interfaces/binary-tree.d.ts +3 -3
  26. package/dist/types/common.d.ts +3 -3
  27. package/dist/types/common.js +2 -2
  28. package/dist/types/data-structures/base/base.d.ts +1 -1
  29. package/dist/types/data-structures/heap/heap.d.ts +1 -1
  30. package/dist/types/data-structures/priority-queue/priority-queue.d.ts +1 -1
  31. package/dist/utils/utils.d.ts +1 -0
  32. package/dist/utils/utils.js +6 -1
  33. package/package.json +2 -2
  34. package/src/data-structures/base/index.ts +1 -1
  35. package/src/data-structures/base/iterable-base.ts +7 -10
  36. package/src/data-structures/binary-tree/avl-tree.ts +73 -61
  37. package/src/data-structures/binary-tree/binary-tree.ts +301 -270
  38. package/src/data-structures/binary-tree/bst.ts +139 -115
  39. package/src/data-structures/binary-tree/rb-tree.ts +81 -73
  40. package/src/data-structures/binary-tree/tree-multimap.ts +72 -103
  41. package/src/data-structures/graph/abstract-graph.ts +13 -11
  42. package/src/data-structures/graph/directed-graph.ts +1 -3
  43. package/src/data-structures/graph/map-graph.ts +6 -1
  44. package/src/data-structures/graph/undirected-graph.ts +3 -6
  45. package/src/data-structures/hash/hash-map.ts +18 -16
  46. package/src/data-structures/heap/heap.ts +7 -10
  47. package/src/data-structures/heap/max-heap.ts +2 -1
  48. package/src/data-structures/heap/min-heap.ts +2 -1
  49. package/src/data-structures/linked-list/singly-linked-list.ts +2 -3
  50. package/src/data-structures/matrix/index.ts +0 -2
  51. package/src/data-structures/matrix/matrix.ts +442 -13
  52. package/src/data-structures/priority-queue/min-priority-queue.ts +11 -10
  53. package/src/data-structures/queue/deque.ts +18 -39
  54. package/src/data-structures/queue/queue.ts +1 -1
  55. package/src/interfaces/binary-tree.ts +9 -4
  56. package/src/types/common.ts +5 -5
  57. package/src/types/data-structures/base/base.ts +14 -3
  58. package/src/types/data-structures/base/index.ts +1 -1
  59. package/src/types/data-structures/graph/abstract-graph.ts +4 -2
  60. package/src/types/data-structures/hash/hash-map.ts +3 -3
  61. package/src/types/data-structures/heap/heap.ts +2 -2
  62. package/src/types/data-structures/priority-queue/priority-queue.ts +2 -2
  63. package/src/utils/utils.ts +7 -1
  64. package/dist/data-structures/matrix/matrix2d.d.ts +0 -107
  65. package/dist/data-structures/matrix/matrix2d.js +0 -199
  66. package/dist/data-structures/matrix/vector2d.d.ts +0 -200
  67. package/dist/data-structures/matrix/vector2d.js +0 -290
  68. package/src/data-structures/matrix/matrix2d.ts +0 -211
  69. package/src/data-structures/matrix/vector2d.ts +0 -315
@@ -14,24 +14,27 @@ import type {
14
14
  BinaryTreePrintOptions,
15
15
  BTNCallback,
16
16
  BTNEntry,
17
- BTNExemplar,
18
- BTNKeyOrNode,
19
17
  DFSOrderPattern,
20
18
  EntryCallback,
19
+ KeyOrNodeOrEntry,
21
20
  NodeDisplayLayout
22
21
  } from '../../types';
23
22
  import { FamilyPosition, IterationType } from '../../types';
24
23
  import { IBinaryTree } from '../../interfaces';
25
24
  import { trampoline } from '../../utils';
26
25
  import { Queue } from '../queue';
27
- import { IterableEntryBase } from "../base";
26
+ import { IterableEntryBase } from '../base';
28
27
 
29
28
  /**
30
29
  * Represents a node in a binary tree.
31
30
  * @template V - The type of data stored in the node.
32
31
  * @template N - The type of the family relationship in the binary tree.
33
32
  */
34
- export class BinaryTreeNode<K = any, V = any, N extends BinaryTreeNode<K, V, N> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>> {
33
+ export class BinaryTreeNode<
34
+ K = any,
35
+ V = any,
36
+ N extends BinaryTreeNode<K, V, N> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>
37
+ > {
35
38
  key: K;
36
39
 
37
40
  value?: V;
@@ -97,21 +100,26 @@ export class BinaryTreeNode<K = any, V = any, N extends BinaryTreeNode<K, V, N>
97
100
  * 5. Leaf Nodes: Nodes without children are leaves.
98
101
  */
99
102
 
100
- export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>, TREE extends BinaryTree<K, V, N, TREE> = BinaryTree<K, V, N, BinaryTreeNested<K, V, N>>> extends IterableEntryBase<K, V | undefined>
101
-
103
+ export class BinaryTree<
104
+ K = any,
105
+ V = any,
106
+ N extends BinaryTreeNode<K, V, N> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>,
107
+ TREE extends BinaryTree<K, V, N, TREE> = BinaryTree<K, V, N, BinaryTreeNested<K, V, N>>
108
+ >
109
+ extends IterableEntryBase<K, V | undefined>
102
110
  implements IBinaryTree<K, V, N, TREE> {
103
- iterationType = IterationType.ITERATIVE
111
+ iterationType = IterationType.ITERATIVE;
104
112
 
105
113
  /**
106
- * The constructor function initializes a binary tree object with optional elements and options.
107
- * @param [elements] - An optional iterable of BTNExemplar objects. These objects represent the
108
- * elements to be added to the binary tree.
114
+ * The constructor function initializes a binary tree object with optional nodes and options.
115
+ * @param [nodes] - An optional iterable of KeyOrNodeOrEntry objects. These objects represent the
116
+ * nodes to be added to the binary tree.
109
117
  * @param [options] - The `options` parameter is an optional object that can contain additional
110
118
  * configuration options for the binary tree. In this case, it is of type
111
119
  * `Partial<BinaryTreeOptions>`, which means that not all properties of `BinaryTreeOptions` are
112
120
  * required.
113
121
  */
114
- constructor(elements?: Iterable<BTNExemplar<K, V, N>>, options?: Partial<BinaryTreeOptions<K>>) {
122
+ constructor(nodes?: Iterable<KeyOrNodeOrEntry<K, V, N>>, options?: Partial<BinaryTreeOptions<K>>) {
115
123
  super();
116
124
  if (options) {
117
125
  const { iterationType, extractor } = options;
@@ -125,10 +133,10 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
125
133
 
126
134
  this._size = 0;
127
135
 
128
- if (elements) this.addMany(elements);
136
+ if (nodes) this.addMany(nodes);
129
137
  }
130
138
 
131
- protected _extractor = (key: K) => Number(key)
139
+ protected _extractor = (key: K) => Number(key);
132
140
 
133
141
  get extractor() {
134
142
  return this._extractor;
@@ -168,30 +176,21 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
168
176
  }
169
177
 
170
178
  /**
171
- * The function "isNode" checks if an exemplar is an instance of the BinaryTreeNode class.
172
- * @param exemplar - The `exemplar` parameter is a variable of type `BTNExemplar<K, V,N>`.
173
- * @returns a boolean value indicating whether the exemplar is an instance of the class N.
174
- */
175
- isNode(exemplar: BTNExemplar<K, V, N>): exemplar is N {
176
- return exemplar instanceof BinaryTreeNode;
177
- }
178
-
179
- /**
180
- * The function `exemplarToNode` converts an exemplar object into a node object.
181
- * @param exemplar - The `exemplar` parameter is of type `BTNExemplar<K, V, N>`.
179
+ * The function `exemplarToNode` converts an keyOrNodeOrEntry object into a node object.
180
+ * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter is of type `KeyOrNodeOrEntry<K, V, N>`.
182
181
  * @param {V} [value] - The `value` parameter is an optional value that can be passed to the
183
- * `exemplarToNode` function. It represents the value associated with the exemplar node. If no value
182
+ * `exemplarToNode` function. It represents the value associated with the keyOrNodeOrEntry node. If no value
184
183
  * is provided, it will be `undefined`.
185
184
  * @returns a value of type N (node), or null, or undefined.
186
185
  */
187
- exemplarToNode(exemplar: BTNExemplar<K, V, N>, value?: V): N | null | undefined {
188
- if (exemplar === undefined) return;
186
+ exemplarToNode(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, N>, value?: V): N | null | undefined {
187
+ if (keyOrNodeOrEntry === undefined) return;
189
188
 
190
189
  let node: N | null | undefined;
191
- if (exemplar === null) {
190
+ if (keyOrNodeOrEntry === null) {
192
191
  node = null;
193
- } else if (this.isEntry(exemplar)) {
194
- const [key, value] = exemplar;
192
+ } else if (this.isEntry(keyOrNodeOrEntry)) {
193
+ const [key, value] = keyOrNodeOrEntry;
195
194
  if (key === undefined) {
196
195
  return;
197
196
  } else if (key === null) {
@@ -199,24 +198,112 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
199
198
  } else {
200
199
  node = this.createNode(key, value);
201
200
  }
202
- } else if (this.isNode(exemplar)) {
203
- node = exemplar;
204
- } else if (this.isNotNodeInstance(exemplar)) {
205
- node = this.createNode(exemplar, value);
201
+ } else if (this.isNode(keyOrNodeOrEntry)) {
202
+ node = keyOrNodeOrEntry;
203
+ } else if (this.isNotNodeInstance(keyOrNodeOrEntry)) {
204
+ node = this.createNode(keyOrNodeOrEntry, value);
206
205
  } else {
207
206
  return;
208
207
  }
209
208
  return node;
210
209
  }
211
210
 
211
+ /**
212
+ * Time Complexity: O(n)
213
+ * Space Complexity: O(log n)
214
+ */
215
+
216
+ /**
217
+ * Time Complexity: O(n)
218
+ * Space Complexity: O(log n)
219
+ *
220
+ * The function `ensureNode` returns the node corresponding to the given key if it is a valid node
221
+ * key, otherwise it returns the key itself.
222
+ * @param {K | N | null | undefined} keyOrNodeOrEntry - The `key` parameter can be of type `K`, `N`,
223
+ * `null`, or `undefined`. It represents a key used to identify a node in a binary tree.
224
+ * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
225
+ * type of iteration to be used when searching for a node by key. It has a default value of
226
+ * `IterationType.ITERATIVE`.
227
+ * @returns either the node corresponding to the given key if it is a valid node key, or the key
228
+ * itself if it is not a valid node key.
229
+ */
230
+ ensureNode(
231
+ keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, N>,
232
+ iterationType = IterationType.ITERATIVE
233
+ ): N | null | undefined {
234
+ let res: N | null | undefined;
235
+ if (this.isRealNode(keyOrNodeOrEntry)) {
236
+ res = keyOrNodeOrEntry;
237
+ } else if (this.isEntry(keyOrNodeOrEntry)) {
238
+ if (keyOrNodeOrEntry[0] === null) res = null;
239
+ else if (keyOrNodeOrEntry[0] !== undefined) res = this.getNodeByKey(keyOrNodeOrEntry[0], iterationType);
240
+ } else {
241
+ if (keyOrNodeOrEntry === null) res = null;
242
+ else if (keyOrNodeOrEntry !== undefined) res = this.getNodeByKey(keyOrNodeOrEntry, iterationType);
243
+ }
244
+ return res;
245
+ }
246
+
247
+ /**
248
+ * The function "isNode" checks if an keyOrNodeOrEntry is an instance of the BinaryTreeNode class.
249
+ * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter is a variable of type `KeyOrNodeOrEntry<K, V,N>`.
250
+ * @returns a boolean value indicating whether the keyOrNodeOrEntry is an instance of the class N.
251
+ */
252
+ isNode(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, N>): keyOrNodeOrEntry is N {
253
+ return keyOrNodeOrEntry instanceof BinaryTreeNode;
254
+ }
255
+
212
256
  /**
213
257
  * The function checks if a given value is an entry in a binary tree node.
214
- * @param kne - BTNExemplar<K, V,N> - A generic type representing a node in a binary tree. It has
258
+ * @param keyOrNodeOrEntry - KeyOrNodeOrEntry<K, V,N> - A generic type representing a node in a binary tree. It has
215
259
  * two type parameters V and N, representing the value and node type respectively.
216
260
  * @returns a boolean value.
217
261
  */
218
- isEntry(kne: BTNExemplar<K, V, N>): kne is BTNEntry<K, V> {
219
- return Array.isArray(kne) && kne.length === 2;
262
+ isEntry(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, N>): keyOrNodeOrEntry is BTNEntry<K, V> {
263
+ return Array.isArray(keyOrNodeOrEntry) && keyOrNodeOrEntry.length === 2;
264
+ }
265
+
266
+ /**
267
+ * Time complexity: O(n)
268
+ * Space complexity: O(log n)
269
+ */
270
+
271
+ /**
272
+ * The function checks if a given node is a real node by verifying if it is an instance of
273
+ * BinaryTreeNode and its key is not NaN.
274
+ * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type.
275
+ * @returns a boolean value.
276
+ */
277
+ isRealNode(node: KeyOrNodeOrEntry<K, V, N>): node is N {
278
+ return node instanceof BinaryTreeNode && String(node.key) !== 'NaN';
279
+ }
280
+
281
+ /**
282
+ * The function checks if a given node is a BinaryTreeNode instance and has a key value of NaN.
283
+ * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type.
284
+ * @returns a boolean value.
285
+ */
286
+ isNIL(node: KeyOrNodeOrEntry<K, V, N>) {
287
+ return node instanceof BinaryTreeNode && String(node.key) === 'NaN';
288
+ }
289
+
290
+ /**
291
+ * The function checks if a given node is a real node or null.
292
+ * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type.
293
+ * @returns a boolean value.
294
+ */
295
+ isNodeOrNull(node: KeyOrNodeOrEntry<K, V, N>): node is N | null {
296
+ return this.isRealNode(node) || node === null;
297
+ }
298
+
299
+ /**
300
+ * The function "isNotNodeInstance" checks if a potential key is a K.
301
+ * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any
302
+ * data type.
303
+ * @returns a boolean value indicating whether the potentialKey is of type number or not.
304
+ */
305
+ isNotNodeInstance(potentialKey: KeyOrNodeOrEntry<K, V, N>): potentialKey is K {
306
+ return !(potentialKey instanceof BinaryTreeNode);
220
307
  }
221
308
 
222
309
  /**
@@ -234,15 +321,15 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
234
321
  * @param {V} [value] - The value to be inserted into the binary tree.
235
322
  * @returns The function `add` returns either a node (`N`), `null`, or `undefined`.
236
323
  */
237
- add(keyOrNodeOrEntry: BTNExemplar<K, V, N>, value?: V): N | null | undefined {
324
+ add(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, N>, value?: V): boolean {
238
325
  const newNode = this.exemplarToNode(keyOrNodeOrEntry, value);
239
- if (newNode === undefined) return;
326
+ if (newNode === undefined) return false;
240
327
 
241
328
  // If the tree is empty, directly set the new node as the root node
242
329
  if (!this.root) {
243
330
  this._root = newNode;
244
331
  this._size = 1;
245
- return newNode;
332
+ return true;
246
333
  }
247
334
 
248
335
  const queue = new Queue<N>([this.root]);
@@ -256,7 +343,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
256
343
  // Check for duplicate keys when newNode is not null
257
344
  if (newNode !== null && cur.key === newNode.key) {
258
345
  this._replaceNode(cur, newNode);
259
- return newNode; // If duplicate keys are found, no insertion is performed
346
+ return true; // If duplicate keys are found, no insertion is performed
260
347
  }
261
348
 
262
349
  // Record the first possible insertion location found
@@ -281,13 +368,12 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
281
368
  potentialParent.right = newNode;
282
369
  }
283
370
  this._size++;
284
- return newNode;
371
+ return true;
285
372
  }
286
373
 
287
- return undefined; // If the insertion position cannot be found, return undefined
374
+ return false; // If the insertion position cannot be found, return undefined
288
375
  }
289
376
 
290
-
291
377
  /**
292
378
  * Time Complexity: O(k log n) - O(k * n)
293
379
  * Space Complexity: O(1)
@@ -298,22 +384,22 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
298
384
  * Time Complexity: O(k log n) - O(k * n)
299
385
  * Space Complexity: O(1)
300
386
  *
301
- * The `addMany` function takes in a collection of nodes and an optional collection of values, and
387
+ * The `addMany` function takes in a collection of keysOrNodesOrEntries and an optional collection of values, and
302
388
  * adds each node with its corresponding value to the data structure.
303
- * @param nodes - An iterable collection of BTNExemplar objects.
389
+ * @param keysOrNodesOrEntries - An iterable collection of KeyOrNodeOrEntry objects.
304
390
  * @param [values] - An optional iterable of values that will be assigned to each node being added.
305
391
  * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
306
392
  */
307
- addMany(nodes: Iterable<BTNExemplar<K, V, N>>, values?: Iterable<V | undefined>): (N | null | undefined)[] {
393
+ addMany(keysOrNodesOrEntries: Iterable<KeyOrNodeOrEntry<K, V, N>>, values?: Iterable<V | undefined>): boolean[] {
308
394
  // TODO not sure addMany not be run multi times
309
- const inserted: (N | null | undefined)[] = [];
395
+ const inserted: boolean[] = [];
310
396
 
311
397
  let valuesIterator: Iterator<V | undefined> | undefined;
312
398
  if (values) {
313
399
  valuesIterator = values[Symbol.iterator]();
314
400
  }
315
401
 
316
- for (const kne of nodes) {
402
+ for (const keyOrNodeOrEntry of keysOrNodesOrEntries) {
317
403
  let value: V | undefined | null = undefined;
318
404
 
319
405
  if (valuesIterator) {
@@ -323,26 +409,39 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
323
409
  }
324
410
  }
325
411
 
326
- inserted.push(this.add(kne, value));
412
+ inserted.push(this.add(keyOrNodeOrEntry, value));
327
413
  }
328
414
 
329
415
  return inserted;
330
416
  }
331
417
 
332
-
333
418
  /**
334
- * Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
419
+ * Time Complexity: O(k * n)
335
420
  * Space Complexity: O(1)
421
+ * "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
336
422
  */
337
423
 
338
- refill(nodesOrKeysOrEntries: Iterable<BTNExemplar<K, V, N>>, values?: Iterable<V | undefined>): void {
424
+ /**
425
+ * Time Complexity: O(k * n)
426
+ * Space Complexity: O(1)
427
+ *
428
+ * The `refill` function clears the current data and adds new key-value pairs to the data structure.
429
+ * @param keysOrNodesOrEntries - An iterable containing keys, nodes, or entries. These can be of type
430
+ * KeyOrNodeOrEntry<K, V, N>.
431
+ * @param [values] - The `values` parameter is an optional iterable that contains the values to be
432
+ * associated with the keys or nodes or entries in the `keysOrNodesOrEntries` parameter. If provided,
433
+ * the values will be associated with the corresponding keys or nodes or entries in the
434
+ * `keysOrNodesOrEntries` iterable
435
+ */
436
+ refill(keysOrNodesOrEntries: Iterable<KeyOrNodeOrEntry<K, V, N>>, values?: Iterable<V | undefined>): void {
339
437
  this.clear();
340
- this.addMany(nodesOrKeysOrEntries, values);
438
+ this.addMany(keysOrNodesOrEntries, values);
341
439
  }
342
440
 
343
441
  /**
344
- * Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
442
+ * Time Complexity: O(k * n)
345
443
  * Space Complexity: O(1)
444
+ * "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
346
445
  */
347
446
 
348
447
  delete<C extends BTNCallback<N, K>>(identifier: K, callback?: C): BinaryTreeDeleteResult<N>[];
@@ -426,24 +525,24 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
426
525
  * Space Complexity: O(1)
427
526
  *
428
527
  * The function calculates the depth of a given node in a binary tree.
429
- * @param {K | N | null | undefined} distNode - The `distNode` parameter represents the node in
528
+ * @param {K | N | null | undefined} dist - The `dist` parameter represents the node in
430
529
  * the binary tree whose depth we want to find. It can be of type `K`, `N`, `null`, or
431
530
  * `undefined`.
432
531
  * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
433
532
  * from which we want to calculate the depth. It can be either a `K` (binary tree node key) or
434
533
  * `N` (binary tree node) or `null` or `undefined`. If no value is provided for `beginRoot
435
- * @returns the depth of the `distNode` relative to the `beginRoot`.
534
+ * @returns the depth of the `dist` relative to the `beginRoot`.
436
535
  */
437
- getDepth(distNode: BTNKeyOrNode<K, N>, beginRoot: BTNKeyOrNode<K, N> = this.root): number {
438
- distNode = this.ensureNode(distNode);
536
+ getDepth(dist: KeyOrNodeOrEntry<K, V, N>, beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root): number {
537
+ dist = this.ensureNode(dist);
439
538
  beginRoot = this.ensureNode(beginRoot);
440
539
  let depth = 0;
441
- while (distNode?.parent) {
442
- if (distNode === beginRoot) {
540
+ while (dist?.parent) {
541
+ if (dist === beginRoot) {
443
542
  return depth;
444
543
  }
445
544
  depth++;
446
- distNode = distNode.parent;
545
+ dist = dist.parent;
447
546
  }
448
547
  return depth;
449
548
  }
@@ -467,7 +566,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
467
566
  * values:
468
567
  * @returns the height of the binary tree.
469
568
  */
470
- getHeight(beginRoot: BTNKeyOrNode<K, N> = this.root, iterationType = this.iterationType): number {
569
+ getHeight(beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root, iterationType = this.iterationType): number {
471
570
  beginRoot = this.ensureNode(beginRoot);
472
571
  if (!beginRoot) return -1;
473
572
 
@@ -516,7 +615,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
516
615
  * to calculate the minimum height of a binary tree. It can have two possible values:
517
616
  * @returns The function `getMinHeight` returns the minimum height of a binary tree.
518
617
  */
519
- getMinHeight(beginRoot: BTNKeyOrNode<K, N> = this.root, iterationType = this.iterationType): number {
618
+ getMinHeight(beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root, iterationType = this.iterationType): number {
520
619
  beginRoot = this.ensureNode(beginRoot);
521
620
  if (!beginRoot) return -1;
522
621
 
@@ -576,7 +675,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
576
675
  * value of a binary tree node), `N` (a node of a binary tree), `null`, or `undefined`. If
577
676
  * @returns a boolean value.
578
677
  */
579
- isPerfectlyBalanced(beginRoot: BTNKeyOrNode<K, N> = this.root): boolean {
678
+ isPerfectlyBalanced(beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root): boolean {
580
679
  return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
581
680
  }
582
681
 
@@ -589,7 +688,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
589
688
  identifier: K,
590
689
  callback?: C,
591
690
  onlyOne?: boolean,
592
- beginRoot?: BTNKeyOrNode<K, N>,
691
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
593
692
  iterationType?: IterationType
594
693
  ): N[];
595
694
 
@@ -597,7 +696,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
597
696
  identifier: N | null | undefined,
598
697
  callback?: C,
599
698
  onlyOne?: boolean,
600
- beginRoot?: BTNKeyOrNode<K, N>,
699
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
601
700
  iterationType?: IterationType
602
701
  ): N[];
603
702
 
@@ -605,7 +704,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
605
704
  identifier: ReturnType<C>,
606
705
  callback: C,
607
706
  onlyOne?: boolean,
608
- beginRoot?: BTNKeyOrNode<K, N>,
707
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
609
708
  iterationType?: IterationType
610
709
  ): N[];
611
710
 
@@ -638,7 +737,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
638
737
  identifier: ReturnType<C> | null | undefined,
639
738
  callback: C = this._defaultOneParamCallback as C,
640
739
  onlyOne = false,
641
- beginRoot: BTNKeyOrNode<K, N> = this.root,
740
+ beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root,
642
741
  iterationType = this.iterationType
643
742
  ): N[] {
644
743
  if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
@@ -686,26 +785,27 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
686
785
  has<C extends BTNCallback<N, K>>(
687
786
  identifier: K,
688
787
  callback?: C,
689
- beginRoot?: BTNKeyOrNode<K, N>,
788
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
690
789
  iterationType?: IterationType
691
790
  ): boolean;
692
791
 
693
792
  has<C extends BTNCallback<N, N>>(
694
793
  identifier: N | null | undefined,
695
794
  callback?: C,
696
- beginRoot?: BTNKeyOrNode<K, N>,
795
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
697
796
  iterationType?: IterationType
698
797
  ): boolean;
699
798
 
700
799
  has<C extends BTNCallback<N>>(
701
800
  identifier: ReturnType<C> | null | undefined,
702
801
  callback: C,
703
- beginRoot?: BTNKeyOrNode<K, N>,
802
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
704
803
  iterationType?: IterationType
705
804
  ): boolean;
706
805
 
707
806
  /**
708
807
  * Time Complexity: O(n)
808
+ * Space Complexity: O(log n).
709
809
  *
710
810
  * The function checks if a Binary Tree Node with a specific identifier exists in the tree.
711
811
  * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
@@ -727,7 +827,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
727
827
  has<C extends BTNCallback<N>>(
728
828
  identifier: ReturnType<C> | null | undefined,
729
829
  callback: C = this._defaultOneParamCallback as C,
730
- beginRoot: BTNKeyOrNode<K, N> = this.root,
830
+ beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root,
731
831
  iterationType = this.iterationType
732
832
  ): boolean {
733
833
  if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
@@ -744,21 +844,21 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
744
844
  getNode<C extends BTNCallback<N, K>>(
745
845
  identifier: K,
746
846
  callback?: C,
747
- beginRoot?: BTNKeyOrNode<K, N>,
847
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
748
848
  iterationType?: IterationType
749
849
  ): N | null | undefined;
750
850
 
751
851
  getNode<C extends BTNCallback<N, N>>(
752
852
  identifier: N | null | undefined,
753
853
  callback?: C,
754
- beginRoot?: BTNKeyOrNode<K, N>,
854
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
755
855
  iterationType?: IterationType
756
856
  ): N | null | undefined;
757
857
 
758
858
  getNode<C extends BTNCallback<N>>(
759
859
  identifier: ReturnType<C>,
760
860
  callback: C,
761
- beginRoot?: BTNKeyOrNode<K, N>,
861
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
762
862
  iterationType?: IterationType
763
863
  ): N | null | undefined;
764
864
 
@@ -786,7 +886,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
786
886
  getNode<C extends BTNCallback<N>>(
787
887
  identifier: ReturnType<C> | null | undefined,
788
888
  callback: C = this._defaultOneParamCallback as C,
789
- beginRoot: BTNKeyOrNode<K, N> = this.root,
889
+ beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root,
790
890
  iterationType = this.iterationType
791
891
  ): N | null | undefined {
792
892
  if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
@@ -839,44 +939,24 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
839
939
  }
840
940
  }
841
941
 
842
- /**
843
- * Time Complexity: O(n)
844
- * Space Complexity: O(log n)
845
- */
846
-
847
- /**
848
- * The function `ensureNode` returns the node corresponding to the given key if it is a valid node
849
- * key, otherwise it returns the key itself.
850
- * @param {K | N | null | undefined} key - The `key` parameter can be of type `K`, `N`,
851
- * `null`, or `undefined`. It represents a key used to identify a node in a binary tree.
852
- * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
853
- * type of iteration to be used when searching for a node by key. It has a default value of
854
- * `IterationType.ITERATIVE`.
855
- * @returns either the node corresponding to the given key if it is a valid node key, or the key
856
- * itself if it is not a valid node key.
857
- */
858
- ensureNode(key: BTNKeyOrNode<K, N>, iterationType = IterationType.ITERATIVE): N | null | undefined {
859
- return this.isNotNodeInstance(key) ? this.getNodeByKey(key, iterationType) : key;
860
- }
861
-
862
942
  get<C extends BTNCallback<N, K>>(
863
943
  identifier: K,
864
944
  callback?: C,
865
- beginRoot?: BTNKeyOrNode<K, N>,
945
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
866
946
  iterationType?: IterationType
867
947
  ): V | undefined;
868
948
 
869
949
  get<C extends BTNCallback<N, N>>(
870
950
  identifier: N | null | undefined,
871
951
  callback?: C,
872
- beginRoot?: BTNKeyOrNode<K, N>,
952
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
873
953
  iterationType?: IterationType
874
954
  ): V | undefined;
875
955
 
876
956
  get<C extends BTNCallback<N>>(
877
957
  identifier: ReturnType<C>,
878
958
  callback: C,
879
- beginRoot?: BTNKeyOrNode<K, N>,
959
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
880
960
  iterationType?: IterationType
881
961
  ): V | undefined;
882
962
 
@@ -905,7 +985,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
905
985
  get<C extends BTNCallback<N>>(
906
986
  identifier: ReturnType<C> | null | undefined,
907
987
  callback: C = this._defaultOneParamCallback as C,
908
- beginRoot: BTNKeyOrNode<K, N> = this.root,
988
+ beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root,
909
989
  iterationType = this.iterationType
910
990
  ): V | undefined {
911
991
  if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
@@ -915,11 +995,14 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
915
995
  }
916
996
 
917
997
  /**
918
- * Time Complexity: O(n)
919
- * Space Complexity: O(log n)
998
+ * Time Complexity: O(1)
999
+ * Space Complexity: O(1)
920
1000
  */
921
1001
 
922
1002
  /**
1003
+ * Time Complexity: O(1)
1004
+ * Space Complexity: O(1)
1005
+ *
923
1006
  * Clear the binary tree, removing all nodes.
924
1007
  */
925
1008
  clear() {
@@ -928,6 +1011,14 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
928
1011
  }
929
1012
 
930
1013
  /**
1014
+ * Time Complexity: O(1)
1015
+ * Space Complexity: O(1)
1016
+ */
1017
+
1018
+ /**
1019
+ * Time Complexity: O(1)
1020
+ * Space Complexity: O(1)
1021
+ *
931
1022
  * Check if the binary tree is empty.
932
1023
  * @returns {boolean} - True if the binary tree is empty, false otherwise.
933
1024
  */
@@ -949,7 +1040,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
949
1040
  * reversed before returning it. If `isReverse` is set to `false`, the path will be returned as is
950
1041
  * @returns The function `getPathToRoot` returns an array of nodes (`N[]`).
951
1042
  */
952
- getPathToRoot(beginRoot: BTNKeyOrNode<K, N>, isReverse = true): N[] {
1043
+ getPathToRoot(beginRoot: KeyOrNodeOrEntry<K, V, N>, isReverse = true): N[] {
953
1044
  // TODO to support get path through passing key
954
1045
  const result: N[] = [];
955
1046
  beginRoot = this.ensureNode(beginRoot);
@@ -968,7 +1059,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
968
1059
 
969
1060
  /**
970
1061
  * Time Complexity: O(log n)
971
- * Space Complexity: O(log n)
1062
+ * Space Complexity: O(1)
972
1063
  */
973
1064
 
974
1065
  /**
@@ -986,7 +1077,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
986
1077
  * is no leftmost node, it returns `null` or `undefined` depending on the input.
987
1078
  */
988
1079
  getLeftMost(
989
- beginRoot: BTNKeyOrNode<K, N> = this.root,
1080
+ beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root,
990
1081
  iterationType = this.iterationType
991
1082
  ): N | null | undefined {
992
1083
  beginRoot = this.ensureNode(beginRoot);
@@ -1032,7 +1123,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1032
1123
  * is no rightmost node, it returns `null` or `undefined`, depending on the input.
1033
1124
  */
1034
1125
  getRightMost(
1035
- beginRoot: BTNKeyOrNode<K, N> = this.root,
1126
+ beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root,
1036
1127
  iterationType = this.iterationType
1037
1128
  ): N | null | undefined {
1038
1129
  // TODO support get right most by passing key in
@@ -1074,7 +1165,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1074
1165
  * possible values:
1075
1166
  * @returns a boolean value.
1076
1167
  */
1077
- isSubtreeBST(beginRoot: BTNKeyOrNode<K, N>, iterationType = this.iterationType): boolean {
1168
+ isBST(beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root, iterationType = this.iterationType): boolean {
1078
1169
  // TODO there is a bug
1079
1170
  beginRoot = this.ensureNode(beginRoot);
1080
1171
  if (!beginRoot) return true;
@@ -1087,69 +1178,56 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1087
1178
  return dfs(cur.left, min, numKey) && dfs(cur.right, numKey, max);
1088
1179
  };
1089
1180
 
1090
- return dfs(beginRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
1181
+ const isStandardBST = dfs(beginRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
1182
+ const isInverseBST = dfs(beginRoot, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER);
1183
+ return isStandardBST || isInverseBST;
1091
1184
  } else {
1092
- const stack = [];
1093
- let prev = Number.MIN_SAFE_INTEGER,
1094
- curr: N | null | undefined = beginRoot;
1095
- while (curr || stack.length > 0) {
1096
- while (curr) {
1097
- stack.push(curr);
1098
- curr = curr.left;
1185
+ const checkBST = (checkMax = false) => {
1186
+ const stack = [];
1187
+ let prev = checkMax ? Number.MAX_SAFE_INTEGER : Number.MIN_SAFE_INTEGER;
1188
+ // @ts-ignore
1189
+ let curr: N | null | undefined = beginRoot;
1190
+ while (curr || stack.length > 0) {
1191
+ while (curr) {
1192
+ stack.push(curr);
1193
+ curr = curr.left;
1194
+ }
1195
+ curr = stack.pop()!;
1196
+ const numKey = this.extractor(curr.key);
1197
+ if (!curr || (!checkMax && prev >= numKey) || (checkMax && prev <= numKey)) return false;
1198
+ prev = numKey;
1199
+ curr = curr.right;
1099
1200
  }
1100
- curr = stack.pop()!;
1101
- const numKey = this.extractor(curr.key);
1102
- if (!curr || prev >= numKey) return false;
1103
- prev = numKey;
1104
- curr = curr.right;
1105
- }
1106
- return true;
1201
+ return true;
1202
+ };
1203
+ const isStandardBST = checkBST(false),
1204
+ isInverseBST = checkBST(true);
1205
+ return isStandardBST || isInverseBST;
1107
1206
  }
1108
1207
  }
1109
1208
 
1110
1209
  /**
1111
- * Time Complexity: O(n)
1112
- * Space Complexity: O(1)
1113
- */
1114
-
1115
- /**
1116
- * Time Complexity: O(n)
1117
- * Space Complexity: O(1)
1118
- *
1119
- * The function checks if a binary tree is a binary search tree.
1120
- * @param iterationType - The parameter "iterationType" is used to specify the type of iteration to
1121
- * be used when checking if the binary tree is a binary search tree (BST). It is an optional
1122
- * parameter with a default value of "this.iterationType". The value of "this.iterationType" is
1123
- * expected to be
1124
- * @returns a boolean value.
1125
- */
1126
- isBST(iterationType = this.iterationType): boolean {
1127
- if (this.root === null) return true;
1128
- return this.isSubtreeBST(this.root, iterationType);
1129
- }
1130
-
1131
- /**
1132
- * Time Complexity: O(n)
1133
- * Space Complexity: O(1)
1210
+ * Time complexity: O(n)
1211
+ * Space complexity: O(log n)
1134
1212
  */
1135
1213
 
1136
1214
  subTreeTraverse<C extends BTNCallback<N>>(
1137
1215
  callback?: C,
1138
- beginRoot?: BTNKeyOrNode<K, N>,
1216
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
1139
1217
  iterationType?: IterationType,
1140
1218
  includeNull?: false
1141
1219
  ): ReturnType<C>[];
1142
1220
 
1143
1221
  subTreeTraverse<C extends BTNCallback<N>>(
1144
1222
  callback?: C,
1145
- beginRoot?: BTNKeyOrNode<K, N>,
1223
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
1146
1224
  iterationType?: IterationType,
1147
1225
  includeNull?: undefined
1148
1226
  ): ReturnType<C>[];
1149
1227
 
1150
1228
  subTreeTraverse<C extends BTNCallback<N | null | undefined>>(
1151
1229
  callback?: C,
1152
- beginRoot?: BTNKeyOrNode<K, N>,
1230
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
1153
1231
  iterationType?: IterationType,
1154
1232
  includeNull?: true
1155
1233
  ): ReturnType<C>[];
@@ -1173,12 +1251,12 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1173
1251
  * whether to include null values in the traversal. If `includeNull` is set to `true`, the
1174
1252
  * traversal will include null values, otherwise it will skip them.
1175
1253
  * @returns The function `subTreeTraverse` returns an array of values that are the result of invoking
1176
- * the `callback` function on each node in the subtree. The type of the array elements is determined
1254
+ * the `callback` function on each node in the subtree. The type of the array nodes is determined
1177
1255
  * by the return type of the `callback` function.
1178
1256
  */
1179
1257
  subTreeTraverse<C extends BTNCallback<N | null | undefined>>(
1180
1258
  callback: C = this._defaultOneParamCallback as C,
1181
- beginRoot: BTNKeyOrNode<K, N> = this.root,
1259
+ beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root,
1182
1260
  iterationType = this.iterationType,
1183
1261
  includeNull = false
1184
1262
  ): ReturnType<C>[] {
@@ -1222,53 +1300,10 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1222
1300
  return ans;
1223
1301
  }
1224
1302
 
1225
- /**
1226
- * Time complexity: O(n)
1227
- * Space complexity: O(log n)
1228
- */
1229
-
1230
- /**
1231
- * The function checks if a given node is a real node by verifying if it is an instance of
1232
- * BinaryTreeNode and its key is not NaN.
1233
- * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type.
1234
- * @returns a boolean value.
1235
- */
1236
- isRealNode(node: BTNExemplar<K, V, N>): node is N {
1237
- return node instanceof BinaryTreeNode && String(node.key) !== 'NaN';
1238
- }
1239
-
1240
- /**
1241
- * The function checks if a given node is a BinaryTreeNode instance and has a key value of NaN.
1242
- * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type.
1243
- * @returns a boolean value.
1244
- */
1245
- isNIL(node: BTNExemplar<K, V, N>) {
1246
- return node instanceof BinaryTreeNode && String(node.key) === 'NaN';
1247
- }
1248
-
1249
- /**
1250
- * The function checks if a given node is a real node or null.
1251
- * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type.
1252
- * @returns a boolean value.
1253
- */
1254
- isNodeOrNull(node: BTNExemplar<K, V, N>): node is N | null {
1255
- return this.isRealNode(node) || node === null;
1256
- }
1257
-
1258
- /**
1259
- * The function "isNotNodeInstance" checks if a potential key is a K.
1260
- * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any
1261
- * data type.
1262
- * @returns a boolean value indicating whether the potentialKey is of type number or not.
1263
- */
1264
- isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {
1265
- return !(potentialKey instanceof BinaryTreeNode)
1266
- }
1267
-
1268
1303
  dfs<C extends BTNCallback<N>>(
1269
1304
  callback?: C,
1270
1305
  pattern?: DFSOrderPattern,
1271
- beginRoot?: BTNKeyOrNode<K, N>,
1306
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
1272
1307
  iterationType?: IterationType,
1273
1308
  includeNull?: false
1274
1309
  ): ReturnType<C>[];
@@ -1276,7 +1311,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1276
1311
  dfs<C extends BTNCallback<N>>(
1277
1312
  callback?: C,
1278
1313
  pattern?: DFSOrderPattern,
1279
- beginRoot?: BTNKeyOrNode<K, N>,
1314
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
1280
1315
  iterationType?: IterationType,
1281
1316
  includeNull?: undefined
1282
1317
  ): ReturnType<C>[];
@@ -1284,7 +1319,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1284
1319
  dfs<C extends BTNCallback<N | null | undefined>>(
1285
1320
  callback?: C,
1286
1321
  pattern?: DFSOrderPattern,
1287
- beginRoot?: BTNKeyOrNode<K, N>,
1322
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
1288
1323
  iterationType?: IterationType,
1289
1324
  includeNull?: true
1290
1325
  ): ReturnType<C>[];
@@ -1315,7 +1350,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1315
1350
  dfs<C extends BTNCallback<N | null | undefined>>(
1316
1351
  callback: C = this._defaultOneParamCallback as C,
1317
1352
  pattern: DFSOrderPattern = 'in',
1318
- beginRoot: BTNKeyOrNode<K, N> = this.root,
1353
+ beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root,
1319
1354
  iterationType: IterationType = IterationType.ITERATIVE,
1320
1355
  includeNull = false
1321
1356
  ): ReturnType<C>[] {
@@ -1414,21 +1449,21 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1414
1449
 
1415
1450
  bfs<C extends BTNCallback<N>>(
1416
1451
  callback?: C,
1417
- beginRoot?: BTNKeyOrNode<K, N>,
1452
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
1418
1453
  iterationType?: IterationType,
1419
1454
  includeNull?: false
1420
1455
  ): ReturnType<C>[];
1421
1456
 
1422
1457
  bfs<C extends BTNCallback<N>>(
1423
1458
  callback?: C,
1424
- beginRoot?: BTNKeyOrNode<K, N>,
1459
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
1425
1460
  iterationType?: IterationType,
1426
1461
  includeNull?: undefined
1427
1462
  ): ReturnType<C>[];
1428
1463
 
1429
1464
  bfs<C extends BTNCallback<N | null | undefined>>(
1430
1465
  callback?: C,
1431
- beginRoot?: BTNKeyOrNode<K, N>,
1466
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
1432
1467
  iterationType?: IterationType,
1433
1468
  includeNull?: true
1434
1469
  ): ReturnType<C>[];
@@ -1456,7 +1491,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1456
1491
  */
1457
1492
  bfs<C extends BTNCallback<N | null | undefined>>(
1458
1493
  callback: C = this._defaultOneParamCallback as C,
1459
- beginRoot: BTNKeyOrNode<K, N> = this.root,
1494
+ beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root,
1460
1495
  iterationType = this.iterationType,
1461
1496
  includeNull = false
1462
1497
  ): ReturnType<C>[] {
@@ -1515,21 +1550,21 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1515
1550
 
1516
1551
  listLevels<C extends BTNCallback<N>>(
1517
1552
  callback?: C,
1518
- beginRoot?: BTNKeyOrNode<K, N>,
1553
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
1519
1554
  iterationType?: IterationType,
1520
1555
  includeNull?: false
1521
1556
  ): ReturnType<C>[][];
1522
1557
 
1523
1558
  listLevels<C extends BTNCallback<N>>(
1524
1559
  callback?: C,
1525
- beginRoot?: BTNKeyOrNode<K, N>,
1560
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
1526
1561
  iterationType?: IterationType,
1527
1562
  includeNull?: undefined
1528
1563
  ): ReturnType<C>[][];
1529
1564
 
1530
1565
  listLevels<C extends BTNCallback<N | null | undefined>>(
1531
1566
  callback?: C,
1532
- beginRoot?: BTNKeyOrNode<K, N>,
1567
+ beginRoot?: KeyOrNodeOrEntry<K, V, N>,
1533
1568
  iterationType?: IterationType,
1534
1569
  includeNull?: true
1535
1570
  ): ReturnType<C>[][];
@@ -1557,7 +1592,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1557
1592
  */
1558
1593
  listLevels<C extends BTNCallback<N | null | undefined>>(
1559
1594
  callback: C = this._defaultOneParamCallback as C,
1560
- beginRoot: BTNKeyOrNode<K, N> = this.root,
1595
+ beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root,
1561
1596
  iterationType = this.iterationType,
1562
1597
  includeNull = false
1563
1598
  ): ReturnType<C>[][] {
@@ -1637,7 +1672,6 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1637
1672
  * after the given node in the inorder traversal of the binary tree.
1638
1673
  */
1639
1674
  getSuccessor(x?: K | N | null): N | null | undefined {
1640
-
1641
1675
  x = this.ensureNode(x);
1642
1676
  if (!this.isRealNode(x)) return undefined;
1643
1677
 
@@ -1655,7 +1689,13 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1655
1689
 
1656
1690
  /**
1657
1691
  * Time complexity: O(n)
1658
- * Space complexity: O(1)
1692
+ * Space complexity: O(n)
1693
+ */
1694
+
1695
+ /**
1696
+ * Time complexity: O(n)
1697
+ * Space complexity: O(n)
1698
+ *
1659
1699
  * The `morris` function performs a depth-first traversal on a binary tree using the Morris traversal
1660
1700
  * algorithm.
1661
1701
  * @param {C} callback - The `callback` parameter is a function that will be called for each node in
@@ -1668,13 +1708,13 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1668
1708
  * for the traversal. It can be specified as a key, a node object, or `null`/`undefined` to indicate
1669
1709
  * the root of the tree. If no value is provided, the default value is the root of the tree.
1670
1710
  * @returns The function `morris` returns an array of values that are the result of invoking the
1671
- * `callback` function on each node in the binary tree. The type of the array elements is determined
1711
+ * `callback` function on each node in the binary tree. The type of the array nodes is determined
1672
1712
  * by the return type of the `callback` function.
1673
1713
  */
1674
1714
  morris<C extends BTNCallback<N>>(
1675
1715
  callback: C = this._defaultOneParamCallback as C,
1676
1716
  pattern: DFSOrderPattern = 'in',
1677
- beginRoot: BTNKeyOrNode<K, N> = this.root
1717
+ beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root
1678
1718
  ): ReturnType<C>[] {
1679
1719
  beginRoot = this.ensureNode(beginRoot);
1680
1720
  if (beginRoot === null) return [];
@@ -1785,8 +1825,8 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1785
1825
  * Time Complexity: O(n)
1786
1826
  * Space Complexity: O(n)
1787
1827
  *
1788
- * The `filter` function creates a new tree by iterating over the elements of the current tree and
1789
- * adding only the elements that satisfy the given predicate function.
1828
+ * The `filter` function creates a new tree by iterating over the nodes of the current tree and
1829
+ * adding only the nodes that satisfy the given predicate function.
1790
1830
  * @param predicate - The `predicate` parameter is a function that takes three arguments: `value`,
1791
1831
  * `key`, and `index`. It should return a boolean value indicating whether the pair should be
1792
1832
  * included in the filtered tree or not.
@@ -1847,22 +1887,33 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1847
1887
  //
1848
1888
 
1849
1889
  /**
1890
+ * Time Complexity: O(n)
1891
+ * Space Complexity: O(n)
1892
+ */
1893
+
1894
+ /**
1895
+ * Time Complexity: O(n)
1896
+ * Space Complexity: O(n)
1897
+ *
1850
1898
  * The `print` function is used to display a binary tree structure in a visually appealing way.
1851
1899
  * @param {K | N | null | undefined} [beginRoot=this.root] - The `root` parameter is of type `K | N | null |
1852
1900
  * undefined`. It represents the root node of a binary tree. The root node can have one of the
1853
1901
  * following types:
1854
1902
  * @param {BinaryTreePrintOptions} [options={ isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false}] - Options object that controls printing behavior. You can specify whether to display undefined, null, or sentinel nodes.
1855
1903
  */
1856
- print(beginRoot: BTNKeyOrNode<K, N> = this.root, options?: BinaryTreePrintOptions): void {
1904
+ print(beginRoot: KeyOrNodeOrEntry<K, V, N> = this.root, options?: BinaryTreePrintOptions): void {
1857
1905
  const opts = { isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false, ...options };
1858
1906
  beginRoot = this.ensureNode(beginRoot);
1859
1907
  if (!beginRoot) return;
1860
1908
 
1861
- if (opts.isShowUndefined) console.log(`U for undefined
1909
+ if (opts.isShowUndefined)
1910
+ console.log(`U for undefined
1862
1911
  `);
1863
- if (opts.isShowNull) console.log(`N for null
1912
+ if (opts.isShowNull)
1913
+ console.log(`N for null
1864
1914
  `);
1865
- if (opts.isShowRedBlackNIL) console.log(`S for Sentinel Node
1915
+ if (opts.isShowRedBlackNIL)
1916
+ console.log(`S for Sentinel Node
1866
1917
  `);
1867
1918
 
1868
1919
  const display = (root: N | null | undefined): void => {
@@ -1920,30 +1971,42 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1920
1971
  } else if (node !== null && node !== undefined) {
1921
1972
  // Display logic of normal nodes
1922
1973
 
1923
- const key = node.key, line = isNaN(this.extractor(key)) ? 'S' : this.extractor(key).toString(),
1974
+ const key = node.key,
1975
+ line = isNaN(this.extractor(key)) ? 'S' : this.extractor(key).toString(),
1924
1976
  width = line.length;
1925
1977
 
1926
- return _buildNodeDisplay(line, width, this._displayAux(node.left, options), this._displayAux(node.right, options))
1927
-
1978
+ return _buildNodeDisplay(
1979
+ line,
1980
+ width,
1981
+ this._displayAux(node.left, options),
1982
+ this._displayAux(node.right, options)
1983
+ );
1928
1984
  } else {
1929
1985
  // For cases where none of the conditions are met, null, undefined, and NaN nodes are not displayed
1930
- const line = node === undefined ? 'U' : 'N', width = line.length;
1986
+ const line = node === undefined ? 'U' : 'N',
1987
+ width = line.length;
1931
1988
 
1932
- return _buildNodeDisplay(line, width, [[''], 1, 0, 0], [[''], 1, 0, 0])
1989
+ return _buildNodeDisplay(line, width, [[''], 1, 0, 0], [[''], 1, 0, 0]);
1933
1990
  }
1934
1991
 
1935
1992
  function _buildNodeDisplay(line: string, width: number, left: NodeDisplayLayout, right: NodeDisplayLayout) {
1936
1993
  const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
1937
1994
  const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
1938
- const firstLine = ' '.repeat(Math.max(0, leftMiddle + 1))
1939
- + '_'.repeat(Math.max(0, leftWidth - leftMiddle - 1))
1940
- + line
1941
- + '_'.repeat(Math.max(0, rightMiddle))
1942
- + ' '.repeat(Math.max(0, rightWidth - rightMiddle));
1943
-
1944
- const secondLine = (leftHeight > 0 ? ' '.repeat(leftMiddle) + '/' + ' '.repeat(leftWidth - leftMiddle - 1) : ' '.repeat(leftWidth))
1945
- + ' '.repeat(width)
1946
- + (rightHeight > 0 ? ' '.repeat(rightMiddle) + '\\' + ' '.repeat(rightWidth - rightMiddle - 1) : ' '.repeat(rightWidth));
1995
+ const firstLine =
1996
+ ' '.repeat(Math.max(0, leftMiddle + 1)) +
1997
+ '_'.repeat(Math.max(0, leftWidth - leftMiddle - 1)) +
1998
+ line +
1999
+ '_'.repeat(Math.max(0, rightMiddle)) +
2000
+ ' '.repeat(Math.max(0, rightWidth - rightMiddle));
2001
+
2002
+ const secondLine =
2003
+ (leftHeight > 0
2004
+ ? ' '.repeat(leftMiddle) + '/' + ' '.repeat(leftWidth - leftMiddle - 1)
2005
+ : ' '.repeat(leftWidth)) +
2006
+ ' '.repeat(width) +
2007
+ (rightHeight > 0
2008
+ ? ' '.repeat(rightMiddle) + '\\' + ' '.repeat(rightWidth - rightMiddle - 1)
2009
+ : ' '.repeat(rightWidth));
1947
2010
 
1948
2011
  const mergedLines = [firstLine, secondLine];
1949
2012
 
@@ -1953,11 +2016,16 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1953
2016
  mergedLines.push(leftLine + ' '.repeat(width) + rightLine);
1954
2017
  }
1955
2018
 
1956
- return <NodeDisplayLayout>[mergedLines, leftWidth + width + rightWidth, Math.max(leftHeight, rightHeight) + 2, leftWidth + Math.floor(width / 2)];
2019
+ return <NodeDisplayLayout>[
2020
+ mergedLines,
2021
+ leftWidth + width + rightWidth,
2022
+ Math.max(leftHeight, rightHeight) + 2,
2023
+ leftWidth + Math.floor(width / 2)
2024
+ ];
1957
2025
  }
1958
2026
  }
1959
2027
 
1960
- protected _defaultOneParamCallback = (node: N | null | undefined) => node ? node.key : undefined;
2028
+ protected _defaultOneParamCallback = (node: N | null | undefined) => (node ? node.key : undefined);
1961
2029
 
1962
2030
  /**
1963
2031
  * Swap the data of two nodes in the binary tree.
@@ -1965,7 +2033,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
1965
2033
  * @param {N} destNode - The destination node to swap.
1966
2034
  * @returns {N} - The destination node after the swap.
1967
2035
  */
1968
- protected _swapProperties(srcNode: BTNKeyOrNode<K, N>, destNode: BTNKeyOrNode<K, N>): N | undefined {
2036
+ protected _swapProperties(srcNode: KeyOrNodeOrEntry<K, V, N>, destNode: KeyOrNodeOrEntry<K, V, N>): N | undefined {
1969
2037
  srcNode = this.ensureNode(srcNode);
1970
2038
  destNode = this.ensureNode(destNode);
1971
2039
 
@@ -2012,43 +2080,6 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
2012
2080
  return newNode;
2013
2081
  }
2014
2082
 
2015
- /**
2016
- * The function `_addTo` adds a new node to a binary tree if there is an available position.
2017
- * @param {N | null | undefined} newNode - The `newNode` parameter represents the node that you want to add to
2018
- * the binary tree. It can be either a node object or `null`.
2019
- * @param {N} parent - The `parent` parameter represents the parent node to which the new node will
2020
- * be added as a child.
2021
- * @returns either the left or right child node of the parent node, depending on which child is
2022
- * available for adding the new node. If a new node is added, the function also updates the size of
2023
- * the binary tree. If neither the left nor right child is available, the function returns undefined.
2024
- * If the parent node is null, the function also returns undefined.
2025
- */
2026
- protected _addTo(newNode: N | null | undefined, parent: BTNKeyOrNode<K, N>): N | null | undefined {
2027
- if (this.isNotNodeInstance(parent)) parent = this.getNode(parent);
2028
-
2029
- if (parent) {
2030
- // When all leaf nodes are null, it will no longer be possible to add new entity nodes to this binary tree.
2031
- // In this scenario, null nodes serve as "sentinel nodes," "virtual nodes," or "placeholder nodes."
2032
- if (parent.left === undefined) {
2033
- parent.left = newNode;
2034
- if (newNode) {
2035
- this._size = this.size + 1;
2036
- }
2037
- return parent.left;
2038
- } else if (parent.right === undefined) {
2039
- parent.right = newNode;
2040
- if (newNode) {
2041
- this._size = this.size + 1;
2042
- }
2043
- return parent.right;
2044
- } else {
2045
- return;
2046
- }
2047
- } else {
2048
- return;
2049
- }
2050
- }
2051
-
2052
2083
  /**
2053
2084
  * The function sets the root property of an object to a given value, and if the value is not null,
2054
2085
  * it also sets the parent property of the value to undefined.