heap-typed 1.48.2 → 1.48.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/data-structures/binary-tree/avl-tree.d.ts +16 -16
  2. package/dist/data-structures/binary-tree/avl-tree.js +7 -7
  3. package/dist/data-structures/binary-tree/binary-tree.d.ts +89 -87
  4. package/dist/data-structures/binary-tree/binary-tree.js +67 -58
  5. package/dist/data-structures/binary-tree/bst.d.ts +28 -47
  6. package/dist/data-structures/binary-tree/bst.js +54 -57
  7. package/dist/data-structures/binary-tree/rb-tree.d.ts +15 -15
  8. package/dist/data-structures/binary-tree/rb-tree.js +7 -7
  9. package/dist/data-structures/binary-tree/tree-multimap.d.ts +22 -22
  10. package/dist/data-structures/binary-tree/tree-multimap.js +11 -11
  11. package/dist/data-structures/graph/abstract-graph.d.ts +1 -0
  12. package/dist/data-structures/graph/abstract-graph.js +4 -0
  13. package/dist/data-structures/graph/directed-graph.d.ts +25 -7
  14. package/dist/data-structures/graph/directed-graph.js +58 -12
  15. package/dist/data-structures/graph/undirected-graph.d.ts +25 -6
  16. package/dist/data-structures/graph/undirected-graph.js +70 -7
  17. package/dist/interfaces/binary-tree.d.ts +6 -6
  18. package/dist/types/common.d.ts +11 -8
  19. package/dist/types/common.js +6 -1
  20. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +3 -3
  21. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +4 -4
  22. package/dist/types/data-structures/binary-tree/bst.d.ts +6 -6
  23. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +3 -3
  24. package/dist/types/data-structures/binary-tree/tree-multimap.d.ts +3 -3
  25. package/package.json +2 -2
  26. package/src/data-structures/binary-tree/avl-tree.ts +20 -21
  27. package/src/data-structures/binary-tree/binary-tree.ts +147 -136
  28. package/src/data-structures/binary-tree/bst.ts +86 -82
  29. package/src/data-structures/binary-tree/rb-tree.ts +25 -26
  30. package/src/data-structures/binary-tree/tree-multimap.ts +30 -35
  31. package/src/data-structures/graph/abstract-graph.ts +5 -0
  32. package/src/data-structures/graph/directed-graph.ts +61 -12
  33. package/src/data-structures/graph/undirected-graph.ts +75 -7
  34. package/src/interfaces/binary-tree.ts +5 -6
  35. package/src/types/common.ts +11 -8
  36. package/src/types/data-structures/binary-tree/avl-tree.ts +3 -3
  37. package/src/types/data-structures/binary-tree/binary-tree.ts +6 -5
  38. package/src/types/data-structures/binary-tree/bst.ts +6 -6
  39. package/src/types/data-structures/binary-tree/rb-tree.ts +3 -3
  40. package/src/types/data-structures/binary-tree/tree-multimap.ts +3 -3
