red-black-tree-typed 1.53.6 → 1.54.1

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 (121) hide show
  1. package/README.md +52 -0
  2. package/dist/common/index.d.ts +12 -0
  3. package/dist/common/index.js +28 -0
  4. package/dist/data-structures/base/iterable-entry-base.js +4 -4
  5. package/dist/data-structures/binary-tree/avl-tree-counter.d.ts +213 -0
  6. package/dist/data-structures/binary-tree/avl-tree-counter.js +407 -0
  7. package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +71 -170
  8. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +133 -331
  9. package/dist/data-structures/binary-tree/avl-tree.d.ts +103 -69
  10. package/dist/data-structures/binary-tree/avl-tree.js +131 -71
  11. package/dist/data-structures/binary-tree/binary-indexed-tree.d.ts +3 -0
  12. package/dist/data-structures/binary-tree/binary-indexed-tree.js +3 -0
  13. package/dist/data-structures/binary-tree/binary-tree.d.ts +309 -208
  14. package/dist/data-structures/binary-tree/binary-tree.js +382 -300
  15. package/dist/data-structures/binary-tree/bst.d.ts +245 -127
  16. package/dist/data-structures/binary-tree/bst.js +366 -163
  17. package/dist/data-structures/binary-tree/index.d.ts +3 -1
  18. package/dist/data-structures/binary-tree/index.js +3 -1
  19. package/dist/data-structures/binary-tree/red-black-tree.d.ts +286 -0
  20. package/dist/data-structures/binary-tree/{rb-tree.js → red-black-tree.js} +181 -108
  21. package/dist/data-structures/binary-tree/tree-counter.d.ts +212 -0
  22. package/dist/data-structures/binary-tree/tree-counter.js +444 -0
  23. package/dist/data-structures/binary-tree/tree-multi-map.d.ts +78 -170
  24. package/dist/data-structures/binary-tree/tree-multi-map.js +145 -367
  25. package/dist/data-structures/graph/abstract-graph.js +2 -2
  26. package/dist/data-structures/graph/directed-graph.d.ts +3 -0
  27. package/dist/data-structures/graph/directed-graph.js +3 -0
  28. package/dist/data-structures/graph/map-graph.d.ts +3 -0
  29. package/dist/data-structures/graph/map-graph.js +3 -0
  30. package/dist/data-structures/graph/undirected-graph.d.ts +3 -0
  31. package/dist/data-structures/graph/undirected-graph.js +3 -0
  32. package/dist/data-structures/hash/hash-map.d.ts +31 -1
  33. package/dist/data-structures/hash/hash-map.js +35 -5
  34. package/dist/data-structures/heap/heap.d.ts +26 -9
  35. package/dist/data-structures/heap/heap.js +37 -17
  36. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +64 -19
  37. package/dist/data-structures/linked-list/doubly-linked-list.js +92 -31
  38. package/dist/data-structures/linked-list/singly-linked-list.d.ts +48 -12
  39. package/dist/data-structures/linked-list/singly-linked-list.js +74 -27
  40. package/dist/data-structures/linked-list/skip-linked-list.d.ts +3 -0
  41. package/dist/data-structures/linked-list/skip-linked-list.js +3 -0
  42. package/dist/data-structures/matrix/matrix.d.ts +3 -0
  43. package/dist/data-structures/matrix/matrix.js +3 -0
  44. package/dist/data-structures/matrix/navigator.d.ts +3 -0
  45. package/dist/data-structures/matrix/navigator.js +3 -0
  46. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +3 -0
  47. package/dist/data-structures/priority-queue/max-priority-queue.js +3 -0
  48. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +3 -0
  49. package/dist/data-structures/priority-queue/min-priority-queue.js +3 -0
  50. package/dist/data-structures/queue/deque.d.ts +37 -8
  51. package/dist/data-structures/queue/deque.js +73 -29
  52. package/dist/data-structures/queue/queue.d.ts +41 -1
  53. package/dist/data-structures/queue/queue.js +51 -9
  54. package/dist/data-structures/stack/stack.d.ts +27 -10
  55. package/dist/data-structures/stack/stack.js +39 -20
  56. package/dist/data-structures/trie/trie.d.ts +111 -10
  57. package/dist/data-structures/trie/trie.js +123 -18
  58. package/dist/index.d.ts +2 -1
  59. package/dist/index.js +2 -1
  60. package/dist/interfaces/binary-tree.d.ts +8 -8
  61. package/dist/types/data-structures/base/base.d.ts +1 -1
  62. package/dist/types/data-structures/binary-tree/avl-tree-counter.d.ts +2 -0
  63. package/dist/types/data-structures/binary-tree/avl-tree-counter.js +2 -0
  64. package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -4
  65. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +0 -3
  66. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -4
  67. package/dist/types/data-structures/binary-tree/bst.d.ts +6 -5
  68. package/dist/types/data-structures/binary-tree/index.d.ts +2 -0
  69. package/dist/types/data-structures/binary-tree/index.js +2 -0
  70. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +2 -5
  71. package/dist/types/data-structures/binary-tree/tree-counter.d.ts +2 -0
  72. package/dist/types/data-structures/binary-tree/tree-counter.js +2 -0
  73. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +2 -5
  74. package/dist/types/utils/utils.d.ts +10 -6
  75. package/dist/utils/utils.js +4 -2
  76. package/package.json +2 -2
  77. package/src/common/index.ts +25 -0
  78. package/src/data-structures/base/iterable-entry-base.ts +4 -4
  79. package/src/data-structures/binary-tree/avl-tree-counter.ts +463 -0
  80. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +152 -373
  81. package/src/data-structures/binary-tree/avl-tree.ts +164 -106
  82. package/src/data-structures/binary-tree/binary-indexed-tree.ts +3 -0
  83. package/src/data-structures/binary-tree/binary-tree.ts +563 -447
  84. package/src/data-structures/binary-tree/bst.ts +433 -237
  85. package/src/data-structures/binary-tree/index.ts +3 -1
  86. package/src/data-structures/binary-tree/{rb-tree.ts → red-black-tree.ts} +224 -146
  87. package/src/data-structures/binary-tree/tree-counter.ts +504 -0
  88. package/src/data-structures/binary-tree/tree-multi-map.ts +159 -401
  89. package/src/data-structures/graph/abstract-graph.ts +2 -2
  90. package/src/data-structures/graph/directed-graph.ts +3 -0
  91. package/src/data-structures/graph/map-graph.ts +3 -0
  92. package/src/data-structures/graph/undirected-graph.ts +3 -0
  93. package/src/data-structures/hash/hash-map.ts +37 -7
  94. package/src/data-structures/heap/heap.ts +72 -49
  95. package/src/data-structures/linked-list/doubly-linked-list.ts +186 -118
  96. package/src/data-structures/linked-list/singly-linked-list.ts +81 -28
  97. package/src/data-structures/linked-list/skip-linked-list.ts +3 -0
  98. package/src/data-structures/matrix/matrix.ts +3 -0
  99. package/src/data-structures/matrix/navigator.ts +3 -0
  100. package/src/data-structures/priority-queue/max-priority-queue.ts +3 -0
  101. package/src/data-structures/priority-queue/min-priority-queue.ts +3 -0
  102. package/src/data-structures/queue/deque.ts +72 -28
  103. package/src/data-structures/queue/queue.ts +50 -7
  104. package/src/data-structures/stack/stack.ts +39 -20
  105. package/src/data-structures/trie/trie.ts +123 -17
  106. package/src/index.ts +4 -3
  107. package/src/interfaces/binary-tree.ts +10 -21
  108. package/src/types/data-structures/base/base.ts +1 -1
  109. package/src/types/data-structures/binary-tree/avl-tree-counter.ts +3 -0
  110. package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +1 -6
  111. package/src/types/data-structures/binary-tree/avl-tree.ts +0 -5
  112. package/src/types/data-structures/binary-tree/binary-tree.ts +1 -6
  113. package/src/types/data-structures/binary-tree/bst.ts +8 -7
  114. package/src/types/data-structures/binary-tree/index.ts +3 -1
  115. package/src/types/data-structures/binary-tree/red-black-tree.ts +5 -0
  116. package/src/types/data-structures/binary-tree/tree-counter.ts +3 -0
  117. package/src/types/data-structures/binary-tree/tree-multi-map.ts +2 -7
  118. package/src/types/utils/utils.ts +16 -10
  119. package/src/utils/utils.ts +4 -2
  120. package/dist/data-structures/binary-tree/rb-tree.d.ts +0 -205
  121. package/src/types/data-structures/binary-tree/rb-tree.ts +0 -10
@@ -6,10 +6,8 @@
6
6
  * @license MIT License
7
7
  */
8
8
 
