doubly-linked-list-typed 1.53.9 → 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 (84) hide show
  1. package/dist/data-structures/binary-tree/avl-tree-counter.d.ts +213 -0
  2. package/dist/data-structures/binary-tree/avl-tree-counter.js +407 -0
  3. package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +71 -189
  4. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +133 -357
  5. package/dist/data-structures/binary-tree/avl-tree.d.ts +108 -78
  6. package/dist/data-structures/binary-tree/avl-tree.js +126 -79
  7. package/dist/data-structures/binary-tree/binary-indexed-tree.d.ts +3 -0
  8. package/dist/data-structures/binary-tree/binary-indexed-tree.js +3 -0
  9. package/dist/data-structures/binary-tree/binary-tree.d.ts +243 -190
  10. package/dist/data-structures/binary-tree/binary-tree.js +273 -229
  11. package/dist/data-structures/binary-tree/bst.d.ts +141 -122
  12. package/dist/data-structures/binary-tree/bst.js +170 -134
  13. package/dist/data-structures/binary-tree/index.d.ts +2 -0
  14. package/dist/data-structures/binary-tree/index.js +2 -0
  15. package/dist/data-structures/binary-tree/red-black-tree.d.ts +84 -80
  16. package/dist/data-structures/binary-tree/red-black-tree.js +101 -79
  17. package/dist/data-structures/binary-tree/tree-counter.d.ts +212 -0
  18. package/dist/data-structures/binary-tree/tree-counter.js +444 -0
  19. package/dist/data-structures/binary-tree/tree-multi-map.d.ts +78 -186
  20. package/dist/data-structures/binary-tree/tree-multi-map.js +140 -388
  21. package/dist/data-structures/graph/directed-graph.d.ts +3 -0
  22. package/dist/data-structures/graph/directed-graph.js +3 -0
  23. package/dist/data-structures/graph/map-graph.d.ts +3 -0
  24. package/dist/data-structures/graph/map-graph.js +3 -0
  25. package/dist/data-structures/graph/undirected-graph.d.ts +3 -0
  26. package/dist/data-structures/graph/undirected-graph.js +3 -0
  27. package/dist/data-structures/linked-list/singly-linked-list.d.ts +3 -0
  28. package/dist/data-structures/linked-list/singly-linked-list.js +3 -0
  29. package/dist/data-structures/linked-list/skip-linked-list.d.ts +3 -0
  30. package/dist/data-structures/linked-list/skip-linked-list.js +3 -0
  31. package/dist/data-structures/matrix/matrix.d.ts +3 -0
  32. package/dist/data-structures/matrix/matrix.js +3 -0
  33. package/dist/data-structures/matrix/navigator.d.ts +3 -0
  34. package/dist/data-structures/matrix/navigator.js +3 -0
  35. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +3 -0
  36. package/dist/data-structures/priority-queue/max-priority-queue.js +3 -0
  37. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +3 -0
  38. package/dist/data-structures/priority-queue/min-priority-queue.js +3 -0
  39. package/dist/data-structures/trie/trie.d.ts +0 -4
  40. package/dist/data-structures/trie/trie.js +0 -4
  41. package/dist/interfaces/binary-tree.d.ts +7 -6
  42. package/dist/types/data-structures/binary-tree/avl-tree-counter.d.ts +2 -0
  43. package/dist/types/data-structures/binary-tree/avl-tree-counter.js +2 -0
  44. package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -3
  45. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +0 -2
  46. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +0 -2
  47. package/dist/types/data-structures/binary-tree/bst.d.ts +3 -2
  48. package/dist/types/data-structures/binary-tree/index.d.ts +2 -0
  49. package/dist/types/data-structures/binary-tree/index.js +2 -0
  50. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +1 -3
  51. package/dist/types/data-structures/binary-tree/tree-counter.d.ts +2 -0
  52. package/dist/types/data-structures/binary-tree/tree-counter.js +2 -0
  53. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -3
  54. package/package.json +2 -2
  55. package/src/data-structures/binary-tree/avl-tree-counter.ts +463 -0
  56. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +148 -394
  57. package/src/data-structures/binary-tree/avl-tree.ts +152 -112
  58. package/src/data-structures/binary-tree/binary-indexed-tree.ts +3 -0
  59. package/src/data-structures/binary-tree/binary-tree.ts +446 -379
  60. package/src/data-structures/binary-tree/bst.ts +224 -201
  61. package/src/data-structures/binary-tree/index.ts +2 -0
  62. package/src/data-structures/binary-tree/red-black-tree.ts +138 -114
  63. package/src/data-structures/binary-tree/tree-counter.ts +504 -0
  64. package/src/data-structures/binary-tree/tree-multi-map.ts +156 -428
  65. package/src/data-structures/graph/directed-graph.ts +3 -0
  66. package/src/data-structures/graph/map-graph.ts +3 -0
  67. package/src/data-structures/graph/undirected-graph.ts +3 -0
  68. package/src/data-structures/linked-list/singly-linked-list.ts +3 -0
  69. package/src/data-structures/linked-list/skip-linked-list.ts +3 -0
  70. package/src/data-structures/matrix/matrix.ts +3 -0
  71. package/src/data-structures/matrix/navigator.ts +3 -0
  72. package/src/data-structures/priority-queue/max-priority-queue.ts +3 -0
  73. package/src/data-structures/priority-queue/min-priority-queue.ts +3 -0
  74. package/src/data-structures/trie/trie.ts +0 -4
  75. package/src/interfaces/binary-tree.ts +10 -11
  76. package/src/types/data-structures/binary-tree/avl-tree-counter.ts +3 -0
  77. package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +1 -4
  78. package/src/types/data-structures/binary-tree/avl-tree.ts +0 -3
  79. package/src/types/data-structures/binary-tree/binary-tree.ts +0 -5
  80. package/src/types/data-structures/binary-tree/bst.ts +5 -3
  81. package/src/types/data-structures/binary-tree/index.ts +2 -0
  82. package/src/types/data-structures/binary-tree/rb-tree.ts +1 -4
  83. package/src/types/data-structures/binary-tree/tree-counter.ts +3 -0
  84. package/src/types/data-structures/binary-tree/tree-multi-map.ts +1 -4
@@ -5,8 +5,7 @@
5
5
  * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
6
6
  * @license MIT License
7
7
  */
