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