@@ -10,7 +10,6 @@ import type {
10
10
  BinaryTreeNodeNested,
11
11
  BinaryTreeOptions,
12
12
  BTNCallback,
13
- BTNKey,
14
13
  BTNodeEntry,
15
14
  BTNodeExemplar,
16
15
  BTNodeKeyOrNode,
@@ -35,14 +34,14 @@ import { IterablePairBase } from "../base";
35
34
  * @template V - The type of data stored in the node.
36
35
  * @template N - The type of the family relationship in the binary tree.
37
36
  */
38
- export class BinaryTreeNode<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode<V, BinaryTreeNodeNested<V>>> {
39
- key: BTNKey;
37
+ export class BinaryTreeNode<K = any, V = any, N extends BinaryTreeNode<K, V, N> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>> {
38
+ key: K;
40
39
 
41
40
  value?: V;
42
41
 
43
42
  parent?: N;
44
43
 
45
- constructor(key: BTNKey, value?: V) {
44
+ constructor(key: K, value?: V) {
46
45
  this.key = key;
47
46
  this.value = value;
48
47
  }
@@ -105,9 +104,9 @@ export class BinaryTreeNode<V = any, N extends BinaryTreeNode<V, N> = BinaryTree
105
104
  * 9. Complete Trees: All levels are fully filled except possibly the last, filled from left to right.
106
105
  */
107
106
 
108
- export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode<V, BinaryTreeNodeNested<V>>, TREE extends BinaryTree<V, N, TREE> = BinaryTree<V, N, BinaryTreeNested<V, N>>> extends IterablePairBase<BTNKey, V | undefined>
107
+ 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 IterablePairBase<K, V | undefined>
109
108
 
110
- implements IBinaryTree<V, N, TREE> {
109
+ implements IBinaryTree<K, V, N, TREE> {
111
110
  iterationType = IterationType.ITERATIVE
112
111
 
113
112
  /**
@@ -119,13 +118,16 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
119
118
  * `Partial<BinaryTreeOptions>`, which means that not all properties of `BinaryTreeOptions` are
120
119
  * required.
121
120
  */
122
- constructor(elements?: Iterable<BTNodeExemplar<V, N>>, options?: Partial<BinaryTreeOptions>) {
121
+ constructor(elements?: Iterable<BTNodeExemplar<K, V, N>>, options?: Partial<BinaryTreeOptions<K>>) {
123
122
  super();
124
123
  if (options) {
125
- const { iterationType } = options;
124
+ const { iterationType, extractor } = options;
126
125
  if (iterationType) {
127
126
  this.iterationType = iterationType;
128
127
  }
128
+ if (extractor) {
129
+ this._extractor = extractor;
130
+ }
129
131
  }
130
132
 
131
133
  this._size = 0;
@@ -133,6 +135,12 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
133
135
  if (elements) this.addMany(elements);
134
136
  }
135
137
 
138
+ protected _extractor = (key: K) => Number(key)
139
+
140
+ get extractor() {
141
+ return this._extractor;
142
+ }
143
+
136
144
  protected _root?: N | null;
137
145
 
138
146
  get root(): N | null | undefined {
@@ -147,12 +155,12 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
147
155
 
148
156
  /**
149
157
  * Creates a new instance of BinaryTreeNode with the given key and value.
150
- * @param {BTNKey} key - The key for the new node.
158
+ * @param {K} key - The key for the new node.
151
159
  * @param {V} value - The value for the new node.
152
160
  * @returns {N} - The newly created BinaryTreeNode.
153
161
  */
154
- createNode(key: BTNKey, value?: V): N {
155
- return new BinaryTreeNode<V, N>(key, value) as N;
162
+ createNode(key: K, value?: V): N {
163
+ return new BinaryTreeNode<K, V, N>(key, value) as N;
156
164
  }
157
165
 
158
166
  /**
@@ -162,27 +170,27 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
162
170
  * you can provide only a subset of the properties defined in the `BinaryTreeOptions` interface.
163
171
  * @returns a new instance of a binary tree.
164
172
  */
165
- createTree(options?: Partial<BinaryTreeOptions>): TREE {
166
- return new BinaryTree<V, N, TREE>([], { iterationType: this.iterationType, ...options }) as TREE;
173
+ createTree(options?: Partial<BinaryTreeOptions<K>>): TREE {
174
+ return new BinaryTree<K, V, N, TREE>([], { iterationType: this.iterationType, ...options }) as TREE;
167
175
  }
168
176
 
169
177
  /**
170
178
  * The function "isNode" checks if an exemplar is an instance of the BinaryTreeNode class.
171
- * @param exemplar - The `exemplar` parameter is a variable of type `BTNodeExemplar<V, N>`.
179
+ * @param exemplar - The `exemplar` parameter is a variable of type `BTNodeExemplar<K, V,N>`.
172
180
  * @returns a boolean value indicating whether the exemplar is an instance of the class N.
173
181
  */
174
- isNode(exemplar: BTNodeExemplar<V, N>): exemplar is N {
182
+ isNode(exemplar: BTNodeExemplar<K, V, N>): exemplar is N {
175
183
  return exemplar instanceof BinaryTreeNode;
176
184
  }
177
185
 
178
186
  /**
179
187
  * The function `exemplarToNode` converts an exemplar of a binary tree node into an actual node
180
188
  * object.
181
- * @param exemplar - BTNodeExemplar<V, N> - A generic type representing the exemplar parameter of the
189
+ * @param exemplar - BTNodeExemplar<K, V,N> - A generic type representing the exemplar parameter of the
182
190
  * function. It can be any type.
183
191
  * @returns a value of type `N` (which represents a node), or `null`, or `undefined`.
184
192
  */
185
- exemplarToNode(exemplar: BTNodeExemplar<V, N>): N | null | undefined {
193
+ exemplarToNode(exemplar: BTNodeExemplar<K, V, N>): N | null | undefined {
186
194
  if (exemplar === undefined) return;
187
195
 
188
196
  let node: N | null | undefined;
@@ -199,7 +207,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
199
207
  }
200
208
  } else if (this.isNode(exemplar)) {
201
209
  node = exemplar;
202
- } else if (this.isNodeKey(exemplar)) {
210
+ } else if (this.isNotNodeInstance(exemplar)) {
203
211
  node = this.createNode(exemplar);
204
212
  } else {
205
213
  return;
@@ -209,11 +217,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
209
217
 
210
218
  /**
211
219
  * The function checks if a given value is an entry in a binary tree node.
212
- * @param kne - BTNodeExemplar<V, N> - A generic type representing a node in a binary tree. It has
220
+ * @param kne - BTNodeExemplar<K, V,N> - A generic type representing a node in a binary tree. It has
213
221
  * two type parameters V and N, representing the value and node type respectively.
214
222
  * @returns a boolean value.
215
223
  */
216
- isEntry(kne: BTNodeExemplar<V, N>): kne is BTNodeEntry<V> {
224
+ isEntry(kne: BTNodeExemplar<K, V, N>): kne is BTNodeEntry<K, V> {
217
225
  return Array.isArray(kne) && kne.length === 2;
218
226
  }
219
227
 
@@ -230,7 +238,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
230
238
  * @param keyOrNodeOrEntry - The parameter `keyOrNodeOrEntry` can be one of the following:
231
239
  * @returns The function `add` returns the inserted node (`N`), `null`, or `undefined`.
232
240
  */
233
- add(keyOrNodeOrEntry: BTNodeExemplar<V, N>): N | null | undefined {
241
+ add(keyOrNodeOrEntry: BTNodeExemplar<K, V, N>): N | null | undefined {
234
242
 
235
243
  let inserted: N | null | undefined;
236
244
  const newNode = this.exemplarToNode(keyOrNodeOrEntry);
@@ -279,11 +287,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
279
287
  * The function `addMany` takes in an iterable of `BTNodeExemplar` objects, adds each object to the
280
288
  * current instance, and returns an array of the inserted nodes.
281
289
  * @param nodes - The `nodes` parameter is an iterable (such as an array or a set) of
282
- * `BTNodeExemplar<V, N>` objects.
290
+ * `BTNodeExemplar<K, V,N>` objects.
283
291
  * @returns The function `addMany` returns an array of values, where each value is either of type
284
292
  * `N`, `null`, or `undefined`.
285
293
  */
286
- addMany(nodes: Iterable<BTNodeExemplar<V, N>>): (N | null | undefined)[] {
294
+ addMany(nodes: Iterable<BTNodeExemplar<K, V, N>>): (N | null | undefined)[] {
287
295
  // TODO not sure addMany not be run multi times
288
296
  const inserted: (N | null | undefined)[] = [];
289
297
  for (const kne of nodes) {
@@ -305,7 +313,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
305
313
  * @param nodesOrKeysOrEntries - The parameter `nodesOrKeysOrEntries` is an iterable object that can
306
314
  * contain either `BTNodeExemplar` objects, keys, or entries.
307
315
  */
308
- refill(nodesOrKeysOrEntries: Iterable<BTNodeExemplar<V, N>>): void {
316
+ refill(nodesOrKeysOrEntries: Iterable<BTNodeExemplar<K, V, N>>): void {
309
317
  this.clear();
310
318
  this.addMany(nodesOrKeysOrEntries);
311
319
  }
@@ -315,7 +323,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
315
323
  * Space Complexity: O(1)
316
324
  */
317
325
 
318
- delete<C extends BTNCallback<N, BTNKey>>(identifier: BTNKey, callback?: C): BiTreeDeleteResult<N>[];
326
+ delete<C extends BTNCallback<N, K>>(identifier: K, callback?: C): BiTreeDeleteResult<N>[];
319
327
 
320
328
  delete<C extends BTNCallback<N, N>>(identifier: N | null | undefined, callback?: C): BiTreeDeleteResult<N>[];
321
329
 
@@ -396,15 +404,15 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
396
404
  * Space Complexity: O(1)
397
405
  *
398
406
  * The function calculates the depth of a given node in a binary tree.
399
- * @param {BTNKey | N | null | undefined} distNode - The `distNode` parameter represents the node in
400
- * the binary tree whose depth we want to find. It can be of type `BTNKey`, `N`, `null`, or
407
+ * @param {K | N | null | undefined} distNode - The `distNode` parameter represents the node in
408
+ * the binary tree whose depth we want to find. It can be of type `K`, `N`, `null`, or
401
409
  * `undefined`.
402
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
403
- * from which we want to calculate the depth. It can be either a `BTNKey` (binary tree node key) or
410
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
411
+ * from which we want to calculate the depth. It can be either a `K` (binary tree node key) or
404
412
  * `N` (binary tree node) or `null` or `undefined`. If no value is provided for `beginRoot
405
413
  * @returns the depth of the `distNode` relative to the `beginRoot`.
406
414
  */
407
- getDepth(distNode: BTNodeKeyOrNode<N>, beginRoot: BTNodeKeyOrNode<N> = this.root): number {
415
+ getDepth(distNode: BTNodeKeyOrNode<K, N>, beginRoot: BTNodeKeyOrNode<K, N> = this.root): number {
408
416
  distNode = this.ensureNode(distNode);
409
417
  beginRoot = this.ensureNode(beginRoot);
410
418
  let depth = 0;
@@ -429,15 +437,15 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
429
437
  *
430
438
  * The function `getHeight` calculates the maximum height of a binary tree using either recursive or
431
439
  * iterative traversal.
432
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
440
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
433
441
  * starting node of the binary tree from which we want to calculate the height. It can be of type
434
- * `BTNKey`, `N`, `null`, or `undefined`. If not provided, it defaults to `this.root`.
442
+ * `K`, `N`, `null`, or `undefined`. If not provided, it defaults to `this.root`.
435
443
  * @param iterationType - The `iterationType` parameter is used to determine whether to calculate the
436
444
  * height of the tree using a recursive approach or an iterative approach. It can have two possible
437
445
  * values:
438
446
  * @returns the height of the binary tree.
439
447
  */
440
- getHeight(beginRoot: BTNodeKeyOrNode<N> = this.root, iterationType = this.iterationType): number {
448
+ getHeight(beginRoot: BTNodeKeyOrNode<K, N> = this.root, iterationType = this.iterationType): number {
441
449
  beginRoot = this.ensureNode(beginRoot);
442
450
  if (!beginRoot) return -1;
443
451
 
@@ -479,14 +487,14 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
479
487
  *
480
488
  * The `getMinHeight` function calculates the minimum height of a binary tree using either a
481
489
  * recursive or iterative approach.
482
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
490
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
483
491
  * starting node of the binary tree from which we want to calculate the minimum height. It can be of
484
- * type `BTNKey`, `N`, `null`, or `undefined`. If no value is provided, it defaults to `this.root`.
492
+ * type `K`, `N`, `null`, or `undefined`. If no value is provided, it defaults to `this.root`.
485
493
  * @param iterationType - The `iterationType` parameter is used to determine the method of iteration
486
494
  * to calculate the minimum height of a binary tree. It can have two possible values:
487
495
  * @returns The function `getMinHeight` returns the minimum height of a binary tree.
488
496
  */
489
- getMinHeight(beginRoot: BTNodeKeyOrNode<N> = this.root, iterationType = this.iterationType): number {
497
+ getMinHeight(beginRoot: BTNodeKeyOrNode<K, N> = this.root, iterationType = this.iterationType): number {
490
498
  beginRoot = this.ensureNode(beginRoot);
491
499
  if (!beginRoot) return -1;
492
500
 
@@ -541,12 +549,12 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
541
549
  *
542
550
  * The function checks if a binary tree is perfectly balanced by comparing the minimum height and the
543
551
  * height of the tree.
544
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
545
- * for calculating the height and minimum height of a binary tree. It can be either a `BTNKey` (a key
552
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
553
+ * for calculating the height and minimum height of a binary tree. It can be either a `K` (a key
546
554
  * value of a binary tree node), `N` (a node of a binary tree), `null`, or `undefined`. If
547
555
  * @returns a boolean value.
548
556
  */
549
- isPerfectlyBalanced(beginRoot: BTNodeKeyOrNode<N> = this.root): boolean {
557
+ isPerfectlyBalanced(beginRoot: BTNodeKeyOrNode<K, N> = this.root): boolean {
550
558
  return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
551
559
  }
552
560
 
@@ -555,11 +563,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
555
563
  * Space Complexity: O(log n)
556
564
  */
557
565
 
558
- getNodes<C extends BTNCallback<N, BTNKey>>(
559
- identifier: BTNKey,
566
+ getNodes<C extends BTNCallback<N, K>>(
567
+ identifier: K,
560
568
  callback?: C,
561
569
  onlyOne?: boolean,
562
- beginRoot?: BTNodeKeyOrNode<N>,
570
+ beginRoot?: BTNodeKeyOrNode<K, N>,
563
571
  iterationType?: IterationType
564
572
  ): N[];
565
573
 
@@ -567,7 +575,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
567
575
  identifier: N | null | undefined,
568
576
  callback?: C,
569
577
  onlyOne?: boolean,
570
- beginRoot?: BTNodeKeyOrNode<N>,
578
+ beginRoot?: BTNodeKeyOrNode<K, N>,
571
579
  iterationType?: IterationType
572
580
  ): N[];
573
581
 
@@ -575,7 +583,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
575
583
  identifier: ReturnType<C>,
576
584
  callback: C,
577
585
  onlyOne?: boolean,
578
- beginRoot?: BTNodeKeyOrNode<N>,
586
+ beginRoot?: BTNodeKeyOrNode<K, N>,
579
587
  iterationType?: IterationType
580
588
  ): N[];
581
589
 
@@ -597,7 +605,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
597
605
  * matches the identifier. If set to true, the function will stop iterating once it finds a matching
598
606
  * node and return that node. If set to false (default), the function will continue iterating and
599
607
  * return all nodes that match the identifier.
600
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
608
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
601
609
  * starting node for the traversal. It can be either a key, a node object, or `null`/`undefined`. If
602
610
  * it is `null` or `undefined`, an empty array will be returned.
603
611
  * @param iterationType - The `iterationType` parameter determines the type of iteration used to
@@ -608,7 +616,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
608
616
  identifier: ReturnType<C> | null | undefined,
609
617
  callback: C = this._defaultOneParamCallback as C,
610
618
  onlyOne = false,
611
- beginRoot: BTNodeKeyOrNode<N> = this.root,
619
+ beginRoot: BTNodeKeyOrNode<K, N> = this.root,
612
620
  iterationType = this.iterationType
613
621
  ): N[] {
614
622
  if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
@@ -653,24 +661,24 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
653
661
  * Space Complexity: O(log n).
654
662
  */
655
663
 
656
- has<C extends BTNCallback<N, BTNKey>>(
657
- identifier: BTNKey,
664
+ has<C extends BTNCallback<N, K>>(
665
+ identifier: K,
658
666
  callback?: C,
659
- beginRoot?: BTNodeKeyOrNode<N>,
667
+ beginRoot?: BTNodeKeyOrNode<K, N>,
660
668
  iterationType?: IterationType
661
669
  ): boolean;
662
670
 
663
671
  has<C extends BTNCallback<N, N>>(
664
672
  identifier: N | null | undefined,
665
673
  callback?: C,
666
- beginRoot?: BTNodeKeyOrNode<N>,
674
+ beginRoot?: BTNodeKeyOrNode<K, N>,
667
675
  iterationType?: IterationType
668
676
  ): boolean;
669
677
 
670
678
  has<C extends BTNCallback<N>>(
671
679
  identifier: ReturnType<C> | null | undefined,
672
680
  callback: C,
673
- beginRoot?: BTNodeKeyOrNode<N>,
681
+ beginRoot?: BTNodeKeyOrNode<K, N>,
674
682
  iterationType?: IterationType
675
683
  ): boolean;
676
684
 
@@ -686,8 +694,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
686
694
  * the binary tree. It is used to filter the nodes based on certain conditions. The `callback`
687
695
  * function should return a boolean value indicating whether the node should be included in the
688
696
  * result or not.
689
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
690
- * for the search in the binary tree. It can be specified as a `BTNKey` (a unique identifier for a
697
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
698
+ * for the search in the binary tree. It can be specified as a `K` (a unique identifier for a
691
699
  * node in the binary tree), a node object (`N`), or `null`/`undefined` to start the search from
692
700
  * @param iterationType - The `iterationType` parameter is a variable that determines the type of
693
701
  * iteration to be performed on the binary tree. It is used to specify whether the iteration should
@@ -697,7 +705,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
697
705
  has<C extends BTNCallback<N>>(
698
706
  identifier: ReturnType<C> | null | undefined,
699
707
  callback: C = this._defaultOneParamCallback as C,
700
- beginRoot: BTNodeKeyOrNode<N> = this.root,
708
+ beginRoot: BTNodeKeyOrNode<K, N> = this.root,
701
709
  iterationType = this.iterationType
702
710
  ): boolean {
703
711
  if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
@@ -711,24 +719,24 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
711
719
  * Space Complexity: O(log n).
712
720
  */
713
721
 
714
- getNode<C extends BTNCallback<N, BTNKey>>(
715
- identifier: BTNKey,
722
+ getNode<C extends BTNCallback<N, K>>(
723
+ identifier: K,
716
724
  callback?: C,
717
- beginRoot?: BTNodeKeyOrNode<N>,
725
+ beginRoot?: BTNodeKeyOrNode<K, N>,
718
726
  iterationType?: IterationType
719
727
  ): N | null | undefined;
720
728
 
721
729
  getNode<C extends BTNCallback<N, N>>(
722
730
  identifier: N | null | undefined,
723
731
  callback?: C,
724
- beginRoot?: BTNodeKeyOrNode<N>,
732
+ beginRoot?: BTNodeKeyOrNode<K, N>,
725
733
  iterationType?: IterationType
726
734
  ): N | null | undefined;
727
735
 
728
736
  getNode<C extends BTNCallback<N>>(
729
737
  identifier: ReturnType<C>,
730
738
  callback: C,
731
- beginRoot?: BTNodeKeyOrNode<N>,
739
+ beginRoot?: BTNodeKeyOrNode<K, N>,
732
740
  iterationType?: IterationType
733
741
  ): N | null | undefined;
734
742
 
@@ -745,7 +753,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
745
753
  * @param {C} callback - The `callback` parameter is a function that will be called for each node in
746
754
  * the binary tree. It is used to determine if a node matches the given identifier. The `callback`
747
755
  * function should take a single parameter of type `N` (the type of the nodes in the binary tree) and
748
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
756
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
749
757
  * for searching the binary tree. It can be either a key value, a node object, or `null`/`undefined`.
750
758
  * If `null` or `undefined` is passed, the search will start from the root of the binary tree.
751
759
  * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
@@ -756,7 +764,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
756
764
  getNode<C extends BTNCallback<N>>(
757
765
  identifier: ReturnType<C> | null | undefined,
758
766
  callback: C = this._defaultOneParamCallback as C,
759
- beginRoot: BTNodeKeyOrNode<N> = this.root,
767
+ beginRoot: BTNodeKeyOrNode<K, N> = this.root,
760
768
  iterationType = this.iterationType
761
769
  ): N | null | undefined {
762
770
  if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
@@ -776,7 +784,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
776
784
  *
777
785
  * The function `getNodeByKey` searches for a node in a binary tree by its key, using either
778
786
  * recursive or iterative iteration.
779
- * @param {BTNKey} key - The `key` parameter is the key value that we are searching for in the tree.
787
+ * @param {K} key - The `key` parameter is the key value that we are searching for in the tree.
780
788
  * It is used to find the node with the matching key value.
781
789
  * @param iterationType - The `iterationType` parameter is used to determine whether the search for
782
790
  * the node with the given key should be performed iteratively or recursively. It has two possible
@@ -784,7 +792,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
784
792
  * @returns The function `getNodeByKey` returns a node (`N`) if a node with the specified key is
785
793
  * found in the binary tree. If no node is found, it returns `undefined`.
786
794
  */
787
- getNodeByKey(key: BTNKey, iterationType = IterationType.ITERATIVE): N | undefined {
795
+ getNodeByKey(key: K, iterationType = IterationType.ITERATIVE): N | undefined {
788
796
  if (!this.root) return undefined;
789
797
  if (iterationType === IterationType.RECURSIVE) {
790
798
  const _dfs = (cur: N): N | undefined => {
@@ -817,7 +825,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
817
825
  /**
818
826
  * The function `ensureNode` returns the node corresponding to the given key if it is a valid node
819
827
  * key, otherwise it returns the key itself.
820
- * @param {BTNKey | N | null | undefined} key - The `key` parameter can be of type `BTNKey`, `N`,
828
+ * @param {K | N | null | undefined} key - The `key` parameter can be of type `K`, `N`,
821
829
  * `null`, or `undefined`. It represents a key used to identify a node in a binary tree.
822
830
  * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
823
831
  * type of iteration to be used when searching for a node by key. It has a default value of
@@ -825,28 +833,28 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
825
833
  * @returns either the node corresponding to the given key if it is a valid node key, or the key
826
834
  * itself if it is not a valid node key.
827
835
  */
828
- ensureNode(key: BTNodeKeyOrNode<N>, iterationType = IterationType.ITERATIVE): N | null | undefined {
829
- return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key;
836
+ ensureNode(key: BTNodeKeyOrNode<K, N>, iterationType = IterationType.ITERATIVE): N | null | undefined {
837
+ return this.isNotNodeInstance(key) ? this.getNodeByKey(key, iterationType) : key;
830
838
  }
831
839
 
832
- get<C extends BTNCallback<N, BTNKey>>(
833
- identifier: BTNKey,
840
+ get<C extends BTNCallback<N, K>>(
841
+ identifier: K,
834
842
  callback?: C,
835
- beginRoot?: BTNodeKeyOrNode<N>,
843
+ beginRoot?: BTNodeKeyOrNode<K, N>,
836
844
  iterationType?: IterationType
837
845
  ): V | undefined;
838
846
 
839
847
  get<C extends BTNCallback<N, N>>(
840
848
  identifier: N | null | undefined,
841
849
  callback?: C,
842
- beginRoot?: BTNodeKeyOrNode<N>,
850
+ beginRoot?: BTNodeKeyOrNode<K, N>,
843
851
  iterationType?: IterationType
844
852
  ): V | undefined;
845
853
 
846
854
  get<C extends BTNCallback<N>>(
847
855
  identifier: ReturnType<C>,
848
856
  callback: C,
849
- beginRoot?: BTNodeKeyOrNode<N>,
857
+ beginRoot?: BTNodeKeyOrNode<K, N>,
850
858
  iterationType?: IterationType
851
859
  ): V | undefined;
852
860
 
@@ -863,8 +871,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
863
871
  * the binary tree. It is used to determine whether a node matches the given identifier. The callback
864
872
  * function should return a value that can be compared to the identifier to determine if it is a
865
873
  * match.
866
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
867
- * for the search in the binary tree. It can be specified as a `BTNKey` (a unique identifier for a
874
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
875
+ * for the search in the binary tree. It can be specified as a `K` (a unique identifier for a
868
876
  * node), a node object of type `N`, or `null`/`undefined` to start the search from the root of
869
877
  * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
870
878
  * be performed when searching for a node in the binary tree. It is an optional parameter with a
@@ -875,7 +883,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
875
883
  get<C extends BTNCallback<N>>(
876
884
  identifier: ReturnType<C> | null | undefined,
877
885
  callback: C = this._defaultOneParamCallback as C,
878
- beginRoot: BTNodeKeyOrNode<N> = this.root,
886
+ beginRoot: BTNodeKeyOrNode<K, N> = this.root,
879
887
  iterationType = this.iterationType
880
888
  ): V | undefined {
881
889
  if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
@@ -911,15 +919,15 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
911
919
  *
912
920
  * The function `getPathToRoot` returns an array of nodes from a given node to the root of a tree
913
921
  * structure, with the option to reverse the order of the nodes.
914
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
915
- * starting node from which you want to find the path to the root. It can be of type `BTNKey`, `N`,
922
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
923
+ * starting node from which you want to find the path to the root. It can be of type `K`, `N`,
916
924
  * `null`, or `undefined`.
917
925
  * @param [isReverse=true] - The `isReverse` parameter is a boolean flag that determines whether the
918
926
  * resulting path should be reversed or not. If `isReverse` is set to `true`, the path will be
919
927
  * reversed before returning it. If `isReverse` is set to `false`, the path will be returned as is
920
928
  * @returns The function `getPathToRoot` returns an array of nodes (`N[]`).
921
929
  */
922
- getPathToRoot(beginRoot: BTNodeKeyOrNode<N>, isReverse = true): N[] {
930
+ getPathToRoot(beginRoot: BTNodeKeyOrNode<K, N>, isReverse = true): N[] {
923
931
  // TODO to support get path through passing key
924
932
  const result: N[] = [];
925
933
  beginRoot = this.ensureNode(beginRoot);
@@ -947,8 +955,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
947
955
  *
948
956
  * The function `getLeftMost` returns the leftmost node in a binary tree, either recursively or
949
957
  * iteratively.
950
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
951
- * for finding the leftmost node in a binary tree. It can be either a `BTNKey` (a key value), `N` (a
958
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
959
+ * for finding the leftmost node in a binary tree. It can be either a `K` (a key value), `N` (a
952
960
  * node), `null`, or `undefined`. If not provided, it defaults to `this.root`,
953
961
  * @param iterationType - The `iterationType` parameter is used to determine the type of iteration to
954
962
  * be performed when finding the leftmost node in a binary tree. It can have two possible values:
@@ -956,7 +964,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
956
964
  * is no leftmost node, it returns `null` or `undefined` depending on the input.
957
965
  */
958
966
  getLeftMost(
959
- beginRoot: BTNodeKeyOrNode<N> = this.root,
967
+ beginRoot: BTNodeKeyOrNode<K, N> = this.root,
960
968
  iterationType = this.iterationType
961
969
  ): N | null | undefined {
962
970
  beginRoot = this.ensureNode(beginRoot);
@@ -992,8 +1000,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
992
1000
  *
993
1001
  * The function `getRightMost` returns the rightmost node in a binary tree, either recursively or
994
1002
  * iteratively.
995
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
996
- * starting node from which we want to find the rightmost node. It can be of type `BTNKey`, `N`,
1003
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
1004
+ * starting node from which we want to find the rightmost node. It can be of type `K`, `N`,
997
1005
  * `null`, or `undefined`. If not provided, it defaults to `this.root`, which is a property of the
998
1006
  * current object.
999
1007
  * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
@@ -1002,7 +1010,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1002
1010
  * is no rightmost node, it returns `null` or `undefined`, depending on the input.
1003
1011
  */
1004
1012
  getRightMost(
1005
- beginRoot: BTNodeKeyOrNode<N> = this.root,
1013
+ beginRoot: BTNodeKeyOrNode<K, N> = this.root,
1006
1014
  iterationType = this.iterationType
1007
1015
  ): N | null | undefined {
1008
1016
  // TODO support get right most by passing key in
@@ -1037,23 +1045,24 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1037
1045
  * Space Complexity: O(1)
1038
1046
  *
1039
1047
  * The function `isSubtreeBST` checks if a given binary tree is a valid binary search tree.
1040
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the root
1048
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the root
1041
1049
  * node of the binary search tree (BST) that you want to check if it is a subtree of another BST.
1042
1050
  * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
1043
1051
  * type of iteration to use when checking if a subtree is a binary search tree (BST). It can have two
1044
1052
  * possible values:
1045
1053
  * @returns a boolean value.
1046
1054
  */
1047
- isSubtreeBST(beginRoot: BTNodeKeyOrNode<N>, iterationType = this.iterationType): boolean {
1055
+ isSubtreeBST(beginRoot: BTNodeKeyOrNode<K, N>, iterationType = this.iterationType): boolean {
1048
1056
  // TODO there is a bug
1049
1057
  beginRoot = this.ensureNode(beginRoot);
1050
1058
  if (!beginRoot) return true;
1051
1059
 
1052
1060
  if (iterationType === IterationType.RECURSIVE) {
1053
- const dfs = (cur: N | null | undefined, min: BTNKey, max: BTNKey): boolean => {
1061
+ const dfs = (cur: N | null | undefined, min: number, max: number): boolean => {
1054
1062
  if (!cur) return true;
1055
- if (cur.key <= min || cur.key >= max) return false;
1056
- return dfs(cur.left, min, cur.key) && dfs(cur.right, cur.key, max);
1063
+ const numKey = this.extractor(cur.key);
1064
+ if (numKey <= min || numKey >= max) return false;
1065
+ return dfs(cur.left, min, numKey) && dfs(cur.right, numKey, max);
1057
1066
  };
1058
1067
 
1059
1068
  return dfs(beginRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
@@ -1067,8 +1076,9 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1067
1076
  curr = curr.left;
1068
1077
  }
1069
1078
  curr = stack.pop()!;
1070
- if (!curr || prev >= curr.key) return false;
1071
- prev = curr.key;
1079
+ const numKey = this.extractor(curr.key);
1080
+ if (!curr || prev >= numKey) return false;
1081
+ prev = numKey;
1072
1082
  curr = curr.right;
1073
1083
  }
1074
1084
  return true;
@@ -1103,21 +1113,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1103
1113
 
1104
1114
  subTreeTraverse<C extends BTNCallback<N>>(
1105
1115
  callback?: C,
1106
- beginRoot?: BTNodeKeyOrNode<N>,
1116
+ beginRoot?: BTNodeKeyOrNode<K, N>,
1107
1117
  iterationType?: IterationType,
1108
1118
  includeNull?: false
1109
1119
  ): ReturnType<C>[];
1110
1120
 
1111
1121
  subTreeTraverse<C extends BTNCallback<N>>(
1112
1122
  callback?: C,
1113
- beginRoot?: BTNodeKeyOrNode<N>,
1123
+ beginRoot?: BTNodeKeyOrNode<K, N>,
1114
1124
  iterationType?: IterationType,
1115
1125
  includeNull?: undefined
1116
1126
  ): ReturnType<C>[];
1117
1127
 
1118
1128
  subTreeTraverse<C extends BTNCallback<N | null | undefined>>(
1119
1129
  callback?: C,
1120
- beginRoot?: BTNodeKeyOrNode<N>,
1130
+ beginRoot?: BTNodeKeyOrNode<K, N>,
1121
1131
  iterationType?: IterationType,
1122
1132
  includeNull?: true
1123
1133
  ): ReturnType<C>[];
@@ -1131,8 +1141,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1131
1141
  * @param {C} callback - The `callback` parameter is a function that will be called for each node in
1132
1142
  * the subtree traversal. It takes a single parameter, which is the current node being traversed, and
1133
1143
  * returns a value of any type.
1134
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
1135
- * starting node or key from which the subtree traversal should begin. It can be of type `BTNKey`,
1144
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
1145
+ * starting node or key from which the subtree traversal should begin. It can be of type `K`,
1136
1146
  * `N`, `null`, or `undefined`. If not provided, the `root` property of the current object is used as
1137
1147
  * the default value.
1138
1148
  * @param iterationType - The `iterationType` parameter determines the type of traversal to be
@@ -1146,7 +1156,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1146
1156
  */
1147
1157
  subTreeTraverse<C extends BTNCallback<N | null | undefined>>(
1148
1158
  callback: C = this._defaultOneParamCallback as C,
1149
- beginRoot: BTNodeKeyOrNode<N> = this.root,
1159
+ beginRoot: BTNodeKeyOrNode<K, N> = this.root,
1150
1160
  iterationType = this.iterationType,
1151
1161
  includeNull = false
1152
1162
  ): ReturnType<C>[] {
@@ -1224,19 +1234,19 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1224
1234
  }
1225
1235
 
1226
1236
  /**
1227
- * The function "isNodeKey" checks if a potential key is a number.
1237
+ * The function "isNotNodeInstance" checks if a potential key is a number.
1228
1238
  * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any
1229
1239
  * data type.
1230
1240
  * @returns a boolean value indicating whether the potentialKey is of type number or not.
1231
1241
  */
1232
- isNodeKey(potentialKey: any): potentialKey is number {
1233
- return typeof potentialKey === 'number';
1242
+ isNotNodeInstance(potentialKey: BTNodeKeyOrNode<K, N>): potentialKey is K {
1243
+ return !(potentialKey instanceof BinaryTreeNode)
1234
1244
  }
1235
1245
 
1236
1246
  dfs<C extends BTNCallback<N>>(
1237
1247
  callback?: C,
1238
1248
  pattern?: DFSOrderPattern,
1239
- beginRoot?: BTNodeKeyOrNode<N>,
1249
+ beginRoot?: BTNodeKeyOrNode<K, N>,
1240
1250
  iterationType?: IterationType,
1241
1251
  includeNull?: false
1242
1252
  ): ReturnType<C>[];
@@ -1244,7 +1254,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1244
1254
  dfs<C extends BTNCallback<N>>(
1245
1255
  callback?: C,
1246
1256
  pattern?: DFSOrderPattern,
1247
- beginRoot?: BTNodeKeyOrNode<N>,
1257
+ beginRoot?: BTNodeKeyOrNode<K, N>,
1248
1258
  iterationType?: IterationType,
1249
1259
  includeNull?: undefined
1250
1260
  ): ReturnType<C>[];
@@ -1252,7 +1262,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1252
1262
  dfs<C extends BTNCallback<N | null | undefined>>(
1253
1263
  callback?: C,
1254
1264
  pattern?: DFSOrderPattern,
1255
- beginRoot?: BTNodeKeyOrNode<N>,
1265
+ beginRoot?: BTNodeKeyOrNode<K, N>,
1256
1266
  iterationType?: IterationType,
1257
1267
  includeNull?: true
1258
1268
  ): ReturnType<C>[];
@@ -1269,7 +1279,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1269
1279
  * `null`, or `undefined`, and returns a value of any type. The default value for this parameter is
1270
1280
  * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter determines the order in which the
1271
1281
  * nodes are traversed during the depth-first search. It can have one of the following values:
1272
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
1282
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
1273
1283
  * for the depth-first search traversal. It can be specified as a key, a node object, or
1274
1284
  * `null`/`undefined`. If not provided, the `beginRoot` will default to the root node of the tree.
1275
1285
  * @param {IterationType} iterationType - The `iterationType` parameter determines the type of
@@ -1283,7 +1293,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1283
1293
  dfs<C extends BTNCallback<N | null | undefined>>(
1284
1294
  callback: C = this._defaultOneParamCallback as C,
1285
1295
  pattern: DFSOrderPattern = 'in',
1286
- beginRoot: BTNodeKeyOrNode<N> = this.root,
1296
+ beginRoot: BTNodeKeyOrNode<K, N> = this.root,
1287
1297
  iterationType: IterationType = IterationType.ITERATIVE,
1288
1298
  includeNull = false
1289
1299
  ): ReturnType<C>[] {
@@ -1382,21 +1392,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1382
1392
 
1383
1393
  bfs<C extends BTNCallback<N>>(
1384
1394
  callback?: C,
1385
- beginRoot?: BTNodeKeyOrNode<N>,
1395
+ beginRoot?: BTNodeKeyOrNode<K, N>,
1386
1396
  iterationType?: IterationType,
1387
1397
  includeNull?: false
1388
1398
  ): ReturnType<C>[];
1389
1399
 
1390
1400
  bfs<C extends BTNCallback<N>>(
1391
1401
  callback?: C,
1392
- beginRoot?: BTNodeKeyOrNode<N>,
1402
+ beginRoot?: BTNodeKeyOrNode<K, N>,
1393
1403
  iterationType?: IterationType,
1394
1404
  includeNull?: undefined
1395
1405
  ): ReturnType<C>[];
1396
1406
 
1397
1407
  bfs<C extends BTNCallback<N | null | undefined>>(
1398
1408
  callback?: C,
1399
- beginRoot?: BTNodeKeyOrNode<N>,
1409
+ beginRoot?: BTNodeKeyOrNode<K, N>,
1400
1410
  iterationType?: IterationType,
1401
1411
  includeNull?: true
1402
1412
  ): ReturnType<C>[];
@@ -1410,7 +1420,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1410
1420
  * @param {C} callback - The `callback` parameter is a function that will be called for each node in
1411
1421
  * the breadth-first search traversal. It takes a single parameter, which is the current node being
1412
1422
  * visited, and returns a value of any type.
1413
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
1423
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
1414
1424
  * starting node for the breadth-first search traversal. It can be specified as a key, a node object,
1415
1425
  * or `null`/`undefined` to indicate the root of the tree. If not provided, the `root` property of
1416
1426
  * the class is used as
@@ -1424,7 +1434,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1424
1434
  */
1425
1435
  bfs<C extends BTNCallback<N | null | undefined>>(
1426
1436
  callback: C = this._defaultOneParamCallback as C,
1427
- beginRoot: BTNodeKeyOrNode<N> = this.root,
1437
+ beginRoot: BTNodeKeyOrNode<K, N> = this.root,
1428
1438
  iterationType = this.iterationType,
1429
1439
  includeNull = false
1430
1440
  ): ReturnType<C>[] {
@@ -1483,21 +1493,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1483
1493
 
1484
1494
  listLevels<C extends BTNCallback<N>>(
1485
1495
  callback?: C,
1486
- beginRoot?: BTNodeKeyOrNode<N>,
1496
+ beginRoot?: BTNodeKeyOrNode<K, N>,
1487
1497
  iterationType?: IterationType,
1488
1498
  includeNull?: false
1489
1499
  ): ReturnType<C>[][];
1490
1500
 
1491
1501
  listLevels<C extends BTNCallback<N>>(
1492
1502
  callback?: C,
1493
- beginRoot?: BTNodeKeyOrNode<N>,
1503
+ beginRoot?: BTNodeKeyOrNode<K, N>,
1494
1504
  iterationType?: IterationType,
1495
1505
  includeNull?: undefined
1496
1506
  ): ReturnType<C>[][];
1497
1507
 
1498
1508
  listLevels<C extends BTNCallback<N | null | undefined>>(
1499
1509
  callback?: C,
1500
- beginRoot?: BTNodeKeyOrNode<N>,
1510
+ beginRoot?: BTNodeKeyOrNode<K, N>,
1501
1511
  iterationType?: IterationType,
1502
1512
  includeNull?: true
1503
1513
  ): ReturnType<C>[][];
@@ -1512,9 +1522,9 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1512
1522
  * @param {C} callback - The `callback` parameter is a function that will be called for each node in
1513
1523
  * the tree. It takes a single parameter, which can be of type `N`, `null`, or `undefined`, and
1514
1524
  * returns a value of any type.
1515
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
1525
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
1516
1526
  * starting node for traversing the tree. It can be either a node object (`N`), a key value
1517
- * (`BTNKey`), `null`, or `undefined`. If not provided, it defaults to the root node of the tree.
1527
+ * (`K`), `null`, or `undefined`. If not provided, it defaults to the root node of the tree.
1518
1528
  * @param iterationType - The `iterationType` parameter determines the type of iteration to be
1519
1529
  * performed on the tree. It can have two possible values:
1520
1530
  * @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines
@@ -1525,7 +1535,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1525
1535
  */
1526
1536
  listLevels<C extends BTNCallback<N | null | undefined>>(
1527
1537
  callback: C = this._defaultOneParamCallback as C,
1528
- beginRoot: BTNodeKeyOrNode<N> = this.root,
1538
+ beginRoot: BTNodeKeyOrNode<K, N> = this.root,
1529
1539
  iterationType = this.iterationType,
1530
1540
  includeNull = false
1531
1541
  ): ReturnType<C>[][] {
@@ -1579,11 +1589,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1579
1589
 
1580
1590
  /**
1581
1591
  * The function `getPredecessor` returns the predecessor node of a given node in a binary tree.
1582
- * @param {BTNKey | N | null | undefined} node - The `node` parameter can be of type `BTNKey`, `N`,
1592
+ * @param {K | N | null | undefined} node - The `node` parameter can be of type `K`, `N`,
1583
1593
  * `null`, or `undefined`.
1584
1594
  * @returns The function `getPredecessor` returns a value of type `N | undefined`.
1585
1595
  */
1586
- getPredecessor(node: BTNodeKeyOrNode<N>): N | undefined {
1596
+ getPredecessor(node: BTNodeKeyOrNode<K, N>): N | undefined {
1587
1597
  node = this.ensureNode(node);
1588
1598
  if (!this.isRealNode(node)) return undefined;
1589
1599
 
@@ -1602,11 +1612,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1602
1612
 
1603
1613
  /**
1604
1614
  * The function `getSuccessor` returns the next node in a binary tree given a current node.
1605
- * @param {BTNKey | N | null} [x] - The parameter `x` can be of type `BTNKey`, `N`, or `null`.
1615
+ * @param {K | N | null} [x] - The parameter `x` can be of type `K`, `N`, or `null`.
1606
1616
  * @returns the successor of the given node or key. The successor is the node that comes immediately
1607
1617
  * after the given node in the inorder traversal of the binary tree.
1608
1618
  */
1609
- getSuccessor(x?: BTNKey | N | null): N | null | undefined {
1619
+ getSuccessor(x?: K | N | null): N | null | undefined {
1610
1620
  x = this.ensureNode(x);
1611
1621
  if (!x) return undefined;
1612
1622
 
@@ -1633,7 +1643,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1633
1643
  * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter in the `morris` function
1634
1644
  * determines the order in which the nodes of a binary tree are traversed. It can have one of the
1635
1645
  * following values:
1636
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
1646
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
1637
1647
  * for the traversal. It can be specified as a key, a node object, or `null`/`undefined` to indicate
1638
1648
  * the root of the tree. If no value is provided, the default value is the root of the tree.
1639
1649
  * @returns The function `morris` returns an array of values that are the result of invoking the
@@ -1643,7 +1653,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1643
1653
  morris<C extends BTNCallback<N>>(
1644
1654
  callback: C = this._defaultOneParamCallback as C,
1645
1655
  pattern: DFSOrderPattern = 'in',
1646
- beginRoot: BTNodeKeyOrNode<N> = this.root
1656
+ beginRoot: BTNodeKeyOrNode<K, N> = this.root
1647
1657
  ): ReturnType<C>[] {
1648
1658
  beginRoot = this.ensureNode(beginRoot);
1649
1659
  if (beginRoot === null) return [];
@@ -1765,7 +1775,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1765
1775
  * @returns The `filter` method is returning a new tree object that contains the key-value pairs that
1766
1776
  * pass the given predicate function.
1767
1777
  */
1768
- filter(predicate: PairCallback<BTNKey, V | undefined, boolean>, thisArg?: any) {
1778
+ filter(predicate: PairCallback<K, V | undefined, boolean>, thisArg?: any) {
1769
1779
  const newTree = this.createTree();
1770
1780
  let index = 0;
1771
1781
  for (const [key, value] of this) {
@@ -1796,7 +1806,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1796
1806
  * will be used as the `this` value when the callback function is called. If you don't pass a value
1797
1807
  * @returns The `map` method is returning a new tree object.
1798
1808
  */
1799
- map(callback: PairCallback<BTNKey, V | undefined, V>, thisArg?: any) {
1809
+ map(callback: PairCallback<K, V | undefined, V>, thisArg?: any) {
1800
1810
  const newTree = this.createTree();
1801
1811
  let index = 0;
1802
1812
  for (const [key, value] of this) {
@@ -1806,7 +1816,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1806
1816
  }
1807
1817
 
1808
1818
  // // TODO Type error, need to return a TREE<NV> that is a value type only for callback function.
1809
- // // map<NV>(callback: (entry: [BTNKey, V | undefined], tree: this) => NV) {
1819
+ // // map<NV>(callback: (entry: [K, V | undefined], tree: this) => NV) {
1810
1820
  // // const newTree = this.createTree();
1811
1821
  // // for (const [key, value] of this) {
1812
1822
  // // newTree.add(key, callback([key, value], this));
@@ -1817,12 +1827,12 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1817
1827
 
1818
1828
  /**
1819
1829
  * The `print` function is used to display a binary tree structure in a visually appealing way.
1820
- * @param {BTNKey | N | null | undefined} [beginRoot=this.root] - The `root` parameter is of type `BTNKey | N | null |
1830
+ * @param {K | N | null | undefined} [beginRoot=this.root] - The `root` parameter is of type `K | N | null |
1821
1831
  * undefined`. It represents the root node of a binary tree. The root node can have one of the
1822
1832
  * following types:
1823
1833
  * @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.
1824
1834
  */
1825
- print(beginRoot: BTNodeKeyOrNode<N> = this.root, options?: BinaryTreePrintOptions): void {
1835
+ print(beginRoot: BTNodeKeyOrNode<K, N> = this.root, options?: BinaryTreePrintOptions): void {
1826
1836
  const opts = { isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false, ...options };
1827
1837
  beginRoot = this.ensureNode(beginRoot);
1828
1838
  if (!beginRoot) return;
@@ -1844,7 +1854,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1844
1854
  display(beginRoot);
1845
1855
  }
1846
1856
 
1847
- protected* _getIterator(node = this.root): IterableIterator<[BTNKey, V | undefined]> {
1857
+ protected* _getIterator(node = this.root): IterableIterator<[K, V | undefined]> {
1848
1858
  if (!node) return;
1849
1859
 
1850
1860
  if (this.iterationType === IterationType.ITERATIVE) {
@@ -1852,24 +1862,24 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1852
1862
  let current: N | null | undefined = node;
1853
1863
 
1854
1864
  while (current || stack.length > 0) {
1855
- while (current && !isNaN(current.key)) {
1865
+ while (current && !isNaN(this.extractor(current.key))) {
1856
1866
  stack.push(current);
1857
1867
  current = current.left;
1858
1868
  }
1859
1869
 
1860
1870
  current = stack.pop();
1861
1871
 
1862
- if (current && !isNaN(current.key)) {
1872
+ if (current && !isNaN(this.extractor(current.key))) {
1863
1873
  yield [current.key, current.value];
1864
1874
  current = current.right;
1865
1875
  }
1866
1876
  }
1867
1877
  } else {
1868
- if (node.left && !isNaN(node.key)) {
1878
+ if (node.left && !isNaN(this.extractor(node.key))) {
1869
1879
  yield* this[Symbol.iterator](node.left);
1870
1880
  }
1871
1881
  yield [node.key, node.value];
1872
- if (node.right && !isNaN(node.key)) {
1882
+ if (node.right && !isNaN(this.extractor(node.key))) {
1873
1883
  yield* this[Symbol.iterator](node.right);
1874
1884
  }
1875
1885
  }
@@ -1884,12 +1894,13 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1884
1894
  return emptyDisplayLayout;
1885
1895
  } else if (node === undefined && !isShowUndefined) {
1886
1896
  return emptyDisplayLayout;
1887
- } else if (node !== null && node !== undefined && isNaN(node.key) && !isShowRedBlackNIL) {
1897
+ } else if (node !== null && node !== undefined && isNaN(this.extractor(node.key)) && !isShowRedBlackNIL) {
1888
1898
  return emptyDisplayLayout;
1889
1899
  } else if (node !== null && node !== undefined) {
1890
1900
  // Display logic of normal nodes
1891
1901
 
1892
- const key = node.key, line = isNaN(key) ? 'S' : key.toString(), width = line.length;
1902
+ const key = node.key, line = isNaN(this.extractor(key)) ? 'S' : this.extractor(key).toString(),
1903
+ width = line.length;
1893
1904
 
1894
1905
  return _buildNodeDisplay(line, width, this._displayAux(node.left, options), this._displayAux(node.right, options))
1895
1906
 
@@ -1933,7 +1944,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1933
1944
  * @param {N} destNode - The destination node to swap.
1934
1945
  * @returns {N} - The destination node after the swap.
1935
1946
  */
1936
- protected _swapProperties(srcNode: BTNodeKeyOrNode<N>, destNode: BTNodeKeyOrNode<N>): N | undefined {
1947
+ protected _swapProperties(srcNode: BTNodeKeyOrNode<K, N>, destNode: BTNodeKeyOrNode<K, N>): N | undefined {
1937
1948
  srcNode = this.ensureNode(srcNode);
1938
1949
  destNode = this.ensureNode(destNode);
1939
1950
 
@@ -1991,8 +2002,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
1991
2002
  * the binary tree. If neither the left nor right child is available, the function returns undefined.
1992
2003
  * If the parent node is null, the function also returns undefined.
1993
2004
  */
1994
- protected _addTo(newNode: N | null | undefined, parent: BTNodeKeyOrNode<N>): N | null | undefined {
1995
- if (this.isNodeKey(parent)) parent = this.getNode(parent);
2005
+ protected _addTo(newNode: N | null | undefined, parent: BTNodeKeyOrNode<K, N>): N | null | undefined {
2006
+ if (this.isNotNodeInstance(parent)) parent = this.getNode(parent);
1996
2007
 
1997
2008
  if (parent) {
1998
2009
  // When all leaf nodes are null, it will no longer be possible to add new entity nodes to this binary tree.