8
- import {
9
- BSTNodeNested,
8
+ import type {
10
9
  BSTNOptKeyOrNode,
11
10
  BSTOptions,
12
11
  BTNRep,
@@ -18,7 +17,8 @@ import {
18
17
  IterationType,
19
18
  NodeCallback,
20
19
  NodePredicate,
21
- OptNode
20
+ OptNode,
21
+ OptNodeOrNull
22
22
  } from '../../types';
23
23
  import { BinaryTree, BinaryTreeNode } from './binary-tree';
24
24
  import { IBinaryTree } from '../../interfaces';
@@ -26,61 +26,44 @@ import { Queue } from '../queue';
26
26
  import { isComparable } from '../../utils';
27
27
  import { Range } from '../../common';
28
28
 
29
- export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNodeNested<K, V>> extends BinaryTreeNode<
30
- K,
31
- V,
32
- NODE
33
- > {
34
- override parent?: NODE;
35
-
29
+ export class BSTNode<K = any, V = any> extends BinaryTreeNode<K, V> {
30
+ /**
31
+ * This TypeScript constructor function initializes an instance with a key and an optional value.
32
+ * @param {K} key - The `key` parameter is typically used to uniquely identify an object or element
33
+ * within a data structure. It serves as a reference or identifier for accessing or manipulating the
34
+ * associated value.
35
+ * @param {V} [value] - The `value` parameter in the constructor is optional, meaning it does not
36
+ * have to be provided when creating an instance of the class. If a value is not provided, it will
37
+ * default to `undefined`.
38
+ */
36
39
  constructor(key: K, value?: V) {
37
40
  super(key, value);
38
- this.parent = undefined;
39
- this._left = undefined;
40
- this._right = undefined;
41
41
  }
42
42
 
43
- protected override _left?: NODE;
43
+ override parent?: BSTNode<K, V> = undefined;
44
44
 
45
- /**
46
- * The function returns the value of the `_left` property.
47
- * @returns The `_left` property of the current object is being returned.
48
- */
49
- override get left(): OptNode<NODE> {
45
+ override _left?: OptNodeOrNull<BSTNode<K, V>> = undefined;
46
+
47
+ override get left(): OptNodeOrNull<BSTNode<K, V>> {
50
48
  return this._left;
51
49
  }
52
50
 
53
- /**
54
- * The function sets the left child of a node and updates the parent reference of the child.
55
- * @param {OptNode<NODE>} v - The parameter `v` is of type `OptNode<NODE>`. It can either be an
56
- * instance of the `NODE` class or `undefined`.
57
- */
58
- override set left(v: OptNode<NODE>) {
51
+ override set left(v: OptNodeOrNull<BSTNode<K, V>>) {
59
52
  if (v) {
60
- v.parent = this as unknown as NODE;
53
+ v.parent = this;
61
54
  }
62
55
  this._left = v;
63
56
  }
64
57
 
65
- protected override _right?: NODE;
58
+ override _right?: OptNodeOrNull<BSTNode<K, V>> = undefined;
66
59
 
67
- /**
68
- * The function returns the right node of a binary tree or undefined if there is no right node.
69
- * @returns The method is returning the value of the `_right` property, which is of type `NODE` or
70
- * `undefined`.
71
- */
72
- override get right(): OptNode<NODE> {
60
+ override get right(): OptNodeOrNull<BSTNode<K, V>> {
73
61
  return this._right;
74
62
  }
75
63
 
76
- /**
77
- * The function sets the right child of a node and updates the parent reference of the child.
78
- * @param {OptNode<NODE>} v - The parameter `v` is of type `OptNode<NODE>`. It can either be a
79
- * `NODE` object or `undefined`.
80
- */
81
- override set right(v: OptNode<NODE>) {
64
+ override set right(v: OptNodeOrNull<BSTNode<K, V>>) {
82
65
  if (v) {
83
- v.parent = this as unknown as NODE;
66
+ v.parent = this;
84
67
  }
85
68
  this._right = v;
86
69
  }
@@ -151,19 +134,20 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
151
134
  * console.log(findLCA(5, 35)); // 15
152
135
  * console.log(findLCA(20, 30)); // 25
153
136
  */
154
- export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE> = BSTNode<K, V, BSTNodeNested<K, V>>>
155
- extends BinaryTree<K, V, R, NODE>
156
- implements IBinaryTree<K, V, R, NODE>
137
+ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
138
+ extends BinaryTree<K, V, R, MK, MV, MR>
139
+ implements IBinaryTree<K, V, R, MK, MV, MR>
157
140
  {
158
141
  /**
159
- * This is the constructor function for a Binary Search Tree class in TypeScript.
160
- * @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter is an
161
- * iterable that can contain either keys, nodes, entries, or raw elements. These elements will be
162
- * added to the binary search tree during the construction of the object.
163
- * @param [options] - An optional object that contains additional options for the Binary Search Tree.
164
- * It can include a comparator function that defines the order of the elements in the tree.
142
+ * This TypeScript constructor initializes a binary search tree with optional options and adds
143
+ * elements if provided.
144
+ * @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the constructor is an
145
+ * iterable that can contain elements of type `BTNRep<K, V, BSTNode<K, V>>` or `R`. It is used to
146
+ * initialize the binary search tree with keys, nodes, entries, or raw data.
147
+ * @param [options] - The `options` parameter is an optional object that can contain the following
148
+ * properties:
165
149
  */
166
- constructor(keysNodesEntriesOrRaws: Iterable<R | BTNRep<K, V, NODE>> = [], options?: BSTOptions<K, V, R>) {
150
+ constructor(keysNodesEntriesOrRaws: Iterable<BTNRep<K, V, BSTNode<K, V>> | R> = [], options?: BSTOptions<K, V, R>) {
167
151
  super([], options);
168
152
 
169
153
  if (options) {
@@ -175,23 +159,14 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
175
159
  if (keysNodesEntriesOrRaws) this.addMany(keysNodesEntriesOrRaws);
176
160
  }
177
161
 
178
- protected override _root?: NODE = undefined;
162
+ protected override _root?: BSTNode<K, V> = undefined;
179
163
 
180
- /**
181
- * The function returns the root node of a tree structure.
182
- * @returns The `_root` property of the object, which is of type `NODE` or `undefined`.
183
- */
184
- override get root(): OptNode<NODE> {
164
+ override get root(): OptNode<BSTNode<K, V>> {
185
165
  return this._root;
186
166
  }
187
167
 
188
168
  protected _isReverse: boolean = false;
189
169
 
190
- /**
191
- * The above function is a getter method in TypeScript that returns the value of the private property
192
- * `_isReverse`.
193
- * @returns The `isReverse` property of the object, which is a boolean value.
194
- */
195
170
  get isReverse(): boolean {
196
171
  return this._isReverse;
197
172
  }
@@ -216,51 +191,43 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
216
191
  return 0;
217
192
  };
218
193
 
219
- /**
220
- * The function returns the value of the _comparator property.
221
- * @returns The `_comparator` property is being returned.
222
- */
223
194
  get comparator() {
224
195
  return this._comparator;
225
196
  }
226
197
 
227
198
  protected _specifyComparable?: (key: K) => Comparable;
228
199
 
229
- /**
230
- * This function returns the value of the `_specifyComparable` property.
231
- * @returns The method `specifyComparable()` is being returned, which is a getter method for the
232
- * `_specifyComparable` property.
233
- */
234
200
  get specifyComparable() {
235
201
  return this._specifyComparable;
236
202
  }
237
203
 
238
204
  /**
205
+ * Time Complexity: O(1)
206
+ * Space Complexity: O(1)
207
+ *
239
208
  * The function creates a new BSTNode with the given key and value and returns it.
240
209
  * @param {K} key - The key parameter is of type K, which represents the type of the key for the node
241
210
  * being created.
242
211
  * @param {V} [value] - The "value" parameter is an optional parameter of type V. It represents the
243
212
  * value associated with the key in the node being created.
244
- * @returns The method is returning a new instance of the BSTNode class, casted as the NODE type.
213
+ * @returns The method is returning a new instance of the BSTNode class, casted as the BSTNode<K, V> type.
245
214
  */
246
- override createNode(key: K, value?: V): NODE {
247
- return new BSTNode<K, V, NODE>(key, this._isMapMode ? undefined : value) as NODE;
215
+ override createNode(key: K, value?: V): BSTNode<K, V> {
216
+ return new BSTNode<K, V>(key, this._isMapMode ? undefined : value);
248
217
  }
249
218
 
250
219
  /**
251
220
  * Time Complexity: O(1)
252
221
  * Space Complexity: O(1)
253
222
  *
254
- * The `createTree` function in TypeScript overrides the default options with the provided options to
255
- * create a new Binary Search Tree.
256
- * @param [options] - The `options` parameter in the `createTree` method is an optional object that
257
- * can contain the following properties:
258
- * @returns A new instance of a Binary Search Tree (BST) is being returned with the specified options
259
- * and properties inherited from the current instance.
223
+ * The function creates a new binary search tree with the specified options.
224
+ * @param [options] - The `options` parameter is an optional object that allows you to customize the
225
+ * behavior of the `createTree` method. It accepts a partial `BSTOptions` object, which has the
226
+ * following properties:
227
+ * @returns a new instance of the BST class with the provided options.
260
228
  */
261
- // @ts-ignore
262
229
  override createTree(options?: BSTOptions<K, V, R>) {
263
- return new BST<K, V, R>([], {
230
+ return new BST<K, V, R, MK, MV, MR>([], {
264
231
  iterationType: this.iterationType,
265
232
  isMapMode: this._isMapMode,
266
233
  specifyComparable: this._specifyComparable,
@@ -276,8 +243,8 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
276
243
  *
277
244
  * The function ensures the existence of a node in a data structure and returns it, or undefined if
278
245
  * it doesn't exist.
279
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The parameter
280
- * `keyNodeEntryOrRaw` can accept a value of type `R`, which represents the key, node,
246
+ * @param {BTNRep<K, V, BSTNode<K, V>>} keyNodeOrEntry - The parameter
247
+ * `keyNodeOrEntry` can accept a value of type `R`, which represents the key, node,
281
248
  * entry, or raw element that needs to be ensured in the tree.
282
249
  * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional
283
250
  * parameter that specifies the type of iteration to be used when ensuring a node. It has a default
@@ -286,48 +253,54 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
286
253
  * not be ensured.
287
254
  */
288
255
  override ensureNode(
289
- keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
256
+ keyNodeOrEntry: BTNRep<K, V, BSTNode<K, V>>,
290
257
  iterationType: IterationType = this.iterationType
291
- ): OptNode<NODE> {
292
- return super.ensureNode(keyNodeEntryOrRaw, iterationType) ?? undefined;
258
+ ): OptNode<BSTNode<K, V>> {
259
+ return super.ensureNode(keyNodeOrEntry, iterationType) ?? undefined;
293
260
  }
294
261
 
295
262
  /**
263
+ * Time Complexity: O(1)
264
+ * Space Complexity: O(1)
265
+ *
296
266
  * The function checks if the input is an instance of the BSTNode class.
297
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The parameter
298
- * `keyNodeEntryOrRaw` can be of type `R` or `BTNRep<K, V, NODE>`.
299
- * @returns a boolean value indicating whether the input parameter `keyNodeEntryOrRaw` is
267
+ * @param {BTNRep<K, V, BSTNode<K, V>>} keyNodeOrEntry - The parameter
268
+ * `keyNodeOrEntry` can be of type `R` or `BTNRep<K, V, BSTNode<K, V>>`.
269
+ * @returns a boolean value indicating whether the input parameter `keyNodeOrEntry` is
300
270
  * an instance of the `BSTNode` class.
301
271
  */
302
- override isNode(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R): keyNodeEntryOrRaw is NODE {
303
- return keyNodeEntryOrRaw instanceof BSTNode;
272
+ override isNode(keyNodeOrEntry: BTNRep<K, V, BSTNode<K, V>>): keyNodeOrEntry is BSTNode<K, V> {
273
+ return keyNodeOrEntry instanceof BSTNode;
304
274
  }
305
275
 
306
276
  /**
307
- * The function "override isKey" checks if a key is comparable based on a given comparator.
277
+ * Time Complexity: O(1)
278
+ * Space Complexity: O(1)
279
+ *
280
+ * The function "override isValidKey" checks if a key is comparable based on a given comparator.
308
281
  * @param {any} key - The `key` parameter is a value that will be checked to determine if it is of
309
282
  * type `K`.
310
- * @returns The `override isKey(key: any): key is K` function is returning a boolean value based on
283
+ * @returns The `override isValidKey(key: any): key is K` function is returning a boolean value based on
311
284
  * the result of the `isComparable` function with the condition `this._compare !==
312
285
  * this._DEFAULT_COMPARATOR`.
313
286
  */
314
- override isKey(key: any): key is K {
287
+ override isValidKey(key: any): key is K {
315
288
  return isComparable(key, this._specifyComparable !== undefined);
316
289
  }
317
290
 
318
291
  /**
319
292
  * Time Complexity: O(log n)
320
- * Space Complexity: O(1)
293
+ * Space Complexity: O(log n)
321
294
  *
322
295
  * The `add` function in TypeScript adds a new node to a binary search tree based on the key value.
323
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The parameter
324
- * `keyNodeEntryOrRaw` can accept a value of type `R` or `BTNRep<K, V, NODE>`.
296
+ * @param {BTNRep<K, V, BSTNode<K, V>>} keyNodeOrEntry - The parameter
297
+ * `keyNodeOrEntry` can accept a value of type `R` or `BTNRep<K, V, BSTNode<K, V>>`.
325
298
  * @param {V} [value] - The `value` parameter is an optional value that can be associated with the
326
299
  * key in the binary search tree. If provided, it will be stored in the node along with the key.
327
300
  * @returns a boolean value.
328
301
  */
329
- override add(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R, value?: V): boolean {
330
- const [newNode, newValue] = this._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
302
+ override add(keyNodeOrEntry: BTNRep<K, V, BSTNode<K, V>>, value?: V): boolean {
303
+ const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
331
304
  if (newNode === undefined) return false;
332
305
 
333
306
  if (this._root === undefined) {
@@ -350,7 +323,7 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
350
323
  this._size++;
351
324
  return true;
352
325
  }
353
- current = current.left;
326
+ if (current.left !== null) current = current.left;
354
327
  } else {
355
328
  if (current.right === undefined) {
356
329
  current.right = newNode;
@@ -358,7 +331,7 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
358
331
  this._size++;
359
332
  return true;
360
333
  }
361
- current = current.right;
334
+ if (current.right !== null) current = current.right;
362
335
  }
363
336
  }
364
337
 
@@ -387,7 +360,7 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
387
360
  * successfully inserted into the data structure.
388
361
  */
389
362
  override addMany(
390
- keysNodesEntriesOrRaws: Iterable<R | BTNRep<K, V, NODE>>,
363
+ keysNodesEntriesOrRaws: Iterable<R | BTNRep<K, V, BSTNode<K, V>>>,
391
364
  values?: Iterable<V | undefined>,
392
365
  isBalanceAdd = true,
393
366
  iterationType: IterationType = this.iterationType
@@ -401,15 +374,16 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
401
374
  }
402
375
 
403
376
  if (!isBalanceAdd) {
404
- for (const kve of keysNodesEntriesOrRaws) {
377
+ for (let kve of keysNodesEntriesOrRaws) {
405
378
  const value = valuesIterator?.next().value;
379
+ if (this.isRaw(kve)) kve = this._toEntryFn!(kve);
406
380
  inserted.push(this.add(kve, value));
407
381
  }
408
382
  return inserted;
409
383
  }
410
384
 
411
385
  const realBTNExemplars: {
412
- key: R | BTNRep<K, V, NODE>;
386
+ key: R | BTNRep<K, V, BSTNode<K, V>>;
413
387
  value: V | undefined;
414
388
  orgIndex: number;
415
389
  }[] = [];
@@ -420,23 +394,21 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
420
394
  i++;
421
395
  }
422
396
 
423
- let sorted: { key: R | BTNRep<K, V, NODE>; value: V | undefined; orgIndex: number }[] = [];
397
+ let sorted: { key: R | BTNRep<K, V, BSTNode<K, V>>; value: V | undefined; orgIndex: number }[] = [];
424
398
 
425
399
  sorted = realBTNExemplars.sort(({ key: a }, { key: b }) => {
426
400
  let keyA: K | undefined | null, keyB: K | undefined | null;
427
- if (this.isEntry(a)) keyA = a[0];
401
+ if (this.isRaw(a)) keyA = this._toEntryFn!(a)[0];
402
+ else if (this.isEntry(a)) keyA = a[0];
428
403
  else if (this.isRealNode(a)) keyA = a.key;
429
- else if (this._toEntryFn) {
430
- keyA = this._toEntryFn(a as R)[0];
431
- } else {
404
+ else {
432
405
  keyA = a as K;
433
406
  }
434
407
 
435
- if (this.isEntry(b)) keyB = b[0];
408
+ if (this.isRaw(b)) keyB = this._toEntryFn!(b)[0];
409
+ else if (this.isEntry(b)) keyB = b[0];
436
410
  else if (this.isRealNode(b)) keyB = b.key;
437
- else if (this._toEntryFn) {
438
- keyB = this._toEntryFn(b as R)[0];
439
- } else {
411
+ else {
440
412
  keyB = b as K;
441
413
  }
442
414
 
@@ -446,11 +418,17 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
446
418
  return 0;
447
419
  });
448
420
 
449
- const _dfs = (arr: { key: R | BTNRep<K, V, NODE>; value: V | undefined; orgIndex: number }[]) => {
421
+ const _dfs = (arr: { key: R | BTNRep<K, V, BSTNode<K, V>>; value: V | undefined; orgIndex: number }[]) => {
450
422
  if (arr.length === 0) return;
451
423
 
452
424
  const mid = Math.floor((arr.length - 1) / 2);
453
- const { key, value, orgIndex } = arr[mid];
425
+ let { key, value } = arr[mid];
426
+ const { orgIndex } = arr[mid];
427
+ if (this.isRaw(key)) {
428
+ const entry = this._toEntryFn!(key);
429
+ key = entry[0];
430
+ value = entry[1] ?? value;
431
+ }
454
432
  inserted[orgIndex] = this.add(key, value);
455
433
  _dfs(arr.slice(0, mid));
456
434
  _dfs(arr.slice(mid + 1));
@@ -465,7 +443,13 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
465
443
  const [l, r] = popped;
466
444
  if (l <= r) {
467
445
  const m = l + Math.floor((r - l) / 2);
468
- const { key, value, orgIndex } = sorted[m];
446
+ let { key, value } = sorted[m];
447
+ const { orgIndex } = sorted[m];
448
+ if (this.isRaw(key)) {
449
+ const entry = this._toEntryFn!(key);
450
+ key = entry[0];
451
+ value = entry[1] ?? value;
452
+ }
469
453
  inserted[orgIndex] = this.add(key, value);
470
454
  stack.push([m + 1, r]);
471
455
  stack.push([l, m - 1]);
@@ -483,36 +467,23 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
483
467
  return inserted;
484
468
  }
485
469
 
486
- /**
487
- * Time Complexity: O(n)
488
- * Space Complexity: O(1)
489
- *
490
- * The `merge` function overrides the base class method by adding elements from another
491
- * binary search tree.
492
- * @param anotherTree - `anotherTree` is an instance of a Binary Search Tree (BST) with key type `K`,
493
- * value type `V`, return type `R`, node type `NODE`, and tree type `TREE`.
494
- */
495
- override merge(anotherTree: this) {
496
- this.addMany(anotherTree, [], false);
497
- }
498
-
499
470
  /**
500
471
  * Time Complexity: O(log n)
501
472
  * Space Complexity: O(k + log n)
502
473
  *
503
474
  * The function `search` in TypeScript overrides the search behavior in a binary tree structure based
504
475
  * on specified criteria.
505
- * @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate - The
506
- * `keyNodeEntryRawOrPredicate` parameter in the `override search` method can accept one of the
476
+ * @param {BTNRep<K, V, BSTNode<K, V>> | NodePredicate<BSTNode<K, V>>} keyNodeEntryOrPredicate - The
477
+ * `keyNodeEntryOrPredicate` parameter in the `override search` method can accept one of the
507
478
  * following types:
508
479
  * @param [onlyOne=false] - The `onlyOne` parameter is a boolean flag that determines whether the
509
480
  * search should stop after finding the first matching node. If `onlyOne` is set to `true`, the
510
481
  * search will return as soon as a matching node is found. If `onlyOne` is set to `false`, the
511
482
  * @param {C} callback - The `callback` parameter in the `override search` function is a function
512
483
  * that will be called on each node that matches the search criteria. It is of type `C`, which
513
- * extends `NodeCallback<NODE>`. The callback function should accept a node of type `NODE` as its
484
+ * extends `NodeCallback<BSTNode<K, V>>`. The callback function should accept a node of type `BSTNode<K, V>` as its
514
485
  * argument and
515
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `override search`
486
+ * @param {BTNRep<K, V, BSTNode<K, V>>} startNode - The `startNode` parameter in the `override search`
516
487
  * method represents the node from which the search operation will begin. It is the starting point
517
488
  * for searching within the tree data structure. The method ensures that the `startNode` is a valid
518
489
  * node before proceeding with the search operation. If the `
@@ -524,29 +495,29 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
524
495
  * structure based on the provided key, predicate, and other options. The search results are
525
496
  * collected in an array and returned as the output of the method.
526
497
  */
527
- override search<C extends NodeCallback<NODE>>(
528
- keyNodeEntryRawOrPredicate: BTNRep<K, V, NODE> | R | NodePredicate<NODE> | Range<K>,
498
+ override search<C extends NodeCallback<BSTNode<K, V>>>(
499
+ keyNodeEntryOrPredicate: BTNRep<K, V, BSTNode<K, V>> | NodePredicate<BSTNode<K, V>> | Range<K>,
529
500
  onlyOne = false,
530
501
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
531
- startNode: BTNRep<K, V, NODE> | R = this._root,
502
+ startNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
532
503
  iterationType: IterationType = this.iterationType
533
504
  ): ReturnType<C>[] {
534
- if (keyNodeEntryRawOrPredicate === undefined) return [];
535
- if (keyNodeEntryRawOrPredicate === null) return [];
505
+ if (keyNodeEntryOrPredicate === undefined) return [];
506
+ if (keyNodeEntryOrPredicate === null) return [];
536
507
  startNode = this.ensureNode(startNode);
537
508
  if (!startNode) return [];
538
- let predicate: NodePredicate<NODE>;
509
+ let predicate: NodePredicate<BSTNode<K, V>>;
539
510
 
540
- const isRange = this.isRange(keyNodeEntryRawOrPredicate);
511
+ const isRange = this.isRange(keyNodeEntryOrPredicate);
541
512
  // Set predicate based on parameter type
542
513
  if (isRange) {
543
- predicate = node => keyNodeEntryRawOrPredicate.isInRange(node.key, this._comparator);
514
+ predicate = node => keyNodeEntryOrPredicate.isInRange(node.key, this._comparator);
544
515
  } else {
545
- predicate = this._ensurePredicate(keyNodeEntryRawOrPredicate);
516
+ predicate = this._ensurePredicate(keyNodeEntryOrPredicate);
546
517
  }
547
- const isToLeftByRange = (cur: NODE) => {
518
+ const isToLeftByRange = (cur: BSTNode<K, V>) => {
548
519
  if (isRange) {
549
- const range = keyNodeEntryRawOrPredicate;
520
+ const range = keyNodeEntryOrPredicate;
550
521
  const leftS = this.isReverse ? range.high : range.low;
551
522
  const leftI = this.isReverse ? range.includeHigh : range.includeLow;
552
523
  return (leftI && this._compare(cur.key, leftS) >= 0) || (!leftI && this._compare(cur.key, leftS) > 0);
@@ -554,9 +525,9 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
554
525
  return false;
555
526
  };
556
527
 
557
- const isToRightByRange = (cur: NODE) => {
528
+ const isToRightByRange = (cur: BSTNode<K, V>) => {
558
529
  if (isRange) {
559
- const range = keyNodeEntryRawOrPredicate;
530
+ const range = keyNodeEntryOrPredicate;
560
531
  const rightS = this.isReverse ? range.low : range.high;
561
532
  const rightI = this.isReverse ? range.includeLow : range.includeLow;
562
533
 
@@ -566,7 +537,7 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
566
537
  };
567
538
  const ans: ReturnType<C>[] = [];
568
539
  if (iterationType === 'RECURSIVE') {
569
- const dfs = (cur: NODE) => {
540
+ const dfs = (cur: BSTNode<K, V>) => {
570
541
  if (predicate(cur)) {
571
542
  ans.push(callback(cur));
572
543
  if (onlyOne) return;
@@ -577,8 +548,8 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
577
548
  if (isRange) {
578
549
  if (this.isRealNode(cur.left) && isToLeftByRange(cur)) dfs(cur.left);
579
550
  if (this.isRealNode(cur.right) && isToRightByRange(cur)) dfs(cur.right);
580
- } else if (!this._isPredicate(keyNodeEntryRawOrPredicate)) {
581
- const benchmarkKey = this._extractKey(keyNodeEntryRawOrPredicate);
551
+ } else if (!this._isPredicate(keyNodeEntryOrPredicate)) {
552
+ const benchmarkKey = this._extractKey(keyNodeEntryOrPredicate);
582
553
  if (
583
554
  this.isRealNode(cur.left) &&
584
555
  benchmarkKey !== null &&
@@ -611,8 +582,8 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
611
582
  if (isRange) {
612
583
  if (this.isRealNode(cur.left) && isToLeftByRange(cur)) stack.push(cur.left);
613
584
  if (this.isRealNode(cur.right) && isToRightByRange(cur)) stack.push(cur.right);
614
- } else if (!this._isPredicate(keyNodeEntryRawOrPredicate)) {
615
- const benchmarkKey = this._extractKey(keyNodeEntryRawOrPredicate);
585
+ } else if (!this._isPredicate(keyNodeEntryOrPredicate)) {
586
+ const benchmarkKey = this._extractKey(keyNodeEntryOrPredicate);
616
587
  if (
617
588
  this.isRealNode(cur.right) &&
618
589
  benchmarkKey !== null &&
@@ -639,16 +610,16 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
639
610
 
640
611
  /**
641
612
  * Time Complexity: O(log n)
642
- * Space Complexity: O(n)
613
+ * Space Complexity: O(k + log n)
643
614
  *
644
615
  * The `rangeSearch` function searches for nodes within a specified range in a binary search tree.
645
616
  * @param {Range<K> | [K, K]} range - The `range` parameter in the `rangeSearch` function can be
646
617
  * either a `Range` object or an array of two elements representing the range boundaries.
647
618
  * @param {C} callback - The `callback` parameter in the `rangeSearch` function is a callback
648
619
  * function that is used to process each node that is found within the specified range during the
649
- * search operation. It is of type `NodeCallback<NODE>`, where `NODE` is the type of nodes in the
620
+ * search operation. It is of type `NodeCallback<BSTNode<K, V>>`, where `BSTNode<K, V>` is the type of nodes in the
650
621
  * data structure.
651
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `rangeSearch`
622
+ * @param {BTNRep<K, V, BSTNode<K, V>>} startNode - The `startNode` parameter in the `rangeSearch`
652
623
  * function represents the node from which the search for nodes within the specified range will
653
624
  * begin. It is the starting point for the range search operation.
654
625
  * @param {IterationType} iterationType - The `iterationType` parameter in the `rangeSearch` function
@@ -658,10 +629,10 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
658
629
  * @returns The `rangeSearch` function is returning the result of calling the `search` method with
659
630
  * the specified parameters.
660
631
  */
661
- rangeSearch<C extends NodeCallback<NODE>>(
632
+ rangeSearch<C extends NodeCallback<BSTNode<K, V>>>(
662
633
  range: Range<K> | [K, K],
663
634
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
664
- startNode: BTNRep<K, V, NODE> | R = this._root,
635
+ startNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
665
636
  iterationType: IterationType = this.iterationType
666
637
  ) {
667
638
  const searchRange: Range<K> = range instanceof Range ? range : new Range(range[0], range[1]);
@@ -670,12 +641,12 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
670
641
 
671
642
  /**
672
643
  * Time Complexity: O(log n)
673
- * Space Complexity: O(1)
644
+ * Space Complexity: O(log n)
674
645
  *
675
- * This function retrieves a node based on a given keyNodeEntryRawOrPredicate within a binary search tree structure.
676
- * @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate - The `keyNodeEntryRawOrPredicate`
677
- * parameter can be of type `BTNRep<K, V, NODE>`, `R`, or `NodePredicate<NODE>`.
678
- * @param {R | BSTNOptKeyOrNode<K, NODE>} startNode - The `startNode` parameter in the `getNode` method
646
+ * This function retrieves a node based on a given keyNodeEntryOrPredicate within a binary search tree structure.
647
+ * @param {BTNRep<K, V, BSTNode<K, V>> | NodePredicate<BSTNode<K, V>>} keyNodeEntryOrPredicate - The `keyNodeEntryOrPredicate`
648
+ * parameter can be of type `BTNRep<K, V, BSTNode<K, V>>`, `R`, or `NodePredicate<BSTNode<K, V>>`.
649
+ * @param {BSTNOptKeyOrNode<K, BSTNode<K, V>>} startNode - The `startNode` parameter in the `getNode` method
679
650
  * is used to specify the starting point for searching nodes in the binary search tree. If no
680
651
  * specific starting point is provided, the default value is set to `this._root`, which is the root
681
652
  * node of the binary search tree.
@@ -683,17 +654,17 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
683
654
  * parameter that specifies the type of iteration to be used. It has a default value of
684
655
  * `this.iterationType`, which means it will use the iteration type defined in the class instance if
685
656
  * no value is provided when calling the method.
686
- * @returns The `getNode` method is returning an optional binary search tree node (`OptNode<NODE>`).
687
- * It is using the `getNodes` method to find the node based on the provided keyNodeEntryRawOrPredicate, beginning at
657
+ * @returns The `getNode` method is returning an optional binary search tree node (`OptNode<BSTNode<K, V>>`).
658
+ * It is using the `getNodes` method to find the node based on the provided keyNodeEntryOrPredicate, beginning at
688
659
  * the specified root node (`startNode`) and using the specified iteration type. The method then
689
660
  * returns the first node found or `undefined` if no node is found.
690
661
  */
691
662
  override getNode(
692
- keyNodeEntryRawOrPredicate: BTNRep<K, V, NODE> | R | NodePredicate<NODE>,
693
- startNode: R | BSTNOptKeyOrNode<K, NODE> = this._root,
663
+ keyNodeEntryOrPredicate: BTNRep<K, V, BSTNode<K, V>> | NodePredicate<BSTNode<K, V>>,
664
+ startNode: BSTNOptKeyOrNode<K, BSTNode<K, V>> = this._root,
694
665
  iterationType: IterationType = this.iterationType
695
- ): OptNode<NODE> {
696
- return this.getNodes(keyNodeEntryRawOrPredicate, true, startNode, iterationType)[0] ?? undefined;
666
+ ): OptNode<BSTNode<K, V>> {
667
+ return this.getNodes(keyNodeEntryOrPredicate, true, startNode, iterationType)[0] ?? undefined;
697
668
  }
698
669
 
699
670
  /**
@@ -708,7 +679,7 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
708
679
  * @param {DFSOrderPattern} [pattern=IN] - The "pattern" parameter in the code snippet refers to the
709
680
  * order in which the Depth-First Search (DFS) algorithm visits the nodes in a tree or graph. It can
710
681
  * take one of the following values:
711
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter is the starting
682
+ * @param {BTNRep<K, V, BSTNode<K, V>>} startNode - The `startNode` parameter is the starting
712
683
  * point for the depth-first search traversal. It can be either a root node, a key-value pair, or a
713
684
  * node entry. If not specified, the default value is the root of the tree.
714
685
  * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter specifies the
@@ -716,10 +687,10 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
716
687
  * following values:
717
688
  * @returns The method is returning an array of the return type of the callback function.
718
689
  */
719
- override dfs<C extends NodeCallback<NODE>>(
690
+ override dfs<C extends NodeCallback<BSTNode<K, V>>>(
720
691
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
721
692
  pattern: DFSOrderPattern = 'IN',
722
- startNode: BTNRep<K, V, NODE> | R = this._root,
693
+ startNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
723
694
  iterationType: IterationType = this.iterationType
724
695
  ): ReturnType<C>[] {
725
696
  return super.dfs(callback, pattern, startNode, iterationType);
@@ -734,7 +705,7 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
734
705
  * @param {C} callback - The `callback` parameter is a function that will be called for each node
735
706
  * visited during the breadth-first search. It should take a single argument, which is the current
736
707
  * node being visited, and it can return a value of any type.
737
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter is the starting
708
+ * @param {BTNRep<K, V, BSTNode<K, V>>} startNode - The `startNode` parameter is the starting
738
709
  * point for the breadth-first search. It can be either a root node, a key-value pair, or an entry
739
710
  * object. If no value is provided, the default value is the root of the tree.
740
711
  * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type
@@ -742,9 +713,9 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
742
713
  * the following values:
743
714
  * @returns an array of the return type of the callback function.
744
715
  */
745
- override bfs<C extends NodeCallback<NODE>>(
716
+ override bfs<C extends NodeCallback<BSTNode<K, V>>>(
746
717
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
747
- startNode: BTNRep<K, V, NODE> | R = this._root,
718
+ startNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
748
719
  iterationType: IterationType = this.iterationType
749
720
  ): ReturnType<C>[] {
750
721
  return super.bfs(callback, startNode, iterationType, false);
@@ -757,9 +728,9 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
757
728
  * The function overrides the listLevels method from the superclass and returns an array of arrays
758
729
  * containing the results of the callback function applied to each level of the tree.
759
730
  * @param {C} callback - The `callback` parameter is a generic type `C` that extends
760
- * `NodeCallback<NODE>`. It represents a callback function that will be called for each node in the
731
+ * `NodeCallback<BSTNode<K, V>>`. It represents a callback function that will be called for each node in the
761
732
  * tree during the iteration process.
762
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter is the starting
733
+ * @param {BTNRep<K, V, BSTNode<K, V>>} startNode - The `startNode` parameter is the starting
763
734
  * point for listing the levels of the binary tree. It can be either a root node of the tree, a
764
735
  * key-value pair representing a node in the tree, or a key representing a node in the tree. If no
765
736
  * value is provided, the root of
@@ -768,9 +739,9 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
768
739
  * @returns The method is returning a two-dimensional array of the return type of the callback
769
740
  * function.
770
741
  */
771
- override listLevels<C extends NodeCallback<NODE>>(
742
+ override listLevels<C extends NodeCallback<BSTNode<K, V>>>(
772
743
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
773
- startNode: BTNRep<K, V, NODE> | R = this._root,
744
+ startNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
774
745
  iterationType: IterationType = this.iterationType
775
746
  ): ReturnType<C>[][] {
776
747
  return super.listLevels(callback, startNode, iterationType, false);
@@ -788,7 +759,7 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
788
759
  * @param {CP} lesserOrGreater - The `lesserOrGreater` parameter is used to determine whether to
789
760
  * traverse nodes that are lesser, greater, or both than the `targetNode`. It accepts the values -1,
790
761
  * 0, or 1, where:
791
- * @param {BTNRep<K, V, NODE> | R} targetNode - The `targetNode` parameter is the node in
762
+ * @param {BTNRep<K, V, BSTNode<K, V>>} targetNode - The `targetNode` parameter is the node in
792
763
  * the binary tree that you want to start traversing from. It can be specified either by providing
793
764
  * the key of the node, the node itself, or an entry containing the key and value of the node. If no
794
765
  * `targetNode` is provided,
@@ -797,21 +768,21 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
797
768
  * @returns The function `lesserOrGreaterTraverse` returns an array of values of type
798
769
  * `ReturnType<C>`, which is the return type of the callback function passed as an argument.
799
770
  */
800
- lesserOrGreaterTraverse<C extends NodeCallback<NODE>>(
771
+ lesserOrGreaterTraverse<C extends NodeCallback<BSTNode<K, V>>>(
801
772
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
802
773
  lesserOrGreater: CP = -1,
803
- targetNode: BTNRep<K, V, NODE> | R = this._root,
774
+ targetNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
804
775
  iterationType: IterationType = this.iterationType
805
776
  ): ReturnType<C>[] {
806
777
  const targetNodeEnsured = this.ensureNode(targetNode);
807
- const ans: ReturnType<NodeCallback<NODE>>[] = [];
778
+ const ans: ReturnType<NodeCallback<BSTNode<K, V>>>[] = [];
808
779
  if (!this._root) return ans;
809
780
  if (!targetNodeEnsured) return ans;
810
781
 
811
782
  const targetKey = targetNodeEnsured.key;
812
783
 
813
784
  if (iterationType === 'RECURSIVE') {
814
- const dfs = (cur: NODE) => {
785
+ const dfs = (cur: BSTNode<K, V>) => {
815
786
  const compared = this._compare(cur.key, targetKey);
816
787
  if (Math.sign(compared) === lesserOrGreater) ans.push(callback(cur));
817
788
  // TODO here can be optimized to O(log n)
@@ -822,7 +793,7 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
822
793
  dfs(this._root);
823
794
  return ans;
824
795
  } else {
825
- const queue = new Queue<NODE>([this._root]);
796
+ const queue = new Queue<BSTNode<K, V>>([this._root]);
826
797
  while (queue.size > 0) {
827
798
  const cur = queue.shift();
828
799
  if (this.isRealNode(cur)) {
@@ -906,7 +877,7 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
906
877
  let balanced = true;
907
878
 
908
879
  if (iterationType === 'RECURSIVE') {
909
- const _height = (cur: OptNode<NODE>): number => {
880
+ const _height = (cur: OptNodeOrNull<BSTNode<K, V>>): number => {
910
881
  if (!cur) return 0;
911
882
  const leftHeight = _height(cur.left),
912
883
  rightHeight = _height(cur.right);
@@ -915,15 +886,15 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
915
886
  };
916
887
  _height(this._root);
917
888
  } else {
918
- const stack: NODE[] = [];
919
- let node: OptNode<NODE> = this._root,
920
- last: OptNode<NODE> = undefined;
921
- const depths: Map<NODE, number> = new Map();
889
+ const stack: BSTNode<K, V>[] = [];
890
+ let node: OptNode<BSTNode<K, V>> = this._root,
891
+ last: OptNode<BSTNode<K, V>> = undefined;
892
+ const depths: Map<BSTNode<K, V>, number> = new Map();
922
893
 
923
894
  while (stack.length > 0 || node) {
924
895
  if (node) {
925
896
  stack.push(node);
926
- node = node.left;
897
+ if (node.left !== null) node = node.left;
927
898
  } else {
928
899
  node = stack[stack.length - 1];
929
900
  if (!node.right || last === node.right) {
@@ -944,12 +915,30 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
944
915
  return balanced;
945
916
  }
946
917
 
947
- // @ts-ignore
948
- override map<MK, MV, MR>(
918
+ /**
919
+ * Time complexity: O(n)
920
+ * Space complexity: O(n)
921
+ *
922
+ * The `map` function in TypeScript overrides the default map behavior for a binary search tree by
923
+ * applying a callback function to each entry and creating a new tree with the results.
924
+ * @param callback - A function that will be called for each entry in the BST. It takes four
925
+ * arguments: the key, the value (which can be undefined), the index of the entry, and a reference to
926
+ * the BST itself.
927
+ * @param [options] - The `options` parameter in the `override map` method is of type `BSTOptions<MK,
928
+ * MV, MR>`. It is an optional parameter that allows you to specify additional options for the Binary
929
+ * Search Tree (BST) being created in the `map` method. These options could include configuration
930
+ * @param {any} [thisArg] - The `thisArg` parameter in the `override map` method is used to specify
931
+ * the value of `this` that should be used when executing the `callback` function. It allows you to
932
+ * set the context or scope in which the callback function will be called. This can be useful when
933
+ * you want
934
+ * @returns The `map` method is returning a new Binary Search Tree (`BST`) instance with the entries
935
+ * transformed by the provided callback function.
936
+ */
937
+ override map(
949
938
  callback: EntryCallback<K, V | undefined, [MK, MV]>,
950
939
  options?: BSTOptions<MK, MV, MR>,
951
940
  thisArg?: any
952
- ) {
941
+ ): BST<MK, MV, MR> {
953
942
  const newTree = new BST<MK, MV, MR>([], options);
954
943
  let index = 0;
955
944
  for (const [key, value] of this) {
@@ -959,35 +948,69 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
959
948
  }
960
949
 
961
950
  /**
951
+ * Time complexity: O(n)
952
+ * Space complexity: O(n)
953
+ *
954
+ * The function `clone` overrides the default cloning behavior to create a deep copy of a tree
955
+ * structure.
956
+ * @returns The `cloned` object is being returned.
957
+ */
958
+ override clone() {
959
+ const cloned = this.createTree();
960
+ this._clone(cloned);
961
+ return cloned;
962
+ }
963
+
964
+ /**
965
+ * Time Complexity: O(1)
966
+ * Space Complexity: O(1)
967
+ *
962
968
  * The function overrides a method and converts a key, value pair or entry or raw element to a node.
963
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - A variable that can be of
964
- * type R or BTNRep<K, V, NODE>. It represents either a key, a node, an entry, or a raw
969
+ * @param {BTNRep<K, V, BSTNode<K, V>>} keyNodeOrEntry - A variable that can be of
970
+ * type R or BTNRep<K, V, BSTNode<K, V>>. It represents either a key, a node, an entry, or a raw
965
971
  * element.
966
972
  * @param {V} [value] - The `value` parameter is an optional value of type `V`. It represents the
967
973
  * value associated with a key in a key-value pair.
968
- * @returns either a NODE object or undefined.
974
+ * @returns either a BSTNode<K, V> object or undefined.
969
975
  */
970
- protected override _keyValueNodeEntryRawToNodeAndValue(
971
- keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
976
+ protected override _keyValueNodeOrEntryToNodeAndValue(
977
+ keyNodeOrEntry: BTNRep<K, V, BSTNode<K, V>>,
972
978
  value?: V
973
- ): [OptNode<NODE>, V | undefined] {
974
- const [node, entryValue] = super._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
979
+ ): [OptNode<BSTNode<K, V>>, V | undefined] {
980
+ const [node, entryValue] = super._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
975
981
  if (node === null) return [undefined, undefined];
976
982
  return [node, value ?? entryValue];
977
983
  }
978
984
 
979
985
  /**
986
+ * Time Complexity: O(1)
987
+ * Space Complexity: O(1)
988
+ *
980
989
  * The function sets the root of a tree-like structure and updates the parent property of the new
981
990
  * root.
982
- * @param {OptNode<NODE>} v - v is a parameter of type NODE or undefined.
991
+ * @param {OptNode<BSTNode<K, V>>} v - v is a parameter of type BSTNode<K, V> or undefined.
983
992
  */
984
- protected override _setRoot(v: OptNode<NODE>) {
993
+ protected override _setRoot(v: OptNode<BSTNode<K, V>>) {
985
994
  if (v) {
986
995
  v.parent = undefined;
987
996
  }
988
997
  this._root = v;
989
998
  }
990
999
 
1000
+ /**
1001
+ * Time Complexity: O(1)
1002
+ * Space Complexity: O(1)
1003
+ *
1004
+ * The _compare function compares two values using a specified comparator function and optionally
1005
+ * reverses the result.
1006
+ * @param {K} a - The parameter `a` is of type `K`, which is used as an input for comparison in the
1007
+ * `_compare` method.
1008
+ * @param {K} b - The parameter `b` in the `_compare` function is of type `K`.
1009
+ * @returns The `_compare` method is returning the result of the ternary expression. If `_isReverse`
1010
+ * is true, it returns the negation of the result of calling the `_comparator` function with
1011
+ * arguments `a` and `b`. If `_isReverse` is false, it returns the result of calling the
1012
+ * `_comparator` function with arguments `a` and `b`.
1013
+ */
991
1014
  protected _compare(a: K, b: K) {
992
1015
  return this._isReverse ? -this._comparator(a, b) : this._comparator(a, b);
993
1016
  }