9
- import {
9
+ import type {
10
10
  BinaryTreeDeleteResult,
11
- BinaryTreeNested,
12
- BinaryTreeNodeNested,
13
11
  BinaryTreeOptions,
14
12
  BinaryTreePrintOptions,
15
13
  BTNEntry,
@@ -23,70 +21,104 @@ import {
23
21
  NodeDisplayLayout,
24
22
  NodePredicate,
25
23
  OptNodeOrNull,
24
+ RBTNColor,
26
25
  ToEntryFn
27
26
  } from '../../types';
28
27
  import { IBinaryTree } from '../../interfaces';
29
28
  import { isComparable, trampoline } from '../../utils';
30
29
  import { Queue } from '../queue';
31
30
  import { IterableEntryBase } from '../base';
32
- import { DFSOperation } from '../../constants';
31
+ import { DFSOperation, Range } from '../../common';
33
32
 
34
33
  /**
35
34
  * Represents a node in a binary tree.
36
35
  * @template V - The type of data stored in the node.
37
- * @template NODE - The type of the family relationship in the binary tree.
36
+ * @template BinaryTreeNode<K, V> - The type of the family relationship in the binary tree.
38
37
  */
39
- export class BinaryTreeNode<
40
- K = any,
41
- V = any,
42
- NODE extends BinaryTreeNode<K, V, NODE> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>
43
- > {
44
- key: K;
45
-
46
- value?: V;
47
-
48
- parent?: NODE;
49
-
38
+ export class BinaryTreeNode<K = any, V = any> {
39
+ /**
40
+ * The constructor function initializes an object with a key and an optional value in TypeScript.
41
+ * @param {K} key - The `key` parameter in the constructor function is used to store the key value
42
+ * for the key-value pair.
43
+ * @param {V} [value] - The `value` parameter in the constructor is optional, meaning it does not
44
+ * have to be provided when creating an instance of the class. If a `value` is not provided, it will
45
+ * default to `undefined`.
46
+ */
50
47
  constructor(key: K, value?: V) {
51
48
  this.key = key;
52
49
  this.value = value;
53
50
  }
54
51
 
55
- protected _left?: OptNodeOrNull<NODE>;
52
+ key: K;
53
+
54
+ value?: V;
55
+
56
+ parent?: BinaryTreeNode<K, V> = undefined;
56
57
 
57
- get left(): OptNodeOrNull<NODE> {
58
+ _left?: OptNodeOrNull<BinaryTreeNode<K, V>> = undefined;
59
+
60
+ get left(): OptNodeOrNull<BinaryTreeNode<K, V>> {
58
61
  return this._left;
59
62
  }
60
63
 
61
- set left(v: OptNodeOrNull<NODE>) {
64
+ set left(v: OptNodeOrNull<BinaryTreeNode<K, V>>) {
62
65
  if (v) {
63
- v.parent = this as unknown as NODE;
66
+ v.parent = this as unknown as BinaryTreeNode<K, V>;
64
67
  }
65
68
  this._left = v;
66
69
  }
67
70
 
68
- protected _right?: OptNodeOrNull<NODE>;
71
+ _right?: OptNodeOrNull<BinaryTreeNode<K, V>> = undefined;
69
72
 
70
- get right(): OptNodeOrNull<NODE> {
73
+ get right(): OptNodeOrNull<BinaryTreeNode<K, V>> {
71
74
  return this._right;
72
75
  }
73
76
 
74
- set right(v: OptNodeOrNull<NODE>) {
77
+ set right(v: OptNodeOrNull<BinaryTreeNode<K, V>>) {
75
78
  if (v) {
76
- v.parent = this as unknown as NODE;
79
+ v.parent = this;
77
80
  }
78
81
  this._right = v;
79
82
  }
80
83
 
84
+ _height: number = 0;
85
+
86
+ get height(): number {
87
+ return this._height;
88
+ }
89
+
90
+ set height(value: number) {
91
+ this._height = value;
92
+ }
93
+
94
+ _color: RBTNColor = 'BLACK';
95
+
96
+ get color(): RBTNColor {
97
+ return this._color;
98
+ }
99
+
100
+ set color(value: RBTNColor) {
101
+ this._color = value;
102
+ }
103
+
104
+ _count: number = 1;
105
+
106
+ get count(): number {
107
+ return this._count;
108
+ }
109
+
110
+ set count(value: number) {
111
+ this._count = value;
112
+ }
113
+
81
114
  get familyPosition(): FamilyPosition {
82
- const that = this as unknown as NODE;
83
115
  if (!this.parent) {
84
116
  return this.left || this.right ? 'ROOT' : 'ISOLATED';
85
117
  }
86
118
 
87
- if (this.parent.left === that) {
119
+ if (this.parent.left === this) {
88
120
  return this.left || this.right ? 'ROOT_LEFT' : 'LEFT';
89
- } else if (this.parent.right === that) {
121
+ } else if (this.parent.right === this) {
90
122
  return this.left || this.right ? 'ROOT_RIGHT' : 'RIGHT';
91
123
  }
92
124
 
@@ -101,28 +133,23 @@ export class BinaryTreeNode<
101
133
  * 4. Subtrees: Each child of a node forms the root of a subtree.
102
134
  * 5. Leaf Nodes: Nodes without children are leaves.
103
135
  */
104
- export class BinaryTree<
105
- K = any,
106
- V = any,
107
- R = object,
108
- NODE extends BinaryTreeNode<K, V, NODE> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>,
109
- TREE extends BinaryTree<K, V, R, NODE, TREE> = BinaryTree<K, V, R, NODE, BinaryTreeNested<K, V, R, NODE>>
110
- >
136
+ export class BinaryTree<K = any, V = any, R = object, MK = any, MV = any, MR = object>
111
137
  extends IterableEntryBase<K, V | undefined>
112
- implements IBinaryTree<K, V, R, NODE, TREE>
138
+ implements IBinaryTree<K, V, R, MK, MV, MR>
113
139
  {
114
- iterationType: IterationType = 'ITERATIVE';
115
-
116
140
  /**
117
- * The constructor initializes a binary tree with optional options and adds keys, nodes, entries, or
118
- * raw data if provided.
119
- * @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the constructor
120
- * is an iterable that can contain elements of type `BTNRep<K, V, NODE>` or `R`. It is
121
- * initialized with an empty array `[]` by default.
122
- * @param [options] - The `options` parameter in the constructor is an object that can contain the
123
- * following properties:
141
+ * This TypeScript constructor function initializes a binary tree with optional options and adds
142
+ * elements based on the provided input.
143
+ * @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the constructor is an
144
+ * iterable that can contain either objects of type `BTNRep<K, V, BinaryTreeNode<K, V>>` or `R`. It
145
+ * is used to initialize the binary tree with keys, nodes, entries, or raw data.
146
+ * @param [options] - The `options` parameter in the constructor is an optional object that can
147
+ * contain the following properties:
124
148
  */
125
- constructor(keysNodesEntriesOrRaws: Iterable<BTNRep<K, V, NODE> | R> = [], options?: BinaryTreeOptions<K, V, R>) {
149
+ constructor(
150
+ keysNodesEntriesOrRaws: Iterable<BTNRep<K, V, BinaryTreeNode<K, V>> | R> = [],
151
+ options?: BinaryTreeOptions<K, V, R>
152
+ ) {
126
153
  super();
127
154
  if (options) {
128
155
  const { iterationType, toEntryFn, isMapMode } = options;
@@ -135,6 +162,8 @@ export class BinaryTree<
135
162
  if (keysNodesEntriesOrRaws) this.addMany(keysNodesEntriesOrRaws);
136
163
  }
137
164
 
165
+ iterationType: IterationType = 'ITERATIVE';
166
+
138
167
  protected _isMapMode = true;
139
168
 
140
169
  get isMapMode() {
@@ -147,9 +176,9 @@ export class BinaryTree<
147
176
  return this._store;
148
177
  }
149
178
 
150
- protected _root?: OptNodeOrNull<NODE>;
179
+ protected _root?: OptNodeOrNull<BinaryTreeNode<K, V>>;
151
180
 
152
- get root(): OptNodeOrNull<NODE> {
181
+ get root(): OptNodeOrNull<BinaryTreeNode<K, V>> {
153
182
  return this._root;
154
183
  }
155
184
 
@@ -159,9 +188,9 @@ export class BinaryTree<
159
188
  return this._size;
160
189
  }
161
190
 
162
- protected _NIL: NODE = new BinaryTreeNode<K, V>(NaN as K) as unknown as NODE;
191
+ protected _NIL: BinaryTreeNode<K, V> = new BinaryTreeNode<K, V>(NaN as K) as unknown as BinaryTreeNode<K, V>;
163
192
 
164
- get NIL(): NODE {
193
+ get NIL(): BinaryTreeNode<K, V> {
165
194
  return this._NIL;
166
195
  }
167
196
 
@@ -172,19 +201,25 @@ export class BinaryTree<
172
201
  }
173
202
 
174
203
  /**
204
+ * Time Complexity: O(1)
205
+ * Space Complexity: O(1)
206
+ *
175
207
  * The function creates a new binary tree node with a specified key and optional value.
176
208
  * @param {K} key - The `key` parameter is the key of the node being created in the binary tree.
177
209
  * @param {V} [value] - The `value` parameter in the `createNode` function is optional, meaning it is
178
210
  * not required to be provided when calling the function. If a `value` is provided, it should be of
179
211
  * type `V`, which is the type of the value associated with the node.
180
212
  * @returns A new BinaryTreeNode instance with the provided key and value is being returned, casted
181
- * as NODE.
213
+ * as BinaryTreeNode<K, V>.
182
214
  */
183
- createNode(key: K, value?: V): NODE {
184
- return new BinaryTreeNode<K, V, NODE>(key, this._isMapMode ? undefined : value) as NODE;
215
+ createNode(key: K, value?: V): BinaryTreeNode<K, V> {
216
+ return new BinaryTreeNode<K, V>(key, this._isMapMode ? undefined : value);
185
217
  }
186
218
 
187
219
  /**
220
+ * Time Complexity: O(1)
221
+ * Space Complexity: O(1)
222
+ *
188
223
  * The function creates a binary tree with the specified options.
189
224
  * @param [options] - The `options` parameter in the `createTree` function is an optional parameter
190
225
  * that allows you to provide partial configuration options for creating a binary tree. It is of type
@@ -192,59 +227,13 @@ export class BinaryTree<
192
227
  * of properties
193
228
  * @returns A new instance of a binary tree with the specified options is being returned.
194
229
  */
195
- createTree(options?: BinaryTreeOptions<K, V, R>): TREE {
196
- return new BinaryTree<K, V, R, NODE, TREE>([], {
230
+ createTree(options?: BinaryTreeOptions<K, V, R>) {
231
+ return new BinaryTree<K, V, R, MK, MV, MR>([], {
197
232
  iterationType: this.iterationType,
198
233
  isMapMode: this._isMapMode,
199
234
  toEntryFn: this._toEntryFn,
200
235
  ...options
201
- }) as TREE;
202
- }
203
-
204
- /**
205
- * The function `keyValueNodeEntryRawToNodeAndValue` converts various input types into a node object
206
- * or returns null.
207
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The
208
- * `keyValueNodeEntryRawToNodeAndValue` function takes in a parameter `keyNodeEntryOrRaw`, which
209
- * can be of type `BTNRep<K, V, NODE>` or `R`. This parameter represents either a key, a
210
- * node, an entry
211
- * @param {V} [value] - The `value` parameter in the `keyValueNodeEntryRawToNodeAndValue` function is
212
- * an optional parameter of type `V`. It represents the value associated with the key in the node
213
- * being created. If a `value` is provided, it will be used when creating the node. If
214
- * @returns The `keyValueNodeEntryRawToNodeAndValue` function returns an optional node
215
- * (`OptNodeOrNull<NODE>`) based on the input parameters provided. The function checks the type of the
216
- * input parameter (`keyNodeEntryOrRaw`) and processes it accordingly to return a node or null
217
- * value.
218
- */
219
- keyValueNodeEntryRawToNodeAndValue(
220
- keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
221
- value?: V
222
- ): [OptNodeOrNull<NODE>, V | undefined] {
223
- if (keyNodeEntryOrRaw === undefined) return [undefined, undefined];
224
- if (keyNodeEntryOrRaw === null) return [null, undefined];
225
-
226
- if (this.isNode(keyNodeEntryOrRaw)) return [keyNodeEntryOrRaw, value];
227
-
228
- if (this.isEntry(keyNodeEntryOrRaw)) {
229
- const [key, entryValue] = keyNodeEntryOrRaw;
230
- if (key === undefined) return [undefined, undefined];
231
- else if (key === null) return [null, undefined];
232
- const finalValue = value ?? entryValue;
233
- return [this.createNode(key, finalValue), finalValue];
234
- }
235
-
236
- if (this.isKey(keyNodeEntryOrRaw)) return [this.createNode(keyNodeEntryOrRaw, value), value];
237
-
238
- if (this.isRaw(keyNodeEntryOrRaw)) {
239
- if (this._toEntryFn) {
240
- const [key, entryValue] = this._toEntryFn(keyNodeEntryOrRaw);
241
- const finalValue = value ?? entryValue;
242
- if (this.isKey(key)) return [this.createNode(key, finalValue), finalValue];
243
- }
244
- return [undefined, undefined];
245
- }
246
-
247
- return [undefined, undefined];
236
+ });
248
237
  }
249
238
 
250
239
  /**
@@ -253,8 +242,8 @@ export class BinaryTree<
253
242
  *
254
243
  * The function `ensureNode` in TypeScript checks if a given input is a node, entry, key, or raw
255
244
  * value and returns the corresponding node or null.
256
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The `keyNodeEntryOrRaw`
257
- * parameter in the `ensureNode` function can be of type `BTNRep<K, V, NODE>` or `R`. It
245
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The `keyNodeOrEntry`
246
+ * parameter in the `ensureNode` function can be of type `BTNRep<K, V, BinaryTreeNode<K, V>>` or `R`. It
258
247
  * is used to determine whether the input is a key, node, entry, or raw data. The
259
248
  * @param {IterationType} iterationType - The `iterationType` parameter in the `ensureNode` function
260
249
  * is used to specify the type of iteration to be performed. It has a default value of
@@ -263,131 +252,174 @@ export class BinaryTree<
263
252
  * conditions specified in the code snippet.
264
253
  */
265
254
  ensureNode(
266
- keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
255
+ keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>,
267
256
  iterationType: IterationType = this.iterationType
268
- ): OptNodeOrNull<NODE> {
269
- if (keyNodeEntryOrRaw === null) return null;
270
- if (keyNodeEntryOrRaw === undefined) return;
271
- if (keyNodeEntryOrRaw === this._NIL) return;
272
- if (this.isNode(keyNodeEntryOrRaw)) return keyNodeEntryOrRaw;
273
-
274
- if (this.isEntry(keyNodeEntryOrRaw)) {
275
- const key = keyNodeEntryOrRaw[0];
257
+ ): OptNodeOrNull<BinaryTreeNode<K, V>> {
258
+ if (keyNodeOrEntry === null) return null;
259
+ if (keyNodeOrEntry === undefined) return;
260
+ if (keyNodeOrEntry === this._NIL) return;
261
+
262
+ if (this.isNode(keyNodeOrEntry)) return keyNodeOrEntry;
263
+
264
+ if (this.isEntry(keyNodeOrEntry)) {
265
+ const key = keyNodeOrEntry[0];
276
266
  if (key === null) return null;
277
267
  if (key === undefined) return;
278
- return this.getNodeByKey(key, iterationType);
268
+ return this.getNode(key, this._root, iterationType);
279
269
  }
280
270
 
281
- if (this._toEntryFn) {
282
- const [key] = this._toEntryFn(keyNodeEntryOrRaw as R);
283
- if (this.isKey(key)) return this.getNodeByKey(key);
284
- }
285
-
286
- if (this.isKey(keyNodeEntryOrRaw)) return this.getNodeByKey(keyNodeEntryOrRaw, iterationType);
287
- return;
271
+ return this.getNode(keyNodeOrEntry, this._root, iterationType);
288
272
  }
289
273
 
290
274
  /**
275
+ * Time Complexity: O(1)
276
+ * Space Complexity: O(1)
277
+ *
291
278
  * The function isNode checks if the input is an instance of BinaryTreeNode.
292
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The parameter
293
- * `keyNodeEntryOrRaw` can be either a key, a node, an entry, or raw data. The function is
279
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The parameter
280
+ * `keyNodeOrEntry` can be either a key, a node, an entry, or raw data. The function is
294
281
  * checking if the input is an instance of a `BinaryTreeNode` and returning a boolean value
295
282
  * accordingly.
296
- * @returns The function `isNode` is checking if the input `keyNodeEntryOrRaw` is an instance of
283
+ * @returns The function `isNode` is checking if the input `keyNodeOrEntry` is an instance of
297
284
  * `BinaryTreeNode`. If it is, the function returns `true`, indicating that the input is a node. If
298
285
  * it is not an instance of `BinaryTreeNode`, the function returns `false`, indicating that the input
299
286
  * is not a node.
300
287
  */
301
- isNode(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R): keyNodeEntryOrRaw is NODE {
302
- return keyNodeEntryOrRaw instanceof BinaryTreeNode;
288
+ isNode(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>): keyNodeOrEntry is BinaryTreeNode<K, V> {
289
+ return keyNodeOrEntry instanceof BinaryTreeNode;
303
290
  }
304
291
 
305
- isRaw(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R): keyNodeEntryOrRaw is R {
306
- return typeof keyNodeEntryOrRaw === 'object';
292
+ /**
293
+ * Time Complexity: O(1)
294
+ * Space Complexity: O(1)
295
+ *
296
+ * The function `isRaw` checks if the input parameter is of type `R` by verifying if it is an object.
297
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>> | R} keyNodeEntryOrRaw - BTNRep<K, V, BinaryTreeNode<K, V>>
298
+ * @returns The function `isRaw` is checking if the `keyNodeEntryOrRaw` parameter is of type `R` by
299
+ * checking if it is an object. If the parameter is an object, the function will return `true`,
300
+ * indicating that it is of type `R`.
301
+ */
302
+ isRaw(keyNodeEntryOrRaw: BTNRep<K, V, BinaryTreeNode<K, V>> | R): keyNodeEntryOrRaw is R {
303
+ return this._toEntryFn !== undefined && typeof keyNodeEntryOrRaw === 'object';
307
304
  }
308
305
 
309
306
  /**
307
+ * Time Complexity: O(1)
308
+ * Space Complexity: O(1)
309
+ *
310
310
  * The function `isRealNode` checks if a given input is a valid node in a binary tree.
311
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The `keyNodeEntryOrRaw`
312
- * parameter in the `isRealNode` function can be of type `BTNRep<K, V, NODE>` or `R`.
313
- * The function checks if the input parameter is a `NODE` type by verifying if it is not equal
314
- * @returns The function `isRealNode` is checking if the input `keyNodeEntryOrRaw` is a valid
311
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The `keyNodeOrEntry`
312
+ * parameter in the `isRealNode` function can be of type `BTNRep<K, V, BinaryTreeNode<K, V>>` or `R`.
313
+ * The function checks if the input parameter is a `BinaryTreeNode<K, V>` type by verifying if it is not equal
314
+ * @returns The function `isRealNode` is checking if the input `keyNodeOrEntry` is a valid
315
315
  * node by comparing it to `this._NIL`, `null`, and `undefined`. If the input is not one of these
316
316
  * values, it then calls the `isNode` method to further determine if the input is a node. The
317
317
  * function will return a boolean value indicating whether the
318
318
  */
319
- isRealNode(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R): keyNodeEntryOrRaw is NODE {
320
- if (keyNodeEntryOrRaw === this._NIL || keyNodeEntryOrRaw === null || keyNodeEntryOrRaw === undefined) return false;
321
- return this.isNode(keyNodeEntryOrRaw);
319
+ isRealNode(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>): keyNodeOrEntry is BinaryTreeNode<K, V> {
320
+ if (keyNodeOrEntry === this._NIL || keyNodeOrEntry === null || keyNodeOrEntry === undefined) return false;
321
+ return this.isNode(keyNodeOrEntry);
322
322
  }
323
323
 
324
324
  /**
325
+ * Time Complexity: O(1)
326
+ * Space Complexity: O(1)
327
+ *
325
328
  * The function checks if a given input is a valid node or null.
326
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The parameter
327
- * `keyNodeEntryOrRaw` in the `isRealNodeOrNull` function can be of type `BTNRep<K,
328
- * V, NODE>` or `R`. It is a union type that can either be a key, a node, an entry, or
329
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The parameter
330
+ * `keyNodeOrEntry` in the `isRealNodeOrNull` function can be of type `BTNRep<K,
331
+ * V, BinaryTreeNode<K, V>>` or `R`. It is a union type that can either be a key, a node, an entry, or
329
332
  * @returns The function `isRealNodeOrNull` is returning a boolean value. It checks if the input
330
- * `keyNodeEntryOrRaw` is either `null` or a real node, and returns `true` if it is a node or
333
+ * `keyNodeOrEntry` is either `null` or a real node, and returns `true` if it is a node or
331
334
  * `null`, and `false` otherwise.
332
335
  */
333
- isRealNodeOrNull(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R): keyNodeEntryOrRaw is NODE | null {
334
- return keyNodeEntryOrRaw === null || this.isRealNode(keyNodeEntryOrRaw);
336
+ isRealNodeOrNull(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>): keyNodeOrEntry is BinaryTreeNode<K, V> | null {
337
+ return keyNodeOrEntry === null || this.isRealNode(keyNodeOrEntry);
335
338
  }
336
339
 
337
340
  /**
341
+ * Time Complexity: O(1)
342
+ * Space Complexity: O(1)
343
+ *
338
344
  * The function isNIL checks if a given key, node, entry, or raw value is equal to the _NIL value.
339
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - BTNRep<K, V,
340
- * NODE> | R
341
- * @returns The function is checking if the `keyNodeEntryOrRaw` parameter is equal to the `_NIL`
345
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - BTNRep<K, V,
346
+ * BinaryTreeNode<K, V>>
347
+ * @returns The function is checking if the `keyNodeOrEntry` parameter is equal to the `_NIL`
342
348
  * property of the current object and returning a boolean value based on that comparison.
343
349
  */
344
- isNIL(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R): boolean {
345
- return keyNodeEntryOrRaw === this._NIL;
350
+ isNIL(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>): boolean {
351
+ return keyNodeOrEntry === this._NIL;
352
+ }
353
+
354
+ /**
355
+ * Time Complexity: O(1)
356
+ * Space Complexity: O(1)
357
+ *
358
+ * The function `isRange` checks if the input parameter is an instance of the `Range` class.
359
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>> | Range<K>}
360
+ * keyNodeEntryOrPredicate - The `keyNodeEntryOrPredicate` parameter in the `isRange` function can be
361
+ * of type `BTNRep<K, V, BinaryTreeNode<K, V>>`, `NodePredicate<BinaryTreeNode<K, V>>`, or
362
+ * `Range<K>`. The function checks if the `keyNodeEntry
363
+ * @returns The `isRange` function is checking if the `keyNodeEntryOrPredicate` parameter is an
364
+ * instance of the `Range` class. If it is an instance of `Range`, the function will return `true`,
365
+ * indicating that the parameter is a `Range<K>`. If it is not an instance of `Range`, the function
366
+ * will return `false`.
367
+ */
368
+ isRange(
369
+ keyNodeEntryOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>> | Range<K>
370
+ ): keyNodeEntryOrPredicate is Range<K> {
371
+ return keyNodeEntryOrPredicate instanceof Range;
346
372
  }
347
373
 
348
374
  /**
375
+ * Time Complexity: O(1)
376
+ * Space Complexity: O(1)
377
+ *
349
378
  * The function determines whether a given key, node, entry, or raw data is a leaf node in a binary
350
379
  * tree.
351
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The parameter
352
- * `keyNodeEntryOrRaw` can be of type `BTNRep<K, V, NODE>` or `R`. It represents a
380
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The parameter
381
+ * `keyNodeOrEntry` can be of type `BTNRep<K, V, BinaryTreeNode<K, V>>` or `R`. It represents a
353
382
  * key, node, entry, or raw data in a binary tree structure. The function `isLeaf` checks whether the
354
383
  * provided
355
384
  * @returns The function `isLeaf` returns a boolean value indicating whether the input
356
- * `keyNodeEntryOrRaw` is a leaf node in a binary tree.
385
+ * `keyNodeOrEntry` is a leaf node in a binary tree.
357
386
  */
358
- isLeaf(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R): boolean {
359
- keyNodeEntryOrRaw = this.ensureNode(keyNodeEntryOrRaw);
360
- if (keyNodeEntryOrRaw === undefined) return false;
361
- if (keyNodeEntryOrRaw === null) return true;
362
- return !this.isRealNode(keyNodeEntryOrRaw.left) && !this.isRealNode(keyNodeEntryOrRaw.right);
387
+ isLeaf(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>): boolean {
388
+ keyNodeOrEntry = this.ensureNode(keyNodeOrEntry);
389
+ if (keyNodeOrEntry === undefined) return false;
390
+ if (keyNodeOrEntry === null) return true;
391
+ return !this.isRealNode(keyNodeOrEntry.left) && !this.isRealNode(keyNodeOrEntry.right);
363
392
  }
364
393
 
365
394
  /**
395
+ * Time Complexity: O(1)
396
+ * Space Complexity: O(1)
397
+ *
366
398
  * The function `isEntry` checks if the input is a BTNEntry object by verifying if it is an array
367
399
  * with a length of 2.
368
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The `keyNodeEntryOrRaw`
369
- * parameter in the `isEntry` function can be of type `BTNRep<K, V, NODE>` or type `R`.
370
- * The function checks if the provided `keyNodeEntryOrRaw` is of type `BTN
371
- * @returns The `isEntry` function is checking if the `keyNodeEntryOrRaw` parameter is an array
400
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The `keyNodeOrEntry`
401
+ * parameter in the `isEntry` function can be of type `BTNRep<K, V, BinaryTreeNode<K, V>>` or type `R`.
402
+ * The function checks if the provided `keyNodeOrEntry` is of type `BTN
403
+ * @returns The `isEntry` function is checking if the `keyNodeOrEntry` parameter is an array
372
404
  * with a length of 2. If it is, then it returns `true`, indicating that the parameter is of type
373
405
  * `BTNEntry<K, V>`. If the condition is not met, it returns `false`.
374
406
  */
375
- isEntry(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R): keyNodeEntryOrRaw is BTNEntry<K, V> {
376
- return Array.isArray(keyNodeEntryOrRaw) && keyNodeEntryOrRaw.length === 2;
407
+ isEntry(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>): keyNodeOrEntry is BTNEntry<K, V> {
408
+ return Array.isArray(keyNodeOrEntry) && keyNodeOrEntry.length === 2;
377
409
  }
378
410
 
379
411
  /**
380
412
  * Time Complexity O(1)
381
413
  * Space Complexity O(1)
382
414
  *
383
- * The function `isKey` checks if a given key is comparable.
415
+ * The function `isValidKey` checks if a given key is comparable.
384
416
  * @param {any} key - The `key` parameter is of type `any`, which means it can be any data type in
385
417
  * TypeScript.
386
- * @returns The function `isKey` is checking if the `key` parameter is `null` or if it is comparable.
418
+ * @returns The function `isValidKey` is checking if the `key` parameter is `null` or if it is comparable.
387
419
  * If the `key` is `null`, the function returns `true`. Otherwise, it returns the result of the
388
420
  * `isComparable` function, which is not provided in the code snippet.
389
421
  */
390
- isKey(key: any): key is K {
422
+ isValidKey(key: any): key is K {
391
423
  if (key === null) return true;
392
424
  return isComparable(key);
393
425
  }
@@ -398,8 +430,8 @@ export class BinaryTree<
398
430
  *
399
431
  * The `add` function in TypeScript adds a new node to a binary tree while handling duplicate keys
400
432
  * and finding the correct insertion position.
401
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The `add` method you provided
402
- * seems to be for adding a new node to a binary tree structure. The `keyNodeEntryOrRaw`
433
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The `add` method you provided
434
+ * seems to be for adding a new node to a binary tree structure. The `keyNodeOrEntry`
403
435
  * parameter in the method can accept different types of values:
404
436
  * @param {V} [value] - The `value` parameter in the `add` method represents the value associated
405
437
  * with the key that you want to add to the binary tree. When adding a key-value pair to the binary
@@ -409,8 +441,8 @@ export class BinaryTree<
409
441
  * node was successful, and `false` if the insertion position could not be found or if a duplicate
410
442
  * key was found and the node was replaced instead of inserted.
411
443
  */
412
- add(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R, value?: V): boolean {
413
- const [newNode, newValue] = this.keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
444
+ add(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>, value?: V): boolean {
445
+ const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
414
446
  if (newNode === undefined) return false;
415
447
 
416
448
  // If the tree is empty, directly set the new node as the root node
@@ -421,8 +453,8 @@ export class BinaryTree<
421
453
  return true;
422
454
  }
423
455
 
424
- const queue = new Queue<NODE>([this._root]);
425
- let potentialParent: NODE | undefined; // Record the parent node of the potential insertion location
456
+ const queue = new Queue<BinaryTreeNode<K, V>>([this._root]);
457
+ let potentialParent: BinaryTreeNode<K, V> | undefined; // Record the parent node of the potential insertion location
426
458
 
427
459
  while (queue.size > 0) {
428
460
  const cur = queue.shift();
@@ -467,14 +499,14 @@ export class BinaryTree<
467
499
 
468
500
  /**
469
501
  * Time Complexity: O(k * n)
470
- * Space Complexity: O(1)
502
+ * Space Complexity: O(k)
471
503
  *
472
504
  * The `addMany` function takes in multiple keys or nodes or entries or raw values along with
473
505
  * optional values, and adds them to a data structure while returning an array indicating whether
474
506
  * each insertion was successful.
475
507
  * @param keysNodesEntriesOrRaws - `keysNodesEntriesOrRaws` is an iterable that can contain a
476
508
  * mix of keys, nodes, entries, or raw values. Each element in this iterable can be of type
477
- * `BTNRep<K, V, NODE>` or `R`.
509
+ * `BTNRep<K, V, BinaryTreeNode<K, V>>` or `R`.
478
510
  * @param [values] - The `values` parameter in the `addMany` function is an optional parameter that
479
511
  * accepts an iterable of values. These values correspond to the keys or nodes being added in the
480
512
  * `keysNodesEntriesOrRaws` parameter. If provided, the function will iterate over the values and
@@ -483,7 +515,10 @@ export class BinaryTree<
483
515
  * node, entry, or raw value was successfully added to the data structure. Each boolean value
484
516
  * corresponds to the success of adding the corresponding key or value in the input iterable.
485
517
  */
486
- addMany(keysNodesEntriesOrRaws: Iterable<BTNRep<K, V, NODE> | R>, values?: Iterable<V | undefined>): boolean[] {
518
+ addMany(
519
+ keysNodesEntriesOrRaws: Iterable<BTNRep<K, V, BinaryTreeNode<K, V>> | R>,
520
+ values?: Iterable<V | undefined>
521
+ ): boolean[] {
487
522
  // TODO not sure addMany not be run multi times
488
523
  const inserted: boolean[] = [];
489
524
 
@@ -492,7 +527,7 @@ export class BinaryTree<
492
527
  valuesIterator = values[Symbol.iterator]();
493
528
  }
494
529
 
495
- for (const keyNodeEntryOrRaw of keysNodesEntriesOrRaws) {
530
+ for (let keyNodeEntryOrRaw of keysNodesEntriesOrRaws) {
496
531
  let value: V | undefined | null = undefined;
497
532
 
498
533
  if (valuesIterator) {
@@ -501,13 +536,25 @@ export class BinaryTree<
501
536
  value = valueResult.value;
502
537
  }
503
538
  }
504
-
539
+ if (this.isRaw(keyNodeEntryOrRaw)) keyNodeEntryOrRaw = this._toEntryFn!(keyNodeEntryOrRaw);
505
540
  inserted.push(this.add(keyNodeEntryOrRaw, value));
506
541
  }
507
542
 
508
543
  return inserted;
509
544
  }
510
545
 
546
+ /**
547
+ * Time Complexity: O(k * n)
548
+ * Space Complexity: O(1)
549
+ *
550
+ * The `merge` function in TypeScript merges another binary tree into the current tree by adding all
551
+ * elements from the other tree.
552
+ * @param anotherTree - BinaryTree<K, V, R, MK, MV, MR>
553
+ */
554
+ merge(anotherTree: BinaryTree<K, V, R, MK, MV, MR>) {
555
+ this.addMany(anotherTree, []);
556
+ }
557
+
511
558
  /**
512
559
  * Time Complexity: O(k * n)
513
560
  * Space Complexity: O(1)
@@ -515,12 +562,15 @@ export class BinaryTree<
515
562
  * The `refill` function clears the existing data structure and then adds new key-value pairs based
516
563
  * on the provided input.
517
564
  * @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the `refill`
518
- * method can accept an iterable containing a mix of `BTNRep<K, V, NODE>` objects or `R`
565
+ * method can accept an iterable containing a mix of `BTNRep<K, V, BinaryTreeNode<K, V>>` objects or `R`
519
566
  * objects.
520
567
  * @param [values] - The `values` parameter in the `refill` method is an optional parameter that
521
568
  * accepts an iterable of values of type `V` or `undefined`.
522
569
  */
523
- refill(keysNodesEntriesOrRaws: Iterable<BTNRep<K, V, NODE> | R>, values?: Iterable<V | undefined>): void {
570
+ refill(
571
+ keysNodesEntriesOrRaws: Iterable<BTNRep<K, V, BinaryTreeNode<K, V>> | R>,
572
+ values?: Iterable<V | undefined>
573
+ ): void {
524
574
  this.clear();
525
575
  this.addMany(keysNodesEntriesOrRaws, values);
526
576
  }
@@ -531,7 +581,7 @@ export class BinaryTree<
531
581
  *
532
582
  * The function `delete` in TypeScript implements the deletion of a node in a binary tree and returns
533
583
  * the deleted node along with information for tree balancing.
534
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw
584
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry
535
585
  * - The `delete` method you provided is used to delete a node from a binary tree based on the key,
536
586
  * node, entry or raw data. The method returns an array of
537
587
  * `BinaryTreeDeleteResult` objects containing information about the deleted node and whether
@@ -540,16 +590,16 @@ export class BinaryTree<
540
590
  * the array contains information about the node that was deleted (`deleted`) and the node that may
541
591
  * need to be balanced (`needBalanced`).
542
592
  */
543
- delete(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R): BinaryTreeDeleteResult<NODE>[] {
544
- const deletedResult: BinaryTreeDeleteResult<NODE>[] = [];
593
+ delete(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>): BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[] {
594
+ const deletedResult: BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[] = [];
545
595
  if (!this._root) return deletedResult;
546
596
 
547
- const curr = this.getNode(keyNodeEntryOrRaw);
597
+ const curr = this.getNode(keyNodeOrEntry);
548
598
  if (!curr) return deletedResult;
549
599
 
550
- const parent: NODE | undefined = curr?.parent;
551
- let needBalanced: NODE | undefined;
552
- let orgCurrent: NODE | undefined = curr;
600
+ const parent: BinaryTreeNode<K, V> | undefined = curr?.parent;
601
+ let needBalanced: BinaryTreeNode<K, V> | undefined;
602
+ let orgCurrent: BinaryTreeNode<K, V> | undefined = curr;
553
603
 
554
604
  if (!curr.left && !curr.right && !parent) {
555
605
  this._setRoot(undefined);
@@ -589,41 +639,45 @@ export class BinaryTree<
589
639
  * Time Complexity: O(n)
590
640
  * Space Complexity: O(k + log n)
591
641
  *
592
- * The function `getNodes` retrieves nodes from a binary tree based on a key, node, entry, raw data,
593
- * or predicate, with options for recursive or iterative traversal.
594
- * @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate
595
- * - The `getNodes` function you provided takes several parameters:
596
- * @param [onlyOne=false] - The `onlyOne` parameter in the `getNodes` function is a boolean flag that
597
- * determines whether to return only the first node that matches the criteria specified by the
598
- * `keyNodeEntryRawOrPredicate` parameter. If `onlyOne` is set to `true`, the function will
599
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
600
- * `getNodes` function is used to specify the starting point for traversing the binary tree. It
601
- * represents the root node of the binary tree or the node from which the traversal should begin. If
602
- * not provided, the default value is set to `this._root
603
- * @param {IterationType} iterationType - The `iterationType` parameter in the `getNodes` function
604
- * determines the type of iteration to be performed when traversing the nodes of a binary tree. It
605
- * can have two possible values:
606
- * @returns The `getNodes` function returns an array of nodes that satisfy the provided condition
607
- * based on the input parameters and the iteration type specified.
642
+ * The `search` function in TypeScript performs a depth-first or breadth-first search on a tree
643
+ * structure based on a given predicate or key, with options to return multiple results or just one.
644
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate - The
645
+ * `keyNodeEntryOrPredicate` parameter in the `search` function can accept three types of values:
646
+ * @param [onlyOne=false] - The `onlyOne` parameter in the `search` function is a boolean flag that
647
+ * determines whether the search should stop after finding the first matching node. If `onlyOne` is
648
+ * set to `true`, the search will return as soon as a matching node is found. If `onlyOne` is
649
+ * @param {C} callback - The `callback` parameter in the `search` function is a callback function
650
+ * that will be called on each node that matches the search criteria. It is of type `C`, which
651
+ * extends `NodeCallback<BinaryTreeNode<K, V>>`. The default value for `callback` is `this._DEFAULT_NODE_CALLBACK` if
652
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the `search` function is
653
+ * used to specify the node from which the search operation should begin. It represents the starting
654
+ * point in the binary tree where the search will be performed. If no specific `startNode` is
655
+ * provided, the search operation will start from the root
656
+ * @param {IterationType} iterationType - The `iterationType` parameter in the `search` function
657
+ * specifies the type of iteration to be used when searching for nodes in a binary tree. It can have
658
+ * two possible values:
659
+ * @returns The `search` function returns an array of values that match the provided criteria based
660
+ * on the search algorithm implemented within the function.
608
661
  */
609
- getNodes(
610
- keyNodeEntryRawOrPredicate: BTNRep<K, V, NODE> | R | NodePredicate<NODE>,
662
+ search<C extends NodeCallback<BinaryTreeNode<K, V>>>(
663
+ keyNodeEntryOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>,
611
664
  onlyOne = false,
612
- startNode: BTNRep<K, V, NODE> | R = this._root,
665
+ callback: C = this._DEFAULT_NODE_CALLBACK as C,
666
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
613
667
  iterationType: IterationType = this.iterationType
614
- ): NODE[] {
615
- if (keyNodeEntryRawOrPredicate === undefined) return [];
616
- if (keyNodeEntryRawOrPredicate === null) return [];
668
+ ): ReturnType<C>[] {
669
+ if (keyNodeEntryOrPredicate === undefined) return [];
670
+ if (keyNodeEntryOrPredicate === null) return [];
617
671
  startNode = this.ensureNode(startNode);
618
672
  if (!startNode) return [];
619
- const callback = this._ensurePredicate(keyNodeEntryRawOrPredicate);
673
+ const predicate = this._ensurePredicate(keyNodeEntryOrPredicate);
620
674
 
621
- const ans: NODE[] = [];
675
+ const ans: ReturnType<C>[] = [];
622
676
 
623
677
  if (iterationType === 'RECURSIVE') {
624
- const dfs = (cur: NODE) => {
625
- if (callback(cur)) {
626
- ans.push(cur);
678
+ const dfs = (cur: BinaryTreeNode<K, V>) => {
679
+ if (predicate(cur)) {
680
+ ans.push(callback(cur));
627
681
  if (onlyOne) return;
628
682
  }
629
683
  if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
@@ -637,8 +691,8 @@ export class BinaryTree<
637
691
  while (stack.length > 0) {
638
692
  const cur = stack.pop();
639
693
  if (this.isRealNode(cur)) {
640
- if (callback(cur)) {
641
- ans.push(cur);
694
+ if (predicate(cur)) {
695
+ ans.push(callback(cur));
642
696
  if (onlyOne) return ans;
643
697
  }
644
698
  if (this.isRealNode(cur.left)) stack.push(cur.left);
@@ -652,14 +706,44 @@ export class BinaryTree<
652
706
 
653
707
  /**
654
708
  * Time Complexity: O(n)
655
- * Space Complexity: O(log n).
709
+ * Space Complexity: O(k + log n)
710
+ *
711
+ * The function `getNodes` retrieves nodes from a binary tree based on a key, node, entry, raw data,
712
+ * or predicate, with options for recursive or iterative traversal.
713
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate
714
+ * - The `getNodes` function you provided takes several parameters:
715
+ * @param [onlyOne=false] - The `onlyOne` parameter in the `getNodes` function is a boolean flag that
716
+ * determines whether to return only the first node that matches the criteria specified by the
717
+ * `keyNodeEntryOrPredicate` parameter. If `onlyOne` is set to `true`, the function will
718
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
719
+ * `getNodes` function is used to specify the starting point for traversing the binary tree. It
720
+ * represents the root node of the binary tree or the node from which the traversal should begin. If
721
+ * not provided, the default value is set to `this._root
722
+ * @param {IterationType} iterationType - The `iterationType` parameter in the `getNodes` function
723
+ * determines the type of iteration to be performed when traversing the nodes of a binary tree. It
724
+ * can have two possible values:
725
+ * @returns The `getNodes` function returns an array of nodes that satisfy the provided condition
726
+ * based on the input parameters and the iteration type specified.
727
+ */
728
+ getNodes(
729
+ keyNodeEntryOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>,
730
+ onlyOne = false,
731
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
732
+ iterationType: IterationType = this.iterationType
733
+ ): BinaryTreeNode<K, V>[] {
734
+ return this.search(keyNodeEntryOrPredicate, onlyOne, node => node, startNode, iterationType);
735
+ }
736
+
737
+ /**
738
+ * Time Complexity: O(n)
739
+ * Space Complexity: O(log n)
656
740
  *
657
741
  * The `getNode` function retrieves a node based on the provided key, node, entry, raw data, or
658
742
  * predicate.
659
- * @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate
660
- * - The `keyNodeEntryRawOrPredicate` parameter in the `getNode` function can accept a key,
743
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate
744
+ * - The `keyNodeEntryOrPredicate` parameter in the `getNode` function can accept a key,
661
745
  * node, entry, raw data, or a predicate function.
662
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
746
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
663
747
  * `getNode` function is used to specify the starting point for searching for a node in a binary
664
748
  * tree. If no specific starting point is provided, the default value is set to `this._root`, which
665
749
  * is typically the root node of the binary tree.
@@ -671,28 +755,11 @@ export class BinaryTree<
671
755
  * or `null` if no matching node is found.
672
756
  */
673
757
  getNode(
674
- keyNodeEntryRawOrPredicate: BTNRep<K, V, NODE> | R | NodePredicate<NODE>,
675
- startNode: BTNRep<K, V, NODE> | R = this._root,
758
+ keyNodeEntryOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>,
759
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
676
760
  iterationType: IterationType = this.iterationType
677
- ): OptNodeOrNull<NODE> {
678
- return this.getNodes(keyNodeEntryRawOrPredicate, true, startNode, iterationType)[0] ?? null;
679
- }
680
-
681
- /**
682
- * Time Complexity: O(n)
683
- * Space Complexity: O(log n)
684
- *
685
- * The function `getNodeByKey` retrieves a node by its key from a binary tree structure.
686
- * @param {K} key - The `key` parameter is the value used to search for a specific node in a data
687
- * structure.
688
- * @param {IterationType} iterationType - The `iterationType` parameter is a type of iteration that
689
- * specifies how the tree nodes should be traversed when searching for a node with the given key. It
690
- * is an optional parameter with a default value of `this.iterationType`.
691
- * @returns The `getNodeByKey` function is returning an optional binary tree node
692
- * (`OptNodeOrNull<NODE>`).
693
- */
694
- getNodeByKey(key: K, iterationType: IterationType = this.iterationType): OptNodeOrNull<NODE> {
695
- return this.getNode(key, this._root, iterationType);
761
+ ): OptNodeOrNull<BinaryTreeNode<K, V>> {
762
+ return this.search(keyNodeEntryOrPredicate, true, node => node, startNode, iterationType)[0];
696
763
  }
697
764
 
698
765
  /**
@@ -701,10 +768,10 @@ export class BinaryTree<
701
768
  *
702
769
  * This function overrides the `get` method to retrieve the value associated with a specified key,
703
770
  * node, entry, raw data, or predicate in a data structure.
704
- * @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate
705
- * - The `keyNodeEntryRawOrPredicate` parameter in the `get` method can accept one of the
771
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate
772
+ * - The `keyNodeEntryOrPredicate` parameter in the `get` method can accept one of the
706
773
  * following types:
707
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `get`
774
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the `get`
708
775
  * method is used to specify the starting point for searching for a key or node in the binary tree.
709
776
  * If no specific starting point is provided, the default starting point is the root of the binary
710
777
  * tree (`this._root`).
@@ -718,16 +785,16 @@ export class BinaryTree<
718
785
  * `undefined`.
719
786
  */
720
787
  override get(
721
- keyNodeEntryRawOrPredicate: BTNRep<K, V, NODE> | R,
722
- startNode: BTNRep<K, V, NODE> | R = this._root,
788
+ keyNodeEntryOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>>,
789
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
723
790
  iterationType: IterationType = this.iterationType
724
791
  ): V | undefined {
725
792
  if (this._isMapMode) {
726
- const key = this._getKey(keyNodeEntryRawOrPredicate);
793
+ const key = this._extractKey(keyNodeEntryOrPredicate);
727
794
  if (key === null || key === undefined) return;
728
795
  return this._store.get(key);
729
796
  }
730
- return this.getNode(keyNodeEntryRawOrPredicate, startNode, iterationType)?.value;
797
+ return this.getNode(keyNodeEntryOrPredicate, startNode, iterationType)?.value;
731
798
  }
732
799
 
733
800
  /**
@@ -736,10 +803,10 @@ export class BinaryTree<
736
803
  *
737
804
  * The `has` function in TypeScript checks if a specified key, node, entry, raw data, or predicate
738
805
  * exists in the data structure.
739
- * @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate
740
- * - The `keyNodeEntryRawOrPredicate` parameter in the `override has` method can accept one of
806
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate
807
+ * - The `keyNodeEntryOrPredicate` parameter in the `override has` method can accept one of
741
808
  * the following types:
742
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
809
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
743
810
  * `override` method is used to specify the starting point for the search operation within the data
744
811
  * structure. It defaults to `this._root` if not provided explicitly.
745
812
  * @param {IterationType} iterationType - The `iterationType` parameter in the `override has` method
@@ -752,18 +819,18 @@ export class BinaryTree<
752
819
  * Otherwise, it returns `false`.
753
820
  */
754
821
  override has(
755
- keyNodeEntryRawOrPredicate: BTNRep<K, V, NODE> | R | NodePredicate<NODE>,
756
- startNode: BTNRep<K, V, NODE> | R = this._root,
822
+ keyNodeEntryOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>,
823
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
757
824
  iterationType: IterationType = this.iterationType
758
825
  ): boolean {
759
- return this.getNodes(keyNodeEntryRawOrPredicate, true, startNode, iterationType).length > 0;
826
+ return this.search(keyNodeEntryOrPredicate, true, node => node, startNode, iterationType).length > 0;
760
827
  }
761
828
 
762
829
  /**
763
830
  * Time Complexity: O(1)
764
831
  * Space Complexity: O(1)
765
832
  *
766
- * The `clear` function resets the root node and size of a data structure to empty.
833
+ * The clear function removes nodes and values in map mode.
767
834
  */
768
835
  clear() {
769
836
  this._clearNodes();
@@ -789,7 +856,7 @@ export class BinaryTree<
789
856
  *
790
857
  * The function checks if a binary tree is perfectly balanced by comparing its minimum height with
791
858
  * its height.
792
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter is the starting
859
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter is the starting
793
860
  * point for checking if the binary tree is perfectly balanced. It represents the root node of the
794
861
  * binary tree or a specific node from which the balance check should begin.
795
862
  * @returns The method `isPerfectlyBalanced` is returning a boolean value, which indicates whether
@@ -798,17 +865,17 @@ export class BinaryTree<
798
865
  * height plus 1 is greater than or equal to the height of the tree, then it is considered perfectly
799
866
  * balanced and
800
867
  */
801
- isPerfectlyBalanced(startNode: BTNRep<K, V, NODE> | R = this._root): boolean {
868
+ isPerfectlyBalanced(startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root): boolean {
802
869
  return this.getMinHeight(startNode) + 1 >= this.getHeight(startNode);
803
870
  }
804
871
 
805
872
  /**
806
873
  * Time Complexity: O(n)
807
- * Space Complexity: O(1)
874
+ * Space Complexity: O(log n)
808
875
  *
809
876
  * The function `isBST` in TypeScript checks if a binary search tree is valid using either recursive
810
877
  * or iterative methods.
811
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `isBST`
878
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the `isBST`
812
879
  * function represents the starting point for checking whether a binary search tree (BST) is valid.
813
880
  * It can be a node in the BST or a reference to the root of the BST. If no specific node is
814
881
  * provided, the function will default to
@@ -820,13 +887,16 @@ export class BinaryTree<
820
887
  * the tree satisfies the BST property, where for every node, all nodes in its left subtree have keys
821
888
  * less than the node's key, and all nodes in its right subtree have keys greater than the node's
822
889
  */
823
- isBST(startNode: BTNRep<K, V, NODE> | R = this._root, iterationType: IterationType = this.iterationType): boolean {
890
+ isBST(
891
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
892
+ iterationType: IterationType = this.iterationType
893
+ ): boolean {
824
894
  // TODO there is a bug
825
895
  startNode = this.ensureNode(startNode);
826
896
  if (!startNode) return true;
827
897
 
828
898
  if (iterationType === 'RECURSIVE') {
829
- const dfs = (cur: OptNodeOrNull<NODE>, min: number, max: number): boolean => {
899
+ const dfs = (cur: OptNodeOrNull<BinaryTreeNode<K, V>>, min: number, max: number): boolean => {
830
900
  if (!this.isRealNode(cur)) return true;
831
901
  const numKey = Number(cur.key);
832
902
  if (numKey <= min || numKey >= max) return false;
@@ -841,7 +911,7 @@ export class BinaryTree<
841
911
  const stack = [];
842
912
  let prev = checkMax ? Number.MAX_SAFE_INTEGER : Number.MIN_SAFE_INTEGER;
843
913
  // @ts-ignore
844
- let curr: OptNodeOrNull<NODE> = startNode;
914
+ let curr: OptNodeOrNull<BinaryTreeNode<K, V>> = startNode;
845
915
  while (this.isRealNode(curr) || stack.length > 0) {
846
916
  while (this.isRealNode(curr)) {
847
917
  stack.push(curr);
@@ -863,13 +933,13 @@ export class BinaryTree<
863
933
 
864
934
  /**
865
935
  * Time Complexity: O(n)
866
- * Space Complexity: O(1)
936
+ * Space Complexity: O(log n)
867
937
  *
868
938
  * The `getDepth` function calculates the depth between two nodes in a binary tree.
869
- * @param {BTNRep<K, V, NODE> | R} dist - The `dist` parameter in the `getDepth`
939
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} dist - The `dist` parameter in the `getDepth`
870
940
  * function represents the node or entry in a binary tree map, or a reference to a node in the tree.
871
941
  * It is the target node for which you want to calculate the depth from the `startNode` node.
872
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
942
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
873
943
  * `getDepth` function represents the starting point from which you want to calculate the depth of a
874
944
  * given node or entry in a binary tree. If no specific starting point is provided, the default value
875
945
  * for `startNode` is set to the root of the binary
@@ -877,7 +947,10 @@ export class BinaryTree<
877
947
  * `startNode` node in a binary tree. If the `dist` node is not found in the path to the `startNode`
878
948
  * node, it returns the depth of the `dist` node from the root of the tree.
879
949
  */
880
- getDepth(dist: BTNRep<K, V, NODE> | R, startNode: BTNRep<K, V, NODE> | R = this._root): number {
950
+ getDepth(
951
+ dist: BTNRep<K, V, BinaryTreeNode<K, V>>,
952
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root
953
+ ): number {
881
954
  let distEnsured = this.ensureNode(dist);
882
955
  const beginRootEnsured = this.ensureNode(startNode);
883
956
  let depth = 0;
@@ -893,11 +966,11 @@ export class BinaryTree<
893
966
 
894
967
  /**
895
968
  * Time Complexity: O(n)
896
- * Space Complexity: O(1)
969
+ * Space Complexity: O(log n)
897
970
  *
898
971
  * The `getHeight` function calculates the maximum height of a binary tree using either a recursive
899
972
  * or iterative approach in TypeScript.
900
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter is the starting
973
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter is the starting
901
974
  * point from which the height of the binary tree will be calculated. It can be a node in the binary
902
975
  * tree or a reference to the root of the tree. If not provided, it defaults to the root of the
903
976
  * binary tree data structure.
@@ -908,12 +981,15 @@ export class BinaryTree<
908
981
  * root node. The height is calculated based on the maximum depth of the tree, considering either a
909
982
  * recursive approach or an iterative approach depending on the `iterationType` parameter.
910
983
  */
911
- getHeight(startNode: BTNRep<K, V, NODE> | R = this._root, iterationType: IterationType = this.iterationType): number {
984
+ getHeight(
985
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
986
+ iterationType: IterationType = this.iterationType
987
+ ): number {
912
988
  startNode = this.ensureNode(startNode);
913
989
  if (!this.isRealNode(startNode)) return -1;
914
990
 
915
991
  if (iterationType === 'RECURSIVE') {
916
- const _getMaxHeight = (cur: OptNodeOrNull<NODE>): number => {
992
+ const _getMaxHeight = (cur: OptNodeOrNull<BinaryTreeNode<K, V>>): number => {
917
993
  if (!this.isRealNode(cur)) return -1;
918
994
  const leftHeight = _getMaxHeight(cur.left);
919
995
  const rightHeight = _getMaxHeight(cur.right);
@@ -922,7 +998,7 @@ export class BinaryTree<
922
998
 
923
999
  return _getMaxHeight(startNode);
924
1000
  } else {
925
- const stack: { node: NODE; depth: number }[] = [{ node: startNode, depth: 0 }];
1001
+ const stack: { node: BinaryTreeNode<K, V>; depth: number }[] = [{ node: startNode, depth: 0 }];
926
1002
  let maxHeight = 0;
927
1003
 
928
1004
  while (stack.length > 0) {
@@ -944,7 +1020,7 @@ export class BinaryTree<
944
1020
  *
945
1021
  * The `getMinHeight` function calculates the minimum height of a binary tree using either a
946
1022
  * recursive or iterative approach in TypeScript.
947
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
1023
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
948
1024
  * `getMinHeight` function represents the starting node from which the minimum height of the binary
949
1025
  * tree will be calculated. It is either a node in the binary tree or a reference to the root of the
950
1026
  * tree. If not provided, the default value is the root
@@ -957,14 +1033,14 @@ export class BinaryTree<
957
1033
  * a stack) based on the `iterationType` parameter.
958
1034
  */
959
1035
  getMinHeight(
960
- startNode: BTNRep<K, V, NODE> | R = this._root,
1036
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
961
1037
  iterationType: IterationType = this.iterationType
962
1038
  ): number {
963
1039
  startNode = this.ensureNode(startNode);
964
1040
  if (!startNode) return -1;
965
1041
 
966
1042
  if (iterationType === 'RECURSIVE') {
967
- const _getMinHeight = (cur: OptNodeOrNull<NODE>): number => {
1043
+ const _getMinHeight = (cur: OptNodeOrNull<BinaryTreeNode<K, V>>): number => {
968
1044
  if (!this.isRealNode(cur)) return 0;
969
1045
  if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return 0;
970
1046
  const leftMinHeight = _getMinHeight(cur.left);
@@ -974,10 +1050,10 @@ export class BinaryTree<
974
1050
 
975
1051
  return _getMinHeight(startNode);
976
1052
  } else {
977
- const stack: NODE[] = [];
978
- let node: OptNodeOrNull<NODE> = startNode,
979
- last: OptNodeOrNull<NODE> = null;
980
- const depths: Map<NODE, number> = new Map();
1053
+ const stack: BinaryTreeNode<K, V>[] = [];
1054
+ let node: OptNodeOrNull<BinaryTreeNode<K, V>> = startNode,
1055
+ last: OptNodeOrNull<BinaryTreeNode<K, V>> = null;
1056
+ const depths: Map<BinaryTreeNode<K, V>, number> = new Map();
981
1057
 
982
1058
  while (stack.length > 0 || node) {
983
1059
  if (this.isRealNode(node)) {
@@ -1012,7 +1088,7 @@ export class BinaryTree<
1012
1088
  * the path to the root. It is expected to be a function that takes a node as an argument and returns
1013
1089
  * a value based on that node. The return type of the callback function is determined by the generic
1014
1090
  * type `C
1015
- * @param {BTNRep<K, V, NODE> | R} beginNode - The `beginNode` parameter in the
1091
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} beginNode - The `beginNode` parameter in the
1016
1092
  * `getPathToRoot` function can be either a key, a node, an entry, or any other value of type `R`.
1017
1093
  * @param [isReverse=true] - The `isReverse` parameter in the `getPathToRoot` function determines
1018
1094
  * whether the resulting path from the given `beginNode` to the root should be in reverse order or
@@ -1022,10 +1098,10 @@ export class BinaryTree<
1022
1098
  * array is either in reverse order or in the original order based on the value of the `isReverse`
1023
1099
  * parameter.
1024
1100
  */
1025
- getPathToRoot<C extends NodeCallback<OptNodeOrNull<NODE>>>(
1101
+ getPathToRoot<C extends NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>>(
1102
+ beginNode: BTNRep<K, V, BinaryTreeNode<K, V>>,
1026
1103
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
1027
- beginNode: BTNRep<K, V, NODE> | R,
1028
- isReverse = true
1104
+ isReverse = false
1029
1105
  ): ReturnType<C>[] {
1030
1106
  const result: ReturnType<C>[] = [];
1031
1107
  let beginNodeEnsured = this.ensureNode(beginNode);
@@ -1043,14 +1119,14 @@ export class BinaryTree<
1043
1119
 
1044
1120
  /**
1045
1121
  * Time Complexity: O(log n)
1046
- * Space Complexity: O(1)
1122
+ * Space Complexity: O(log n)
1047
1123
  *
1048
1124
  * The function `getLeftMost` retrieves the leftmost node in a binary tree using either recursive or
1049
1125
  * tail-recursive iteration.
1050
1126
  * @param {C} callback - The `callback` parameter is a function that will be called with the leftmost
1051
1127
  * node of a binary tree or with `undefined` if the tree is empty. It is provided with a default
1052
1128
  * value of `_DEFAULT_NODE_CALLBACK` if not specified.
1053
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
1129
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
1054
1130
  * `getLeftMost` function represents the starting point for finding the leftmost node in a binary
1055
1131
  * tree. It can be either a key, a node, or an entry in the binary tree structure. If no specific
1056
1132
  * starting point is provided, the function will default
@@ -1062,9 +1138,9 @@ export class BinaryTree<
1062
1138
  * `NIL`, it returns the result of the callback function applied to `undefined`. If the `startNode`
1063
1139
  * node is not a real node, it returns the result of the callback
1064
1140
  */
1065
- getLeftMost<C extends NodeCallback<OptNodeOrNull<NODE>>>(
1141
+ getLeftMost<C extends NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>>(
1066
1142
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
1067
- startNode: BTNRep<K, V, NODE> | R = this._root,
1143
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
1068
1144
  iterationType: IterationType = this.iterationType
1069
1145
  ): ReturnType<C> {
1070
1146
  if (this.isNIL(startNode)) return callback(undefined);
@@ -1073,7 +1149,7 @@ export class BinaryTree<
1073
1149
  if (!this.isRealNode(startNode)) return callback(startNode);
1074
1150
 
1075
1151
  if (iterationType === 'RECURSIVE') {
1076
- const dfs = (cur: NODE): NODE => {
1152
+ const dfs = (cur: BinaryTreeNode<K, V>): BinaryTreeNode<K, V> => {
1077
1153
  if (!this.isRealNode(cur.left)) return cur;
1078
1154
  return dfs(cur.left);
1079
1155
  };
@@ -1081,7 +1157,7 @@ export class BinaryTree<
1081
1157
  return callback(dfs(startNode));
1082
1158
  } else {
1083
1159
  // Indirect implementation of iteration using tail recursion optimization
1084
- const dfs = trampoline((cur: NODE): NODE => {
1160
+ const dfs = trampoline((cur: BinaryTreeNode<K, V>): BinaryTreeNode<K, V> => {
1085
1161
  if (!this.isRealNode(cur.left)) return cur;
1086
1162
  return dfs.cont(cur.left);
1087
1163
  });
@@ -1092,15 +1168,15 @@ export class BinaryTree<
1092
1168
 
1093
1169
  /**
1094
1170
  * Time Complexity: O(log n)
1095
- * Space Complexity: O(1)
1171
+ * Space Complexity: O(log n)
1096
1172
  *
1097
1173
  * The function `getRightMost` retrieves the rightmost node in a binary tree using either recursive
1098
1174
  * or iterative traversal methods.
1099
1175
  * @param {C} callback - The `callback` parameter is a function that will be called with the result
1100
- * of finding the rightmost node in a binary tree. It is of type `NodeCallback<OptNodeOrNull<NODE>>`,
1176
+ * of finding the rightmost node in a binary tree. It is of type `NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>`,
1101
1177
  * which means it is a callback function that can accept either an optional binary tree node or null
1102
1178
  * as
1103
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
1179
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
1104
1180
  * `getRightMost` function represents the starting point for finding the rightmost node in a binary
1105
1181
  * tree. It can be either a key, a node, or an entry in the binary tree structure. If no specific
1106
1182
  * starting point is provided, the function will default
@@ -1112,18 +1188,17 @@ export class BinaryTree<
1112
1188
  * the binary tree structure, determined based on the specified iteration type ('RECURSIVE' or
1113
1189
  * other).
1114
1190
  */
1115
- getRightMost<C extends NodeCallback<OptNodeOrNull<NODE>>>(
1191
+ getRightMost<C extends NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>>(
1116
1192
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
1117
- startNode: BTNRep<K, V, NODE> | R = this._root,
1193
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
1118
1194
  iterationType: IterationType = this.iterationType
1119
1195
  ): ReturnType<C> {
1120
1196
  if (this.isNIL(startNode)) return callback(undefined);
1121
- // TODO support get right most by passing key in
1122
1197
  startNode = this.ensureNode(startNode);
1123
1198
  if (!startNode) return callback(startNode);
1124
1199
 
1125
1200
  if (iterationType === 'RECURSIVE') {
1126
- const dfs = (cur: NODE): NODE => {
1201
+ const dfs = (cur: BinaryTreeNode<K, V>): BinaryTreeNode<K, V> => {
1127
1202
  if (!this.isRealNode(cur.right)) return cur;
1128
1203
  return dfs(cur.right);
1129
1204
  };
@@ -1131,7 +1206,7 @@ export class BinaryTree<
1131
1206
  return callback(dfs(startNode));
1132
1207
  } else {
1133
1208
  // Indirect implementation of iteration using tail recursion optimization
1134
- const dfs = trampoline((cur: NODE) => {
1209
+ const dfs = trampoline((cur: BinaryTreeNode<K, V>) => {
1135
1210
  if (!this.isRealNode(cur.right)) return cur;
1136
1211
  return dfs.cont(cur.right);
1137
1212
  });
@@ -1142,20 +1217,20 @@ export class BinaryTree<
1142
1217
 
1143
1218
  /**
1144
1219
  * Time Complexity: O(log n)
1145
- * Space Complexity: O(1)
1220
+ * Space Complexity: O(log n)
1146
1221
  *
1147
1222
  * The function `getPredecessor` in TypeScript returns the predecessor node of a given node in a
1148
1223
  * binary tree.
1149
- * @param {NODE} node - The `getPredecessor` function you provided seems to be attempting to find the
1224
+ * @param {BinaryTreeNode<K, V>} node - The `getPredecessor` function you provided seems to be attempting to find the
1150
1225
  * predecessor of a given node in a binary tree. However, there seems to be a logical issue in the
1151
1226
  * while loop condition that might cause an infinite loop.
1152
- * @returns The `getPredecessor` function returns the predecessor node of the input `NODE` parameter.
1227
+ * @returns The `getPredecessor` function returns the predecessor node of the input `BinaryTreeNode<K, V>` parameter.
1153
1228
  * If the left child of the input node exists, it traverses to the rightmost node of the left subtree
1154
1229
  * to find the predecessor. If the left child does not exist, it returns the input node itself.
1155
1230
  */
1156
- getPredecessor(node: NODE): NODE {
1231
+ getPredecessor(node: BinaryTreeNode<K, V>): BinaryTreeNode<K, V> {
1157
1232
  if (this.isRealNode(node.left)) {
1158
- let predecessor: OptNodeOrNull<NODE> = node.left;
1233
+ let predecessor: OptNodeOrNull<BinaryTreeNode<K, V>> = node.left;
1159
1234
  while (!this.isRealNode(predecessor) || (this.isRealNode(predecessor.right) && predecessor.right !== node)) {
1160
1235
  if (this.isRealNode(predecessor)) {
1161
1236
  predecessor = predecessor.right;
@@ -1169,18 +1244,18 @@ export class BinaryTree<
1169
1244
 
1170
1245
  /**
1171
1246
  * Time Complexity: O(log n)
1172
- * Space Complexity: O(1)
1247
+ * Space Complexity: O(log n)
1173
1248
  *
1174
1249
  * The function `getSuccessor` in TypeScript returns the next node in an in-order traversal of a
1175
1250
  * binary tree.
1176
- * @param {K | NODE | null} [x] - The `getSuccessor` function takes a parameter `x`, which can be of
1177
- * type `K`, `NODE`, or `null`.
1251
+ * @param {K | BinaryTreeNode<K, V> | null} [x] - The `getSuccessor` function takes a parameter `x`, which can be of
1252
+ * type `K`, `BinaryTreeNode<K, V>`, or `null`.
1178
1253
  * @returns The `getSuccessor` function returns the successor node of the input node `x`. If `x` has
1179
1254
  * a right child, the function returns the leftmost node in the right subtree of `x`. If `x` does not
1180
1255
  * have a right child, the function traverses up the parent nodes until it finds a node that is not
1181
1256
  * the right child of its parent, and returns that node
1182
1257
  */
1183
- getSuccessor(x?: K | NODE | null): OptNodeOrNull<NODE> {
1258
+ getSuccessor(x?: K | BinaryTreeNode<K, V> | null): OptNodeOrNull<BinaryTreeNode<K, V>> {
1184
1259
  x = this.ensureNode(x);
1185
1260
  if (!this.isRealNode(x)) return undefined;
1186
1261
 
@@ -1188,7 +1263,7 @@ export class BinaryTree<
1188
1263
  return this.getLeftMost(node => node, x.right);
1189
1264
  }
1190
1265
 
1191
- let y: OptNodeOrNull<NODE> = x.parent;
1266
+ let y: OptNodeOrNull<BinaryTreeNode<K, V>> = x.parent;
1192
1267
  while (this.isRealNode(y) && x === y.right) {
1193
1268
  x = y;
1194
1269
  y = y.parent;
@@ -1196,17 +1271,17 @@ export class BinaryTree<
1196
1271
  return y;
1197
1272
  }
1198
1273
 
1199
- dfs<C extends NodeCallback<NODE>>(
1274
+ dfs<C extends NodeCallback<BinaryTreeNode<K, V>>>(
1200
1275
  callback?: C,
1201
1276
  pattern?: DFSOrderPattern,
1202
- startNode?: BTNRep<K, V, NODE> | R,
1277
+ startNode?: BTNRep<K, V, BinaryTreeNode<K, V>>,
1203
1278
  iterationType?: IterationType
1204
1279
  ): ReturnType<C>[];
1205
1280
 
1206
- dfs<C extends NodeCallback<NODE | null>>(
1281
+ dfs<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(
1207
1282
  callback?: C,
1208
1283
  pattern?: DFSOrderPattern,
1209
- startNode?: BTNRep<K, V, NODE> | R,
1284
+ startNode?: BTNRep<K, V, BinaryTreeNode<K, V>>,
1210
1285
  iterationType?: IterationType,
1211
1286
  includeNull?: boolean
1212
1287
  ): ReturnType<C>[];
@@ -1218,12 +1293,12 @@ export class BinaryTree<
1218
1293
  * The function `dfs` performs a depth-first search traversal on a binary tree structure based on the
1219
1294
  * specified parameters.
1220
1295
  * @param {C} callback - The `callback` parameter is a generic type `C` that extends the
1221
- * `NodeCallback` interface with a type parameter of `OptNodeOrNull<NODE>`. It has a default value of
1296
+ * `NodeCallback` interface with a type parameter of `OptNodeOrNull<BinaryTreeNode<K, V>>`. It has a default value of
1222
1297
  * `this._DEFAULT_NODE_CALLBACK as C`.
1223
1298
  * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `dfs` method specifies the
1224
1299
  * order in which the Depth-First Search (DFS) algorithm should traverse the nodes in the tree. The
1225
1300
  * possible values for the `pattern` parameter are:
1226
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `dfs`
1301
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the `dfs`
1227
1302
  * method is used to specify the starting point for the Depth-First Search traversal. It can be
1228
1303
  * either a `BTNRep` object representing a key, node, or entry in the binary tree map,
1229
1304
  * or it can be a
@@ -1237,10 +1312,10 @@ export class BinaryTree<
1237
1312
  * @returns The `dfs` method is returning an array of the return type specified by the generic type
1238
1313
  * parameter `C`. The return type is determined by the callback function provided to the method.
1239
1314
  */
1240
- dfs<C extends NodeCallback<OptNodeOrNull<NODE>>>(
1315
+ dfs<C extends NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>>(
1241
1316
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
1242
1317
  pattern: DFSOrderPattern = 'IN',
1243
- startNode: BTNRep<K, V, NODE> | R = this._root,
1318
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
1244
1319
  iterationType: IterationType = this.iterationType,
1245
1320
  includeNull = false
1246
1321
  ): ReturnType<C>[] {
@@ -1249,16 +1324,16 @@ export class BinaryTree<
1249
1324
  return this._dfs(callback, pattern, startNode, iterationType, includeNull);
1250
1325
  }
1251
1326
 
1252
- bfs<C extends NodeCallback<NODE>>(
1327
+ bfs<C extends NodeCallback<BinaryTreeNode<K, V>>>(
1253
1328
  callback?: C,
1254
- startNode?: BTNRep<K, V, NODE> | R,
1329
+ startNode?: BTNRep<K, V, BinaryTreeNode<K, V>>,
1255
1330
  iterationType?: IterationType,
1256
1331
  includeNull?: false
1257
1332
  ): ReturnType<C>[];
1258
1333
 
1259
- bfs<C extends NodeCallback<NODE | null>>(
1334
+ bfs<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(
1260
1335
  callback?: C,
1261
- startNode?: BTNRep<K, V, NODE> | R,
1336
+ startNode?: BTNRep<K, V, BinaryTreeNode<K, V>>,
1262
1337
  iterationType?: IterationType,
1263
1338
  includeNull?: true
1264
1339
  ): ReturnType<C>[];
@@ -1271,8 +1346,8 @@ export class BinaryTree<
1271
1346
  * tree, executing a specified callback function on each node visited.
1272
1347
  * @param {C} callback - The `callback` parameter in the `bfs` function is a function that will be
1273
1348
  * called on each node visited during the breadth-first search traversal. It is a generic type `C`
1274
- * that extends the `NodeCallback` type, which takes a parameter of type `NODE` or `null`.
1275
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `bfs`
1349
+ * that extends the `NodeCallback` type, which takes a parameter of type `BinaryTreeNode<K, V>` or `null`.
1350
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the `bfs`
1276
1351
  * function represents the starting point for the breadth-first search traversal in a binary tree. It
1277
1352
  * can be specified as a key, node, or entry in the binary tree structure. If not provided, the
1278
1353
  * default value is the root node of the binary
@@ -1286,19 +1361,21 @@ export class BinaryTree<
1286
1361
  * @returns The `bfs` function returns an array of values that are the result of applying the
1287
1362
  * provided callback function to each node in the binary tree in a breadth-first search manner.
1288
1363
  */
1289
- bfs<C extends NodeCallback<NODE | null>>(
1364
+ bfs<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(
1290
1365
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
1291
- startNode: BTNRep<K, V, NODE> | R = this._root,
1366
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
1292
1367
  iterationType: IterationType = this.iterationType,
1293
1368
  includeNull = false
1294
1369
  ): ReturnType<C>[] {
1295
1370
  startNode = this.ensureNode(startNode);
1296
1371
  if (!startNode) return [];
1297
1372
 
1298
- const ans: ReturnType<NodeCallback<NODE>>[] = [];
1373
+ const ans: ReturnType<NodeCallback<BinaryTreeNode<K, V>>>[] = [];
1299
1374
 
1300
1375
  if (iterationType === 'RECURSIVE') {
1301
- const queue: Queue<OptNodeOrNull<NODE>> = new Queue<OptNodeOrNull<NODE>>([startNode]);
1376
+ const queue: Queue<OptNodeOrNull<BinaryTreeNode<K, V>>> = new Queue<OptNodeOrNull<BinaryTreeNode<K, V>>>([
1377
+ startNode
1378
+ ]);
1302
1379
 
1303
1380
  const dfs = (level: number) => {
1304
1381
  if (queue.size === 0) return;
@@ -1319,7 +1396,7 @@ export class BinaryTree<
1319
1396
 
1320
1397
  dfs(0);
1321
1398
  } else {
1322
- const queue = new Queue<OptNodeOrNull<NODE>>([startNode]);
1399
+ const queue = new Queue<OptNodeOrNull<BinaryTreeNode<K, V>>>([startNode]);
1323
1400
  while (queue.size > 0) {
1324
1401
  const levelSize = queue.size;
1325
1402
 
@@ -1348,7 +1425,7 @@ export class BinaryTree<
1348
1425
  * structure based on a specified callback and iteration type.
1349
1426
  * @param {C} callback - The `callback` parameter is a function that will be called on each leaf node
1350
1427
  * in the binary tree. It is optional and defaults to a default callback function if not provided.
1351
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `leaves`
1428
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the `leaves`
1352
1429
  * method is used to specify the starting point for finding and processing the leaves of a binary
1353
1430
  * tree. It can be provided as either a key, a node, or an entry in the binary tree structure. If not
1354
1431
  * explicitly provided, the default value
@@ -1358,17 +1435,17 @@ export class BinaryTree<
1358
1435
  * @returns The `leaves` method returns an array of values that are the result of applying the
1359
1436
  * provided callback function to each leaf node in the binary tree.
1360
1437
  */
1361
- leaves<C extends NodeCallback<NODE | null>>(
1438
+ leaves<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(
1362
1439
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
1363
- startNode: BTNRep<K, V, NODE> | R = this._root,
1440
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
1364
1441
  iterationType: IterationType = this.iterationType
1365
1442
  ): ReturnType<C>[] {
1366
1443
  startNode = this.ensureNode(startNode);
1367
- const leaves: ReturnType<NodeCallback<NODE>>[] = [];
1444
+ const leaves: ReturnType<NodeCallback<BinaryTreeNode<K, V>>>[] = [];
1368
1445
  if (!this.isRealNode(startNode)) return [];
1369
1446
 
1370
1447
  if (iterationType === 'RECURSIVE') {
1371
- const dfs = (cur: NODE) => {
1448
+ const dfs = (cur: BinaryTreeNode<K, V>) => {
1372
1449
  if (this.isLeaf(cur)) {
1373
1450
  leaves.push(callback(cur));
1374
1451
  }
@@ -1395,16 +1472,16 @@ export class BinaryTree<
1395
1472
  return leaves;
1396
1473
  }
1397
1474
 
1398
- listLevels<C extends NodeCallback<NODE>>(
1475
+ listLevels<C extends NodeCallback<BinaryTreeNode<K, V>>>(
1399
1476
  callback?: C,
1400
- startNode?: BTNRep<K, V, NODE> | R,
1477
+ startNode?: BTNRep<K, V, BinaryTreeNode<K, V>>,
1401
1478
  iterationType?: IterationType,
1402
1479
  includeNull?: false
1403
1480
  ): ReturnType<C>[][];
1404
1481
 
1405
- listLevels<C extends NodeCallback<NODE | null>>(
1482
+ listLevels<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(
1406
1483
  callback?: C,
1407
- startNode?: BTNRep<K, V, NODE> | R,
1484
+ startNode?: BTNRep<K, V, BinaryTreeNode<K, V>>,
1408
1485
  iterationType?: IterationType,
1409
1486
  includeNull?: true
1410
1487
  ): ReturnType<C>[][];
@@ -1418,7 +1495,7 @@ export class BinaryTree<
1418
1495
  * @param {C} callback - The `callback` parameter is a function that will be applied to each node in
1419
1496
  * the binary tree during the traversal. It is used to process each node and determine what
1420
1497
  * information to include in the output for each level of the tree.
1421
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
1498
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
1422
1499
  * `listLevels` function represents the starting point for traversing the binary tree. It can be
1423
1500
  * either a key, a node, or an entry in the binary tree. If not provided, the default value is the
1424
1501
  * root of the binary tree.
@@ -1433,9 +1510,9 @@ export class BinaryTree<
1433
1510
  * level in a binary tree. Each inner array contains the return value of the provided callback
1434
1511
  * function applied to the nodes at that level.
1435
1512
  */
1436
- listLevels<C extends NodeCallback<NODE | null>>(
1513
+ listLevels<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(
1437
1514
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
1438
- startNode: BTNRep<K, V, NODE> | R = this._root,
1515
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
1439
1516
  iterationType: IterationType = this.iterationType,
1440
1517
  includeNull = false
1441
1518
  ): ReturnType<C>[][] {
@@ -1444,7 +1521,7 @@ export class BinaryTree<
1444
1521
  if (!startNode) return levelsNodes;
1445
1522
 
1446
1523
  if (iterationType === 'RECURSIVE') {
1447
- const _recursive = (node: NODE | null, level: number) => {
1524
+ const _recursive = (node: BinaryTreeNode<K, V> | null, level: number) => {
1448
1525
  if (!levelsNodes[level]) levelsNodes[level] = [];
1449
1526
  levelsNodes[level].push(callback(node));
1450
1527
  if (includeNull) {
@@ -1458,7 +1535,7 @@ export class BinaryTree<
1458
1535
 
1459
1536
  _recursive(startNode, 0);
1460
1537
  } else {
1461
- const stack: [NODE | null, number][] = [[startNode, 0]];
1538
+ const stack: [BinaryTreeNode<K, V> | null, number][] = [[startNode, 0]];
1462
1539
 
1463
1540
  while (stack.length > 0) {
1464
1541
  const head = stack.pop()!;
@@ -1488,11 +1565,11 @@ export class BinaryTree<
1488
1565
  * Morris Traversal algorithm with different order patterns.
1489
1566
  * @param {C} callback - The `callback` parameter in the `morris` function is a function that will be
1490
1567
  * called on each node in the binary tree during the traversal. It is of type `C`, which extends the
1491
- * `NodeCallback<NODE>` type. The default value for `callback` is `this._DEFAULT
1568
+ * `NodeCallback<BinaryTreeNode<K, V>>` type. The default value for `callback` is `this._DEFAULT
1492
1569
  * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `morris` function specifies
1493
1570
  * the type of Depth-First Search (DFS) order pattern to traverse the binary tree. The possible
1494
1571
  * values for the `pattern` parameter are:
1495
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `morris`
1572
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the `morris`
1496
1573
  * function is the starting point for the Morris traversal algorithm. It represents the root node of
1497
1574
  * the binary tree or the node from which the traversal should begin. It can be provided as either a
1498
1575
  * key, a node, an entry, or a reference
@@ -1500,19 +1577,19 @@ export class BinaryTree<
1500
1577
  * provided callback function to each node in the binary tree in the specified order pattern (IN,
1501
1578
  * PRE, or POST).
1502
1579
  */
1503
- morris<C extends NodeCallback<NODE>>(
1580
+ morris<C extends NodeCallback<BinaryTreeNode<K, V>>>(
1504
1581
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
1505
1582
  pattern: DFSOrderPattern = 'IN',
1506
- startNode: BTNRep<K, V, NODE> | R = this._root
1583
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root
1507
1584
  ): ReturnType<C>[] {
1508
1585
  startNode = this.ensureNode(startNode);
1509
1586
  if (!startNode) return [];
1510
- const ans: ReturnType<NodeCallback<NODE>>[] = [];
1587
+ const ans: ReturnType<NodeCallback<BinaryTreeNode<K, V>>>[] = [];
1511
1588
 
1512
- let cur: OptNodeOrNull<NODE> = startNode;
1513
- const _reverseEdge = (node: OptNodeOrNull<NODE>) => {
1514
- let pre: OptNodeOrNull<NODE> = null;
1515
- let next: OptNodeOrNull<NODE> = null;
1589
+ let cur: OptNodeOrNull<BinaryTreeNode<K, V>> = startNode;
1590
+ const _reverseEdge = (node: OptNodeOrNull<BinaryTreeNode<K, V>>) => {
1591
+ let pre: OptNodeOrNull<BinaryTreeNode<K, V>> = null;
1592
+ let next: OptNodeOrNull<BinaryTreeNode<K, V>> = null;
1516
1593
  while (node) {
1517
1594
  next = node.right;
1518
1595
  node.right = pre;
@@ -1521,9 +1598,9 @@ export class BinaryTree<
1521
1598
  }
1522
1599
  return pre;
1523
1600
  };
1524
- const _printEdge = (node: OptNodeOrNull<NODE>) => {
1525
- const tail: OptNodeOrNull<NODE> = _reverseEdge(node);
1526
- let cur: OptNodeOrNull<NODE> = tail;
1601
+ const _printEdge = (node: OptNodeOrNull<BinaryTreeNode<K, V>>) => {
1602
+ const tail: OptNodeOrNull<BinaryTreeNode<K, V>> = _reverseEdge(node);
1603
+ let cur: OptNodeOrNull<BinaryTreeNode<K, V>> = tail;
1527
1604
  while (cur) {
1528
1605
  ans.push(callback(cur));
1529
1606
  cur = cur.right;
@@ -1597,8 +1674,13 @@ export class BinaryTree<
1597
1674
  * original tree using breadth-first search (bfs), and adds the nodes to the new tree. If a node in
1598
1675
  * the original tree is null, a null node is added to the cloned tree. If a node
1599
1676
  */
1600
- clone(): TREE {
1677
+ clone() {
1601
1678
  const cloned = this.createTree();
1679
+ this._clone(cloned);
1680
+ return cloned;
1681
+ }
1682
+
1683
+ protected _clone(cloned: BinaryTree<K, V, R, MK, MV, MR>) {
1602
1684
  this.bfs(
1603
1685
  node => {
1604
1686
  if (node === null) cloned.add(null);
@@ -1612,7 +1694,6 @@ export class BinaryTree<
1612
1694
  true
1613
1695
  );
1614
1696
  if (this._isMapMode) cloned._store = this._store;
1615
- return cloned;
1616
1697
  }
1617
1698
 
1618
1699
  /**
@@ -1635,7 +1716,7 @@ export class BinaryTree<
1635
1716
  const newTree = this.createTree();
1636
1717
  let index = 0;
1637
1718
  for (const [key, value] of this) {
1638
- if (predicate.call(thisArg, value, key, index++, this)) {
1719
+ if (predicate.call(thisArg, key, value, index++, this)) {
1639
1720
  newTree.add([key, value]);
1640
1721
  }
1641
1722
  }
@@ -1646,43 +1727,41 @@ export class BinaryTree<
1646
1727
  * Time Complexity: O(n)
1647
1728
  * Space Complexity: O(n)
1648
1729
  *
1649
- * The `map` function iterates over key-value pairs in a tree data structure, applies a callback
1650
- * function to each value, and returns a new tree with the updated values.
1651
- * @param callback - The `callback` parameter in the `map` method is a function that will be called
1652
- * on each entry in the tree. It takes four arguments:
1653
- * @param {any} [thisArg] - The `thisArg` parameter in the `map` function is an optional parameter
1654
- * that specifies the value to be passed as `this` when executing the callback function. If provided,
1655
- * the `thisArg` value will be used as the `this` value within the callback function. If `thisArg
1656
- * @returns The `map` method is returning a new tree with the entries modified by the provided
1657
- * callback function. Each entry in the original tree is passed to the callback function, and the
1658
- * result of the callback function is added to the new tree.
1730
+ * The `map` function in TypeScript creates a new BinaryTree by applying a callback function to each
1731
+ * entry in the original BinaryTree.
1732
+ * @param callback - A function that will be called for each entry in the current binary tree. It
1733
+ * takes the key, value (which can be undefined), and an array containing the mapped key and value as
1734
+ * arguments.
1735
+ * @param [options] - The `options` parameter in the `map` method is of type `BinaryTreeOptions<MK,
1736
+ * MV, MR>`. It is an optional parameter that allows you to specify additional options for the binary
1737
+ * tree being created during the mapping process. These options could include things like custom
1738
+ * comparators, initial
1739
+ * @param {any} [thisArg] - The `thisArg` parameter in the `map` method is used to specify the value
1740
+ * of `this` when executing the `callback` function. It allows you to set the context (value of
1741
+ * `this`) within the callback function. If `thisArg` is provided, it will be passed
1742
+ * @returns The `map` function is returning a new `BinaryTree` instance filled with entries that are
1743
+ * the result of applying the provided `callback` function to each entry in the original tree.
1659
1744
  */
1660
- map(callback: EntryCallback<K, V | undefined, V>, thisArg?: any) {
1661
- const newTree = this.createTree();
1745
+ map(
1746
+ callback: EntryCallback<K, V | undefined, [MK, MV]>,
1747
+ options?: BinaryTreeOptions<MK, MV, MR>,
1748
+ thisArg?: any
1749
+ ): BinaryTree<MK, MV, MR> {
1750
+ const newTree = new BinaryTree<MK, MV, MR>([], options);
1662
1751
  let index = 0;
1663
1752
  for (const [key, value] of this) {
1664
- newTree.add([key, callback.call(thisArg, value, key, index++, this)]);
1753
+ newTree.add(callback.call(thisArg, key, value, index++, this));
1665
1754
  }
1666
1755
  return newTree;
1667
1756
  }
1668
1757
 
1669
- // // TODO Type error, need to return a TREE<NV> that is a value type only for callback function.
1670
- // // map<NV>(callback: (entry: [K, V | undefined], tree: this) => NV) {
1671
- // // const newTree = this.createTree();
1672
- // // for (const [key, value] of this) {
1673
- // // newTree.add(key, callback([key, value], this));
1674
- // // }
1675
- // // return newTree;
1676
- // // }
1677
- //
1678
-
1679
1758
  /**
1680
1759
  * Time Complexity: O(n)
1681
1760
  * Space Complexity: O(n)
1682
1761
  *
1683
1762
  * The function `toVisual` in TypeScript overrides the visual representation of a binary tree with
1684
1763
  * customizable options for displaying undefined, null, and sentinel nodes.
1685
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
1764
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
1686
1765
  * `toVisual` method is used to specify the starting point for visualizing the binary tree structure.
1687
1766
  * It can be a node, key, entry, or the root of the tree. If no specific starting point is provided,
1688
1767
  * the default is set to the root
@@ -1694,7 +1773,10 @@ export class BinaryTree<
1694
1773
  * the lines to the output string. The final output string contains the visual representation of the
1695
1774
  * binary tree with the specified options.
1696
1775
  */
1697
- override toVisual(startNode: BTNRep<K, V, NODE> | R = this._root, options?: BinaryTreePrintOptions): string {
1776
+ override toVisual(
1777
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
1778
+ options?: BinaryTreePrintOptions
1779
+ ): string {
1698
1780
  const opts = { isShowUndefined: false, isShowNull: true, isShowRedBlackNIL: false, ...options };
1699
1781
  startNode = this.ensureNode(startNode);
1700
1782
  let output = '';
@@ -1704,8 +1786,8 @@ export class BinaryTree<
1704
1786
  if (opts.isShowNull) output += `N for null\n`;
1705
1787
  if (opts.isShowRedBlackNIL) output += `S for Sentinel Node(NIL)\n`;
1706
1788
 
1707
- const display = (root: OptNodeOrNull<NODE>): void => {
1708
- const [lines, , ,] = this._displayAux(root, opts);
1789
+ const display = (root: OptNodeOrNull<BinaryTreeNode<K, V>>): void => {
1790
+ const [lines] = this._displayAux(root, opts);
1709
1791
  let paragraph = '';
1710
1792
  for (const line of lines) {
1711
1793
  paragraph += line + '\n';
@@ -1727,15 +1809,53 @@ export class BinaryTree<
1727
1809
  * printing options for the binary tree. It is an optional parameter that allows you to customize how
1728
1810
  * the binary tree is printed, such as choosing between different traversal orders or formatting
1729
1811
  * options.
1730
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
1812
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
1731
1813
  * `override print` method is used to specify the starting point for printing the binary tree. It can
1732
1814
  * be either a key, a node, an entry, or the root of the tree. If no specific starting point is
1733
1815
  * provided, the default value is set to
1734
1816
  */
1735
- override print(options?: BinaryTreePrintOptions, startNode: BTNRep<K, V, NODE> | R = this._root) {
1817
+ override print(options?: BinaryTreePrintOptions, startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root) {
1736
1818
  console.log(this.toVisual(startNode, options));
1737
1819
  }
1738
1820
 
1821
+ /**
1822
+ * Time Complexity: O(1)
1823
+ * Space Complexity: O(1)
1824
+ *
1825
+ * The function `keyValueNodeEntryRawToNodeAndValue` converts various input types into a node object
1826
+ * or returns null.
1827
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The
1828
+ * `keyValueNodeEntryRawToNodeAndValue` function takes in a parameter `keyNodeOrEntry`, which
1829
+ * can be of type `BTNRep<K, V, BinaryTreeNode<K, V>>` or `R`. This parameter represents either a key, a
1830
+ * node, an entry
1831
+ * @param {V} [value] - The `value` parameter in the `keyValueNodeEntryRawToNodeAndValue` function is
1832
+ * an optional parameter of type `V`. It represents the value associated with the key in the node
1833
+ * being created. If a `value` is provided, it will be used when creating the node. If
1834
+ * @returns The `keyValueNodeEntryRawToNodeAndValue` function returns an optional node
1835
+ * (`OptNodeOrNull<BinaryTreeNode<K, V>>`) based on the input parameters provided. The function checks the type of the
1836
+ * input parameter (`keyNodeOrEntry`) and processes it accordingly to return a node or null
1837
+ * value.
1838
+ */
1839
+ protected _keyValueNodeOrEntryToNodeAndValue(
1840
+ keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>,
1841
+ value?: V
1842
+ ): [OptNodeOrNull<BinaryTreeNode<K, V>>, V | undefined] {
1843
+ if (keyNodeOrEntry === undefined) return [undefined, undefined];
1844
+ if (keyNodeOrEntry === null) return [null, undefined];
1845
+
1846
+ if (this.isNode(keyNodeOrEntry)) return [keyNodeOrEntry, value];
1847
+
1848
+ if (this.isEntry(keyNodeOrEntry)) {
1849
+ const [key, entryValue] = keyNodeOrEntry;
1850
+ if (key === undefined) return [undefined, undefined];
1851
+ else if (key === null) return [null, undefined];
1852
+ const finalValue = value ?? entryValue;
1853
+ return [this.createNode(key, finalValue), finalValue];
1854
+ }
1855
+
1856
+ return [this.createNode(keyNodeOrEntry, value), value];
1857
+ }
1858
+
1739
1859
  /**
1740
1860
  * Time complexity: O(n)
1741
1861
  * Space complexity: O(n)
@@ -1744,11 +1864,11 @@ export class BinaryTree<
1744
1864
  * the specified order pattern and callback function.
1745
1865
  * @param {C} callback - The `callback` parameter in the `_dfs` method is a function that will be
1746
1866
  * called on each node visited during the depth-first search traversal. It is of type `C`, which
1747
- * extends `NodeCallback<OptNodeOrNull<NODE>>`. The default value for this parameter is `this._DEFAULT
1867
+ * extends `NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>`. The default value for this parameter is `this._DEFAULT
1748
1868
  * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `_dfs` method specifies the
1749
1869
  * order in which the nodes are visited during the Depth-First Search traversal. It can have one of
1750
1870
  * the following values:
1751
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `_dfs`
1871
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the `_dfs`
1752
1872
  * method is used to specify the starting point for the depth-first search traversal in a binary
1753
1873
  * tree. It can be provided as either a `BTNRep` object or a reference to the root node
1754
1874
  * of the tree. If no specific
@@ -1778,26 +1898,26 @@ export class BinaryTree<
1778
1898
  * @returns The function `_dfs` returns an array of the return type of the callback function provided
1779
1899
  * as input.
1780
1900
  */
1781
- protected _dfs<C extends NodeCallback<OptNodeOrNull<NODE>>>(
1901
+ protected _dfs<C extends NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>>(
1782
1902
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
1783
1903
  pattern: DFSOrderPattern = 'IN',
1784
- startNode: BTNRep<K, V, NODE> | R = this._root,
1904
+ startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
1785
1905
  iterationType: IterationType = this.iterationType,
1786
1906
  includeNull = false,
1787
- shouldVisitLeft: (node: OptNodeOrNull<NODE>) => boolean = node => !!node,
1788
- shouldVisitRight: (node: OptNodeOrNull<NODE>) => boolean = node => !!node,
1789
- shouldVisitRoot: (node: OptNodeOrNull<NODE>) => boolean = node => {
1907
+ shouldVisitLeft: (node: OptNodeOrNull<BinaryTreeNode<K, V>>) => boolean = node => !!node,
1908
+ shouldVisitRight: (node: OptNodeOrNull<BinaryTreeNode<K, V>>) => boolean = node => !!node,
1909
+ shouldVisitRoot: (node: OptNodeOrNull<BinaryTreeNode<K, V>>) => boolean = node => {
1790
1910
  if (includeNull) return this.isRealNodeOrNull(node);
1791
1911
  return this.isRealNode(node);
1792
1912
  },
1793
- shouldProcessRoot: (node: OptNodeOrNull<NODE>) => boolean = node => this.isRealNodeOrNull(node)
1913
+ shouldProcessRoot: (node: OptNodeOrNull<BinaryTreeNode<K, V>>) => boolean = node => this.isRealNodeOrNull(node)
1794
1914
  ): ReturnType<C>[] {
1795
1915
  startNode = this.ensureNode(startNode);
1796
1916
  if (!startNode) return [];
1797
1917
  const ans: ReturnType<C>[] = [];
1798
1918
 
1799
1919
  if (iterationType === 'RECURSIVE') {
1800
- const dfs = (node: OptNodeOrNull<NODE>) => {
1920
+ const dfs = (node: OptNodeOrNull<BinaryTreeNode<K, V>>) => {
1801
1921
  if (!shouldVisitRoot(node)) return;
1802
1922
 
1803
1923
  const visitLeft = () => {
@@ -1828,15 +1948,15 @@ export class BinaryTree<
1828
1948
 
1829
1949
  dfs(startNode);
1830
1950
  } else {
1831
- const stack: DFSStackItem<NODE>[] = [{ opt: DFSOperation.VISIT, node: startNode }];
1951
+ const stack: DFSStackItem<BinaryTreeNode<K, V>>[] = [{ opt: DFSOperation.VISIT, node: startNode }];
1832
1952
 
1833
- const pushLeft = (cur: DFSStackItem<NODE>) => {
1953
+ const pushLeft = (cur: DFSStackItem<BinaryTreeNode<K, V>>) => {
1834
1954
  if (shouldVisitLeft(cur.node)) stack.push({ opt: DFSOperation.VISIT, node: cur.node?.left });
1835
1955
  };
1836
- const pushRight = (cur: DFSStackItem<NODE>) => {
1956
+ const pushRight = (cur: DFSStackItem<BinaryTreeNode<K, V>>) => {
1837
1957
  if (shouldVisitRight(cur.node)) stack.push({ opt: DFSOperation.VISIT, node: cur.node?.right });
1838
1958
  };
1839
- const pushRoot = (cur: DFSStackItem<NODE>) => {
1959
+ const pushRoot = (cur: DFSStackItem<BinaryTreeNode<K, V>>) => {
1840
1960
  if (shouldVisitRoot(cur.node)) stack.push({ opt: DFSOperation.PROCESS, node: cur.node });
1841
1961
  };
1842
1962
 
@@ -1890,8 +2010,8 @@ export class BinaryTree<
1890
2010
  if (!node) return;
1891
2011
 
1892
2012
  if (this.iterationType === 'ITERATIVE') {
1893
- const stack: OptNodeOrNull<NODE>[] = [];
1894
- let current: OptNodeOrNull<NODE> = node;
2013
+ const stack: OptNodeOrNull<BinaryTreeNode<K, V>>[] = [];
2014
+ let current: OptNodeOrNull<BinaryTreeNode<K, V>> = node;
1895
2015
 
1896
2016
  while (current || stack.length > 0) {
1897
2017
  while (this.isRealNode(current)) {
@@ -1934,7 +2054,7 @@ export class BinaryTree<
1934
2054
  * information about how to display a node in a binary tree. The `NodeDisplayLayout` consists of four
1935
2055
  * elements:
1936
2056
  */
1937
- protected _displayAux(node: OptNodeOrNull<NODE>, options: BinaryTreePrintOptions): NodeDisplayLayout {
2057
+ protected _displayAux(node: OptNodeOrNull<BinaryTreeNode<K, V>>, options: BinaryTreePrintOptions): NodeDisplayLayout {
1938
2058
  const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
1939
2059
  const emptyDisplayLayout = <NodeDisplayLayout>[['─'], 1, 0, 0];
1940
2060
 
@@ -2002,24 +2122,27 @@ export class BinaryTree<
2002
2122
  }
2003
2123
  }
2004
2124
 
2005
- protected _DEFAULT_NODE_CALLBACK = (node: OptNodeOrNull<NODE>) => (node ? node.key : undefined);
2125
+ protected _DEFAULT_NODE_CALLBACK = (node: OptNodeOrNull<BinaryTreeNode<K, V>>) => (node ? node.key : undefined);
2006
2126
 
2007
2127
  /**
2008
2128
  * Time Complexity: O(1)
2009
2129
  * Space Complexity: O(1)
2010
2130
  *
2011
2131
  * The _swapProperties function swaps key and value properties between two nodes in a binary tree.
2012
- * @param {BTNRep<K, V, NODE> | R} srcNode - The `srcNode` parameter in the
2132
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} srcNode - The `srcNode` parameter in the
2013
2133
  * `_swapProperties` method can be either a BTNRep object containing key and value
2014
2134
  * properties, or it can be of type R.
2015
- * @param {BTNRep<K, V, NODE> | R} destNode - The `destNode` parameter in the
2135
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} destNode - The `destNode` parameter in the
2016
2136
  * `_swapProperties` method represents the node or entry where the properties will be swapped with
2017
- * the `srcNode`. It can be of type `BTNRep<K, V, NODE>` or `R`. The method ensures that
2137
+ * the `srcNode`. It can be of type `BTNRep<K, V, BinaryTreeNode<K, V>>` or `R`. The method ensures that
2018
2138
  * both `srcNode
2019
2139
  * @returns The `_swapProperties` method returns either the `destNode` with its key and value swapped
2020
2140
  * with the `srcNode`, or `undefined` if either `srcNode` or `destNode` is falsy.
2021
2141
  */
2022
- protected _swapProperties(srcNode: BTNRep<K, V, NODE> | R, destNode: BTNRep<K, V, NODE> | R): NODE | undefined {
2142
+ protected _swapProperties(
2143
+ srcNode: BTNRep<K, V, BinaryTreeNode<K, V>>,
2144
+ destNode: BTNRep<K, V, BinaryTreeNode<K, V>>
2145
+ ): BinaryTreeNode<K, V> | undefined {
2023
2146
  srcNode = this.ensureNode(srcNode);
2024
2147
  destNode = this.ensureNode(destNode);
2025
2148
 
@@ -2045,16 +2168,16 @@ export class BinaryTree<
2045
2168
  * Space Complexity: O(1)
2046
2169
  *
2047
2170
  * The _replaceNode function replaces an old node with a new node in a binary tree structure.
2048
- * @param {NODE} oldNode - The `oldNode` parameter represents the node that you want to replace in a
2171
+ * @param {BinaryTreeNode<K, V>} oldNode - The `oldNode` parameter represents the node that you want to replace in a
2049
2172
  * tree data structure.
2050
- * @param {NODE} newNode - The `newNode` parameter in the `_replaceNode` function represents the node
2173
+ * @param {BinaryTreeNode<K, V>} newNode - The `newNode` parameter in the `_replaceNode` function represents the node
2051
2174
  * that will replace the `oldNode` in a tree data structure. This function is responsible for
2052
2175
  * updating the parent, left child, right child, and root (if necessary) references when replacing a
2053
2176
  * node in the tree.
2054
2177
  * @returns The method `_replaceNode` is returning the `newNode` that was passed as a parameter after
2055
2178
  * replacing the `oldNode` with it in the binary tree structure.
2056
2179
  */
2057
- protected _replaceNode(oldNode: NODE, newNode: NODE): NODE {
2180
+ protected _replaceNode(oldNode: BinaryTreeNode<K, V>, newNode: BinaryTreeNode<K, V>): BinaryTreeNode<K, V> {
2058
2181
  if (oldNode.parent) {
2059
2182
  if (oldNode.parent.left === oldNode) {
2060
2183
  oldNode.parent.left = newNode;
@@ -2078,10 +2201,10 @@ export class BinaryTree<
2078
2201
  *
2079
2202
  * The function _setRoot sets the root node of a data structure while updating the parent reference
2080
2203
  * of the previous root node.
2081
- * @param v - The parameter `v` in the `_setRoot` method is of type `OptNodeOrNull<NODE>`, which means
2082
- * it can either be an optional `NODE` type or `null`.
2204
+ * @param v - The parameter `v` in the `_setRoot` method is of type `OptNodeOrNull<BinaryTreeNode<K, V>>`, which means
2205
+ * it can either be an optional `BinaryTreeNode<K, V>` type or `null`.
2083
2206
  */
2084
- protected _setRoot(v: OptNodeOrNull<NODE>) {
2207
+ protected _setRoot(v: OptNodeOrNull<BinaryTreeNode<K, V>>) {
2085
2208
  if (v) {
2086
2209
  v.parent = undefined;
2087
2210
  }
@@ -2094,34 +2217,29 @@ export class BinaryTree<
2094
2217
  *
2095
2218
  * The function `_ensurePredicate` in TypeScript ensures that the input is converted into a valid
2096
2219
  * predicate function for a binary tree node.
2097
- * @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate - The
2220
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate - The
2098
2221
  * `_ensurePredicate` method in the provided code snippet is responsible for ensuring that the input
2099
- * parameter `keyNodeEntryRawOrPredicate` is transformed into a valid predicate function that can be
2222
+ * parameter `keyNodeEntryOrPredicate` is transformed into a valid predicate function that can be
2100
2223
  * used for filtering nodes in a binary tree.
2101
- * @returns A NodePredicate<NODE> function is being returned.
2224
+ * @returns A NodePredicate<BinaryTreeNode<K, V>> function is being returned.
2102
2225
  */
2103
2226
  protected _ensurePredicate(
2104
- keyNodeEntryRawOrPredicate: BTNRep<K, V, NODE> | R | NodePredicate<NODE>
2105
- ): NodePredicate<NODE> {
2106
- if (keyNodeEntryRawOrPredicate === null || keyNodeEntryRawOrPredicate === undefined)
2107
- return (node: NODE) => (node ? false : false);
2227
+ keyNodeEntryOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>
2228
+ ): NodePredicate<BinaryTreeNode<K, V>> {
2229
+ if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === undefined)
2230
+ return (node: BinaryTreeNode<K, V>) => (node ? false : false);
2108
2231
 
2109
- if (this._isPredicate(keyNodeEntryRawOrPredicate)) return keyNodeEntryRawOrPredicate;
2232
+ if (this._isPredicate(keyNodeEntryOrPredicate)) return keyNodeEntryOrPredicate;
2110
2233
 
2111
- if (this.isRealNode(keyNodeEntryRawOrPredicate)) return (node: NODE) => node === keyNodeEntryRawOrPredicate;
2234
+ if (this.isRealNode(keyNodeEntryOrPredicate))
2235
+ return (node: BinaryTreeNode<K, V>) => node === keyNodeEntryOrPredicate;
2112
2236
 
2113
- if (this.isEntry(keyNodeEntryRawOrPredicate)) {
2114
- const [key] = keyNodeEntryRawOrPredicate;
2115
- return (node: NODE) => node.key === key;
2237
+ if (this.isEntry(keyNodeEntryOrPredicate)) {
2238
+ const [key] = keyNodeEntryOrPredicate;
2239
+ return (node: BinaryTreeNode<K, V>) => node.key === key;
2116
2240
  }
2117
2241
 
2118
- if (this.isKey(keyNodeEntryRawOrPredicate)) return (node: NODE) => node.key === keyNodeEntryRawOrPredicate;
2119
-
2120
- if (this._toEntryFn) {
2121
- const [key] = this._toEntryFn(keyNodeEntryRawOrPredicate);
2122
- return (node: NODE) => node.key === key;
2123
- }
2124
- return (node: NODE) => node.key === keyNodeEntryRawOrPredicate;
2242
+ return (node: BinaryTreeNode<K, V>) => node.key === keyNodeEntryOrPredicate;
2125
2243
  }
2126
2244
 
2127
2245
  /**
@@ -2131,12 +2249,12 @@ export class BinaryTree<
2131
2249
  * The function `_isPredicate` checks if a given parameter is a function.
2132
2250
  * @param {any} p - The parameter `p` is a variable of type `any`, which means it can hold any type
2133
2251
  * of value. In this context, the function `_isPredicate` is checking if `p` is a function that
2134
- * satisfies the type `NodePredicate<NODE>`.
2252
+ * satisfies the type `NodePredicate<BinaryTreeNode<K, V>>`.
2135
2253
  * @returns The function is checking if the input `p` is a function and returning a boolean value
2136
2254
  * based on that check. If `p` is a function, it will return `true`, indicating that `p` is a
2137
2255
  * predicate function for a binary tree node. If `p` is not a function, it will return `false`.
2138
2256
  */
2139
- protected _isPredicate(p: any): p is NodePredicate<NODE> {
2257
+ protected _isPredicate(p: any): p is NodePredicate<BinaryTreeNode<K, V>> {
2140
2258
  return typeof p === 'function';
2141
2259
  }
2142
2260
 
@@ -2144,32 +2262,24 @@ export class BinaryTree<
2144
2262
  * Time Complexity: O(1)
2145
2263
  * Space Complexity: O(1)
2146
2264
  *
2147
- * The function `_getKey` in TypeScript returns the key from a given input, which can be a node,
2265
+ * The function `_extractKey` in TypeScript returns the key from a given input, which can be a node,
2148
2266
  * entry, raw data, or null/undefined.
2149
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The `_getKey` method you provided is a
2150
- * TypeScript method that takes in a parameter `keyNodeEntryOrRaw` of type `BTNRep<K, V, NODE> | R`,
2151
- * where `BTNRep` is a generic type with keys `K`, `V`, and `NODE`, and `
2152
- * @returns The `_getKey` method returns the key value extracted from the `keyNodeEntryOrRaw`
2267
+ * @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The `_extractKey` method you provided is a
2268
+ * TypeScript method that takes in a parameter `keyNodeOrEntry` of type `BTNRep<K, V, BinaryTreeNode<K, V>>`,
2269
+ * where `BTNRep` is a generic type with keys `K`, `V`, and `BinaryTreeNode<K, V>`, and `
2270
+ * @returns The `_extractKey` method returns the key value extracted from the `keyNodeOrEntry`
2153
2271
  * parameter. The return value can be a key value of type `K`, `null`, or `undefined`, depending on
2154
2272
  * the conditions checked in the method.
2155
2273
  */
2156
- protected _getKey(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R): K | null | undefined {
2157
- if (keyNodeEntryOrRaw === null) return null;
2158
- if (keyNodeEntryOrRaw === undefined) return;
2159
- if (keyNodeEntryOrRaw === this._NIL) return;
2160
- if (this.isNode(keyNodeEntryOrRaw)) return keyNodeEntryOrRaw.key;
2161
-
2162
- if (this.isEntry(keyNodeEntryOrRaw)) return keyNodeEntryOrRaw[0];
2163
-
2164
- if (this.isRaw(keyNodeEntryOrRaw)) {
2165
- if (this._toEntryFn) {
2166
- const [key] = this._toEntryFn(keyNodeEntryOrRaw);
2167
- return key;
2168
- }
2169
- return;
2170
- }
2274
+ protected _extractKey(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>): K | null | undefined {
2275
+ if (keyNodeOrEntry === null) return null;
2276
+ if (keyNodeOrEntry === undefined) return;
2277
+ if (keyNodeOrEntry === this._NIL) return;
2278
+ if (this.isNode(keyNodeOrEntry)) return keyNodeOrEntry.key;
2279
+
2280
+ if (this.isEntry(keyNodeOrEntry)) return keyNodeOrEntry[0];
2171
2281
 
2172
- return keyNodeEntryOrRaw;
2282
+ return keyNodeOrEntry;
2173
2283
  }
2174
2284
 
2175
2285
  /**
@@ -2193,6 +2303,9 @@ export class BinaryTree<
2193
2303
  }
2194
2304
 
2195
2305
  /**
2306
+ * Time Complexity: O(1)
2307
+ * Space Complexity: O(1)
2308
+ *
2196
2309
  * The _clearNodes function sets the root node to undefined and resets the size to 0.
2197
2310
  */
2198
2311
  protected _clearNodes() {
@@ -2201,6 +2314,9 @@ export class BinaryTree<
2201
2314
  }
2202
2315
 
2203
2316
  /**
2317
+ * Time Complexity: O(1)
2318
+ * Space Complexity: O(1)
2319
+ *
2204
2320
  * The _clearValues function clears all values stored in the _store object.
2205
2321
  */
2206
2322
  protected _clearValues() {