heap-typed 1.51.7 → 1.51.9

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 (56) hide show
  1. package/README.md +72 -80
  2. package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +103 -74
  3. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +116 -93
  4. package/dist/data-structures/binary-tree/avl-tree.d.ts +82 -62
  5. package/dist/data-structures/binary-tree/avl-tree.js +90 -71
  6. package/dist/data-structures/binary-tree/binary-tree.d.ts +318 -233
  7. package/dist/data-structures/binary-tree/binary-tree.js +492 -392
  8. package/dist/data-structures/binary-tree/bst.d.ts +204 -251
  9. package/dist/data-structures/binary-tree/bst.js +256 -358
  10. package/dist/data-structures/binary-tree/rb-tree.d.ts +74 -85
  11. package/dist/data-structures/binary-tree/rb-tree.js +111 -119
  12. package/dist/data-structures/binary-tree/tree-multi-map.d.ts +92 -76
  13. package/dist/data-structures/binary-tree/tree-multi-map.js +105 -93
  14. package/dist/data-structures/graph/abstract-graph.d.ts +10 -15
  15. package/dist/data-structures/graph/abstract-graph.js +10 -15
  16. package/dist/data-structures/hash/hash-map.d.ts +31 -38
  17. package/dist/data-structures/hash/hash-map.js +40 -55
  18. package/dist/data-structures/heap/heap.d.ts +1 -3
  19. package/dist/data-structures/queue/deque.d.ts +2 -3
  20. package/dist/data-structures/queue/deque.js +2 -3
  21. package/dist/data-structures/trie/trie.d.ts +1 -1
  22. package/dist/data-structures/trie/trie.js +1 -1
  23. package/dist/interfaces/binary-tree.d.ts +7 -7
  24. package/dist/types/common.d.ts +2 -3
  25. package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +4 -3
  26. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +4 -3
  27. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +6 -5
  28. package/dist/types/data-structures/binary-tree/bst.d.ts +6 -5
  29. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +4 -3
  30. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +4 -3
  31. package/dist/types/utils/utils.d.ts +10 -1
  32. package/dist/utils/utils.d.ts +2 -1
  33. package/dist/utils/utils.js +27 -1
  34. package/package.json +2 -2
  35. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +142 -100
  36. package/src/data-structures/binary-tree/avl-tree.ts +109 -80
  37. package/src/data-structures/binary-tree/binary-tree.ts +556 -433
  38. package/src/data-structures/binary-tree/bst.ts +286 -375
  39. package/src/data-structures/binary-tree/rb-tree.ts +132 -125
  40. package/src/data-structures/binary-tree/tree-multi-map.ts +129 -102
  41. package/src/data-structures/graph/abstract-graph.ts +10 -10
  42. package/src/data-structures/hash/hash-map.ts +42 -49
  43. package/src/data-structures/heap/heap.ts +1 -1
  44. package/src/data-structures/queue/deque.ts +2 -2
  45. package/src/data-structures/queue/queue.ts +1 -1
  46. package/src/data-structures/trie/trie.ts +2 -2
  47. package/src/interfaces/binary-tree.ts +11 -9
  48. package/src/types/common.ts +2 -3
  49. package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +4 -3
  50. package/src/types/data-structures/binary-tree/avl-tree.ts +4 -3
  51. package/src/types/data-structures/binary-tree/binary-tree.ts +7 -6
  52. package/src/types/data-structures/binary-tree/bst.ts +6 -5
  53. package/src/types/data-structures/binary-tree/rb-tree.ts +4 -3
  54. package/src/types/data-structures/binary-tree/tree-multi-map.ts +4 -3
  55. package/src/types/utils/utils.ts +14 -1
  56. package/src/utils/utils.ts +20 -1
@@ -7,22 +7,28 @@
7
7
  */
8
8
  import type {
9
9
  BSTNested,
10
+ BSTNKeyOrNode,
10
11
  BSTNodeNested,
11
12
  BSTOptions,
12
13
  BTNCallback,
13
- BTNodePureExemplar,
14
+ BTNPureKeyOrNodeOrEntry,
15
+ Comparable,
16
+ Comparator,
17
+ CP,
18
+ DFSOrderPattern,
19
+ IterationType,
14
20
  KeyOrNodeOrEntry
15
21
  } from '../../types';
16
- import { BSTNKeyOrNode, BSTVariant, CP, DFSOrderPattern, IterationType } from '../../types';
22
+ import { BTNEntry } from '../../types';
17
23
  import { BinaryTree, BinaryTreeNode } from './binary-tree';
18
24
  import { IBinaryTree } from '../../interfaces';
19
25
  import { Queue } from '../queue';
20
26
 
21
- export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNodeNested<K, V>> extends BinaryTreeNode<
22
- K,
23
- V,
24
- NODE
25
- > {
27
+ export class BSTNode<
28
+ K extends Comparable,
29
+ V = any,
30
+ NODE extends BSTNode<K, V, NODE> = BSTNodeNested<K, V>
31
+ > extends BinaryTreeNode<K, V, NODE> {
26
32
  override parent?: NODE;
27
33
 
28
34
  constructor(key: K, value?: V) {
@@ -88,35 +94,37 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
88
94
  * 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.
89
95
  */
90
96
  export class BST<
91
- K = any,
97
+ K extends Comparable,
92
98
  V = any,
99
+ R = BTNEntry<K, V>,
93
100
  NODE extends BSTNode<K, V, NODE> = BSTNode<K, V, BSTNodeNested<K, V>>,
94
- TREE extends BST<K, V, NODE, TREE> = BST<K, V, NODE, BSTNested<K, V, NODE>>
101
+ TREE extends BST<K, V, R, NODE, TREE> = BST<K, V, R, NODE, BSTNested<K, V, R, NODE>>
95
102
  >
96
- extends BinaryTree<K, V, NODE, TREE>
97
- implements IBinaryTree<K, V, NODE, TREE> {
98
- /**
99
- * This is the constructor function for a TypeScript class that initializes a binary search tree with
100
- * optional keys or nodes or entries and options.
101
- * @param keysOrNodesOrEntries - An iterable object that contains keys, nodes, or entries. It is used
102
- * to initialize the binary search tree with the provided keys, nodes, or entries.
103
- * @param [options] - The `options` parameter is an optional object that can contain additional
104
- * configuration options for the binary search tree. It can have the following properties:
105
- */
106
- constructor(keysOrNodesOrEntries: Iterable<KeyOrNodeOrEntry<K, V, NODE>> = [], options?: BSTOptions<K>) {
103
+ extends BinaryTree<K, V, R, NODE, TREE>
104
+ implements IBinaryTree<K, V, R, NODE, TREE> {
105
+ /**
106
+ * This is the constructor function for a Binary Search Tree class in TypeScript.
107
+ * @param keysOrNodesOrEntriesOrRawElements - The `keysOrNodesOrEntriesOrRawElements` parameter is an
108
+ * iterable that can contain either keys, nodes, entries, or raw elements. These elements will be
109
+ * added to the binary search tree during the construction of the object.
110
+ * @param [options] - An optional object that contains additional options for the Binary Search Tree.
111
+ * It can include a comparator function that defines the order of the elements in the tree.
112
+ */
113
+ constructor(
114
+ keysOrNodesOrEntriesOrRawElements: Iterable<R | KeyOrNodeOrEntry<K, V, NODE>> = [],
115
+ options?: BSTOptions<K, V, R>
116
+ ) {
107
117
  super([], options);
108
118
 
109
119
  if (options) {
110
- const { variant } = options;
111
- if (variant) this._variant = variant;
120
+ const { comparator } = options;
121
+ if (comparator) this._comparator = comparator;
112
122
  }
113
123
 
114
- this._root = undefined;
115
-
116
- if (keysOrNodesOrEntries) this.addMany(keysOrNodesOrEntries);
124
+ if (keysOrNodesOrEntriesOrRawElements) this.addMany(keysOrNodesOrEntriesOrRawElements);
117
125
  }
118
126
 
119
- protected override _root?: NODE;
127
+ protected override _root?: NODE = undefined;
120
128
 
121
129
  /**
122
130
  * The function returns the root node of a tree structure.
@@ -126,16 +134,6 @@ export class BST<
126
134
  return this._root;
127
135
  }
128
136
 
129
- protected _variant: BSTVariant = 'STANDARD';
130
-
131
- /**
132
- * The function returns the value of the _variant property.
133
- * @returns The value of the `_variant` property.
134
- */
135
- get variant() {
136
- return this._variant;
137
- }
138
-
139
137
  /**
140
138
  * The function creates a new BSTNode with the given key and value and returns it.
141
139
  * @param {K} key - The key parameter is of type K, which represents the type of the key for the node
@@ -151,113 +149,82 @@ export class BST<
151
149
  /**
152
150
  * The function creates a new binary search tree with the specified options.
153
151
  * @param [options] - The `options` parameter is an optional object that allows you to customize the
154
- * behavior of the `createTree` method. It is of type `Partial<BSTOptions<K>>`, which means it is a
155
- * partial object of type `BSTOptions<K>`.
156
- * @returns a new instance of the BST class, with the provided options merged with the default
157
- * options. The returned value is casted as TREE.
152
+ * behavior of the `createTree` method. It accepts a partial `BSTOptions` object, which has the
153
+ * following properties:
154
+ * @returns a new instance of the BST class with the provided options.
158
155
  */
159
- override createTree(options?: Partial<BSTOptions<K>>): TREE {
160
- return new BST<K, V, NODE, TREE>([], {
156
+ override createTree(options?: Partial<BSTOptions<K, V, R>>): TREE {
157
+ return new BST<K, V, R, NODE, TREE>([], {
161
158
  iterationType: this.iterationType,
162
- variant: this.variant,
159
+ comparator: this.comparator,
163
160
  ...options
164
161
  }) as TREE;
165
162
  }
166
163
 
167
164
  /**
168
- * The function `keyValueOrEntryToNode` takes an keyOrNodeOrEntry and returns a node if the keyOrNodeOrEntry is valid,
169
- * otherwise it returns undefined.
170
- * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter is of type `KeyOrNodeOrEntry<K, V, NODE>`, where:
171
- * @param {V} [value] - The `value` parameter is an optional value that can be passed to the
172
- * `keyValueOrEntryToNode` function. It represents the value associated with the keyOrNodeOrEntry node.
173
- * @returns a node of type NODE or undefined.
174
- */
175
- override keyValueOrEntryToNode(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>, value?: V): NODE | undefined {
176
- let node: NODE | undefined;
177
- if (keyOrNodeOrEntry === null || keyOrNodeOrEntry === undefined) {
178
- return;
179
- } else if (this.isNode(keyOrNodeOrEntry)) {
180
- node = keyOrNodeOrEntry;
181
- } else if (this.isEntry(keyOrNodeOrEntry)) {
182
- const [key, value] = keyOrNodeOrEntry;
183
- if (key === undefined || key === null) {
184
- return;
185
- } else {
186
- node = this.createNode(key, value);
187
- }
188
- } else if (!this.isNode(keyOrNodeOrEntry)) {
189
- node = this.createNode(keyOrNodeOrEntry, value);
190
- } else {
191
- return;
192
- }
193
- return node;
194
- }
195
-
196
- /**
197
- * Time Complexity: O(log n)
198
- * Space Complexity: O(log n)
165
+ * The function overrides a method and converts a key, value pair or entry or raw element to a node.
166
+ * @param {R | KeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - A variable that can be of
167
+ * type R or KeyOrNodeOrEntry<K, V, NODE>. It represents either a key, a node, an entry, or a raw
168
+ * element.
169
+ * @param {V} [value] - The `value` parameter is an optional value of type `V`. It represents the
170
+ * value associated with a key in a key-value pair.
171
+ * @returns either a NODE object or undefined.
199
172
  */
173
+ override keyValueOrEntryOrRawElementToNode(
174
+ keyOrNodeOrEntryOrRawElement: R | KeyOrNodeOrEntry<K, V, NODE>,
175
+ value?: V
176
+ ): NODE | undefined {
177
+ return super.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement, value) ?? undefined;
178
+ }
200
179
 
201
180
  /**
202
181
  * Time Complexity: O(log n)
203
182
  * Space Complexity: O(log n)
204
183
  *
205
- * The function `ensureNode` returns the node corresponding to the given key if it is a node key,
206
- * otherwise it returns the key itself.
207
- * @param {K | NODE | undefined} keyOrNodeOrEntry - The `key` parameter can be of type `K`, `NODE`, or
208
- * `undefined`.
209
- * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
210
- * type of iteration to be performed. It has a default value of `'ITERATIVE'`.
211
- * @returns either a node object (NODE) or undefined.
184
+ * The function ensures the existence of a node in a data structure and returns it, or undefined if
185
+ * it doesn't exist.
186
+ * @param {R | KeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The parameter
187
+ * `keyOrNodeOrEntryOrRawElement` can accept a value of type `R`, which represents the key, node,
188
+ * entry, or raw element that needs to be ensured in the tree.
189
+ * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional
190
+ * parameter that specifies the type of iteration to be used when ensuring a node. It has a default
191
+ * value of `'ITERATIVE'`.
192
+ * @returns The method is returning either the node that was ensured or `undefined` if the node could
193
+ * not be ensured.
212
194
  */
213
195
  override ensureNode(
214
- keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>,
196
+ keyOrNodeOrEntryOrRawElement: R | KeyOrNodeOrEntry<K, V, NODE>,
215
197
  iterationType: IterationType = 'ITERATIVE'
216
198
  ): NODE | undefined {
217
- if (keyOrNodeOrEntry === this.NIL) return;
218
- if (this.isRealNode(keyOrNodeOrEntry)) {
219
- return keyOrNodeOrEntry;
220
- }
221
-
222
- if (this.isEntry(keyOrNodeOrEntry)) {
223
- const key = keyOrNodeOrEntry[0];
224
- if (key === null || key === undefined) return;
225
- return this.getNodeByKey(key, iterationType);
226
- }
227
-
228
- const key = keyOrNodeOrEntry;
229
- if (key === null || key === undefined) return;
230
- return this.getNodeByKey(key, iterationType);
199
+ return super.ensureNode(keyOrNodeOrEntryOrRawElement, iterationType) ?? undefined;
231
200
  }
232
201
 
233
202
  /**
234
- * The function checks if an keyOrNodeOrEntry is an instance of BSTNode.
235
- * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter is a variable of type `KeyOrNodeOrEntry<K, V, NODE>`.
236
- * @returns a boolean value indicating whether the keyOrNodeOrEntry is an instance of the BSTNode class.
203
+ * The function checks if the input is an instance of the BSTNode class.
204
+ * @param {R | KeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The parameter
205
+ * `keyOrNodeOrEntryOrRawElement` can be of type `R` or `KeyOrNodeOrEntry<K, V, NODE>`.
206
+ * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRawElement` is
207
+ * an instance of the `BSTNode` class.
237
208
  */
238
- override isNode(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>): keyOrNodeOrEntry is NODE {
239
- return keyOrNodeOrEntry instanceof BSTNode;
209
+ override isNode(
210
+ keyOrNodeOrEntryOrRawElement: R | KeyOrNodeOrEntry<K, V, NODE>
211
+ ): keyOrNodeOrEntryOrRawElement is NODE {
212
+ return keyOrNodeOrEntryOrRawElement instanceof BSTNode;
240
213
  }
241
214
 
242
- /**
243
- * Time Complexity: O(log n)
244
- * Space Complexity: O(1)
245
- */
246
-
247
215
  /**
248
216
  * Time Complexity: O(log n)
249
217
  * Space Complexity: O(1)
250
218
  *
251
- * The `add` function adds a new node to a binary tree, updating the value if the key already exists
252
- * or inserting a new node if the key is unique.
253
- * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can accept three types of values:
254
- * @param {V} [value] - The `value` parameter represents the value associated with the key that is
255
- * being added to the binary tree.
256
- * @returns The method `add` returns either the newly added node (`newNode`) or `undefined` if the
257
- * node was not added.
258
- */
259
- override add(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>, value?: V): boolean {
260
- const newNode = this.keyValueOrEntryToNode(keyOrNodeOrEntry, value);
219
+ * The `add` function in TypeScript adds a new node to a binary search tree based on the key value.
220
+ * @param {R | KeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The parameter
221
+ * `keyOrNodeOrEntryOrRawElement` can accept a value of type `R` or `KeyOrNodeOrEntry<K, V, NODE>`.
222
+ * @param {V} [value] - The `value` parameter is an optional value that can be associated with the
223
+ * key in the binary search tree. If provided, it will be stored in the node along with the key.
224
+ * @returns a boolean value.
225
+ */
226
+ override add(keyOrNodeOrEntryOrRawElement: R | KeyOrNodeOrEntry<K, V, NODE>, value?: V): boolean {
227
+ const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement, value);
261
228
  if (newNode === undefined) return false;
262
229
 
263
230
  if (this.root === undefined) {
@@ -268,19 +235,10 @@ export class BST<
268
235
 
269
236
  let current = this.root;
270
237
  while (current !== undefined) {
271
- if (this._compare(current.key, newNode.key) === 'EQ') {
272
- // if (current !== newNode) {
273
- // The key value is the same but the reference is different, update the value of the existing node
238
+ if (this.comparator(current.key, newNode.key) === 0) {
274
239
  this._replaceNode(current, newNode);
275
240
  return true;
276
-
277
- // } else {
278
- // The key value is the same and the reference is the same, replace the entire node
279
- // this._replaceNode(current, newNode);
280
-
281
- // return;
282
- // }
283
- } else if (this._compare(current.key, newNode.key) === 'GT') {
241
+ } else if (this.comparator(current.key, newNode.key) > 0) {
284
242
  if (current.left === undefined) {
285
243
  current.left = newNode;
286
244
  this._size++;
@@ -301,32 +259,33 @@ export class BST<
301
259
  }
302
260
 
303
261
  /**
304
- * Time Complexity: O(k log n)
305
- * Space Complexity: O(k + log n)
262
+ * Time Complexity: O(log n)
263
+ * Space Complexity: O(log n)
306
264
  */
307
265
 
308
266
  /**
309
267
  * Time Complexity: O(k log n)
310
268
  * Space Complexity: O(k + log n)
311
269
  *
312
- * The `addMany` function in TypeScript adds multiple keys or nodes to a binary tree, optionally
313
- * balancing the tree after each addition.
314
- * @param keysOrNodesOrEntries - An iterable containing the keys, nodes, or entries to be added to
315
- * the binary tree.
270
+ * The `addMany` function in TypeScript adds multiple keys or nodes to a data structure and returns
271
+ * an array indicating whether each key or node was successfully inserted.
272
+ * @param keysOrNodesOrEntriesOrRawElements - An iterable containing keys, nodes, entries, or raw
273
+ * elements to be added to the data structure.
316
274
  * @param [values] - An optional iterable of values to be associated with the keys or nodes being
317
275
  * added. If provided, the values will be assigned to the corresponding keys or nodes in the same
318
276
  * order. If not provided, undefined will be assigned as the value for each key or node.
319
- * @param [isBalanceAdd=true] - A boolean flag indicating whether the add operation should be
320
- * balanced or not. If set to true, the add operation will be balanced using a binary search tree
321
- * algorithm. If set to false, the add operation will not be balanced and the nodes will be added
322
- * in the order they appear in the input.
323
- * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
324
- * type of iteration to use when adding multiple keys or nodes. It has a default value of
325
- * `this.iterationType`, which suggests that it is a property of the current object.
326
- * @returns The function `addMany` returns an array of nodes (`NODE`) or `undefined` values.
277
+ * @param [isBalanceAdd=true] - A boolean flag indicating whether the tree should be balanced after
278
+ * adding the elements. If set to true, the tree will be balanced using a binary search tree
279
+ * algorithm. If set to false, the elements will be added without balancing the tree. The default
280
+ * value is true.
281
+ * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that
282
+ * specifies the type of iteration to use when adding multiple keys or nodes to the binary search
283
+ * tree. It can have two possible values:
284
+ * @returns The function `addMany` returns an array of booleans indicating whether each element was
285
+ * successfully inserted into the data structure.
327
286
  */
328
287
  override addMany(
329
- keysOrNodesOrEntries: Iterable<KeyOrNodeOrEntry<K, V, NODE>>,
288
+ keysOrNodesOrEntriesOrRawElements: Iterable<R | KeyOrNodeOrEntry<K, V, NODE>>,
330
289
  values?: Iterable<V | undefined>,
331
290
  isBalanceAdd = true,
332
291
  iterationType: IterationType = this.iterationType
@@ -340,7 +299,7 @@ export class BST<
340
299
  }
341
300
 
342
301
  if (!isBalanceAdd) {
343
- for (const kve of keysOrNodesOrEntries) {
302
+ for (const kve of keysOrNodesOrEntriesOrRawElements) {
344
303
  const value = valuesIterator?.next().value;
345
304
  const nn = this.add(kve, value);
346
305
  inserted.push(nn);
@@ -348,33 +307,44 @@ export class BST<
348
307
  return inserted;
349
308
  }
350
309
 
351
- const realBTNExemplars: BTNodePureExemplar<K, V, NODE>[] = [];
310
+ const realBTNExemplars: (R | BTNPureKeyOrNodeOrEntry<K, V, NODE>)[] = [];
352
311
 
353
- const isRealBTNExemplar = (kve: KeyOrNodeOrEntry<K, V, NODE>): kve is BTNodePureExemplar<K, V, NODE> => {
312
+ const isRealBTNExemplar = (kve: R | KeyOrNodeOrEntry<K, V, NODE>): kve is BTNPureKeyOrNodeOrEntry<K, V, NODE> => {
354
313
  if (kve === undefined || kve === null) return false;
355
314
  return !(this.isEntry(kve) && (kve[0] === undefined || kve[0] === null));
356
315
  };
357
316
 
358
- for (const kve of keysOrNodesOrEntries) {
317
+ for (const kve of keysOrNodesOrEntriesOrRawElements) {
359
318
  isRealBTNExemplar(kve) && realBTNExemplars.push(kve);
360
319
  }
361
320
 
362
- let sorted: BTNodePureExemplar<K, V, NODE>[] = [];
321
+ let sorted: (R | BTNPureKeyOrNodeOrEntry<K, V, NODE>)[] = [];
363
322
 
364
323
  sorted = realBTNExemplars.sort((a, b) => {
365
- let aR: number, bR: number;
366
- if (this.isEntry(a)) aR = this.extractor(a[0]);
367
- else if (this.isRealNode(a)) aR = this.extractor(a.key);
368
- else aR = this.extractor(a);
324
+ let keyA: K | undefined | null, keyB: K | undefined | null;
325
+ if (this.isEntry(a)) keyA = a[0];
326
+ else if (this.isRealNode(a)) keyA = a.key;
327
+ else if (this.toEntryFn) {
328
+ keyA = this.toEntryFn(a as R)[0];
329
+ } else {
330
+ keyA = a as K;
331
+ }
369
332
 
370
- if (this.isEntry(b)) bR = this.extractor(b[0]);
371
- else if (this.isRealNode(b)) bR = this.extractor(b.key);
372
- else bR = this.extractor(b);
333
+ if (this.isEntry(b)) keyB = b[0];
334
+ else if (this.isRealNode(b)) keyB = b.key;
335
+ else if (this.toEntryFn) {
336
+ keyB = this.toEntryFn(b as R)[0];
337
+ } else {
338
+ keyB = b as K;
339
+ }
373
340
 
374
- return aR - bR;
341
+ if (keyA !== undefined && keyA !== null && keyB !== undefined && keyB !== null) {
342
+ return this.comparator(keyA, keyB);
343
+ }
344
+ return 0;
375
345
  });
376
346
 
377
- const _dfs = (arr: BTNodePureExemplar<K, V, NODE>[]) => {
347
+ const _dfs = (arr: (R | BTNPureKeyOrNodeOrEntry<K, V, NODE>)[]) => {
378
348
  if (arr.length === 0) return;
379
349
 
380
350
  const mid = Math.floor((arr.length - 1) / 2);
@@ -412,38 +382,32 @@ export class BST<
412
382
  }
413
383
 
414
384
  /**
415
- * Time Complexity: O(log n)
416
- * Space Complexity: O(k + log n)
417
- * /
418
-
419
- /**
420
385
  * Time Complexity: O(log n)
421
386
  * Space Complexity: O(k + log n)
422
387
  *
423
- * The function `getNodes` returns an array of nodes that match a given identifier, using either a
424
- * recursive or iterative approach.
388
+ * The `getNodes` function in TypeScript retrieves nodes from a binary tree based on a given
389
+ * identifier and callback function.
425
390
  * @param {ReturnType<C> | undefined} identifier - The `identifier` parameter is the value that you
426
- * want to search for in the nodes of the binary tree. It can be of any type that is returned by the
427
- * callback function `C`.
428
- * @param {C} callback - The `callback` parameter is a function that takes a node of type `NODE` as its
429
- * argument and returns a value of type `ReturnType<C>`. The `C` type parameter represents a callback
430
- * function type that extends the `BTNCallback<NODE>` type. The `BTNCallback<NODE>` type is
431
- * @param [onlyOne=false] - A boolean flag indicating whether to stop searching after finding the
432
- * first node that matches the identifier. If set to true, the function will return an array
433
- * containing only the first matching node. If set to false (default), the function will continue
434
- * searching for all nodes that match the identifier and return an array containing
435
- * @param {K | NODE | undefined} beginRoot - The `beginRoot` parameter represents the starting node
436
- * for the traversal. It can be either a key value or a node object. If it is undefined, the
437
- * traversal will start from the root of the tree.
438
- * @param iterationType - The `iterationType` parameter determines the type of iteration to be
439
- * performed on the binary tree. It can have two possible values:
440
- * @returns The method returns an array of nodes (`NODE[]`).
391
+ * want to search for in the binary tree. It can be of any type that is returned by the callback
392
+ * function.
393
+ * @param {C} callback - The `callback` parameter is a function that takes a node as input and
394
+ * returns a value. This value is used to identify the nodes that match the given identifier. The
395
+ * `callback` function is optional and defaults to `this._DEFAULT_CALLBACK`.
396
+ * @param [onlyOne=false] - A boolean value indicating whether to return only the first matching node
397
+ * or all matching nodes. If set to true, only the first matching node will be returned. If set to
398
+ * false, all matching nodes will be returned. The default value is false.
399
+ * @param {R | KeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter is the starting
400
+ * point for the search in the binary tree. It can be either a node object, a key-value pair, or an
401
+ * entry object. If it is not provided, the `root` of the binary tree is used as the starting point.
402
+ * @param {IterationType} iterationType - The `iterationType` parameter determines the type of
403
+ * iteration to be performed. It can have two possible values:
404
+ * @returns The method `getNodes` returns an array of `NODE` objects.
441
405
  */
442
406
  override getNodes<C extends BTNCallback<NODE>>(
443
407
  identifier: ReturnType<C> | undefined,
444
408
  callback: C = this._DEFAULT_CALLBACK as C,
445
409
  onlyOne = false,
446
- beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
410
+ beginRoot: R | KeyOrNodeOrEntry<K, V, NODE> = this.root,
447
411
  iterationType: IterationType = this.iterationType
448
412
  ): NODE[] {
449
413
  beginRoot = this.ensureNode(beginRoot);
@@ -462,8 +426,8 @@ export class BST<
462
426
  if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
463
427
  // TODO potential bug
464
428
  if (callback === this._DEFAULT_CALLBACK) {
465
- if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') dfs(cur.left);
466
- if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') dfs(cur.right);
429
+ if (this.isRealNode(cur.left) && this.comparator(cur.key, identifier as K) > 0) dfs(cur.left);
430
+ if (this.isRealNode(cur.right) && this.comparator(cur.key, identifier as K) < 0) dfs(cur.right);
467
431
  } else {
468
432
  this.isRealNode(cur.left) && dfs(cur.left);
469
433
  this.isRealNode(cur.right) && dfs(cur.right);
@@ -482,8 +446,8 @@ export class BST<
482
446
  }
483
447
  // TODO potential bug
484
448
  if (callback === this._DEFAULT_CALLBACK) {
485
- if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') stack.push(cur.right);
486
- if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') stack.push(cur.left);
449
+ if (this.isRealNode(cur.right) && this.comparator(cur.key, identifier as K) < 0) stack.push(cur.right);
450
+ if (this.isRealNode(cur.left) && this.comparator(cur.key, identifier as K) > 0) stack.push(cur.left);
487
451
 
488
452
  // if (this.isRealNode(cur.right) && this._lt(cur.key, identifier as K)) stack.push(cur.right);
489
453
  // if (this.isRealNode(cur.left) && this._gt(cur.key, identifier as K)) stack.push(cur.left);
@@ -511,58 +475,57 @@ export class BST<
511
475
  * Time Complexity: O(log n)
512
476
  * Space Complexity: O(1)
513
477
  *
514
- * The `getNode` function retrieves a node from a Red-Black Tree based on the provided identifier and
515
- * callback function.
516
- * @param {ReturnType<C> | undefined} identifier - The `identifier` parameter is the value or key
517
- * that you want to search for in the binary search tree. It can be of any type that is compatible
518
- * with the type of nodes in the tree.
519
- * @param {C} callback - The `callback` parameter is a function that will be called for each node in
520
- * the tree. It is used to determine whether a node matches the given identifier. The `callback`
521
- * function should take a node as its parameter and return a value that can be compared to the
522
- * `identifier` parameter.
478
+ * The function `getNode` returns the first node that matches the given identifier and callback
479
+ * function in a binary search tree.
480
+ * @param {ReturnType<C> | undefined} identifier - The `identifier` parameter is the value that you
481
+ * want to search for in the binary search tree. It can be of any type that is compatible with the
482
+ * type returned by the callback function.
483
+ * @param {C} callback - The `callback` parameter is a function that will be used to determine if a
484
+ * node matches the desired criteria. It should be a function that takes a node as an argument and
485
+ * returns a boolean value indicating whether the node matches the criteria or not. If no callback is
486
+ * provided, the default callback will be
523
487
  * @param beginRoot - The `beginRoot` parameter is the starting point for the search in the binary
524
- * search tree. It can be either a key or a node. If it is a key, it will be converted to a node
525
- * using the `ensureNode` method. If it is not provided, the `root`
526
- * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
527
- * be performed when searching for nodes in the binary search tree. It is an optional parameter and
528
- * its default value is taken from the `iterationType` property of the class.
529
- * @returns The method is returning a value of type `NODE | null | undefined`.
488
+ * search tree. It can be either a key or a node. If it is a key, the search will start from the node
489
+ * with that key. If it is a node, the search will start from that node.
490
+ * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type
491
+ * of iteration to be performed when searching for nodes in the binary search tree. It can have one
492
+ * of the following values:
493
+ * @returns The method is returning a NODE object or undefined.
530
494
  */
531
495
  override getNode<C extends BTNCallback<NODE>>(
532
496
  identifier: ReturnType<C> | undefined,
533
497
  callback: C = this._DEFAULT_CALLBACK as C,
534
- beginRoot: BSTNKeyOrNode<K, NODE> = this.root,
498
+ beginRoot: R | BSTNKeyOrNode<K, NODE> = this.root,
535
499
  iterationType: IterationType = this.iterationType
536
500
  ): NODE | undefined {
537
501
  return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined;
538
502
  }
539
503
 
540
504
  /**
541
- * Time Complexity: O(log n)
542
- * Space Complexity: O(1)
505
+ * Time Complexity: O(k log n)
506
+ * Space Complexity: O(k + log n)
543
507
  */
544
508
 
545
509
  /**
546
510
  * Time Complexity: O(log n)
547
511
  * Space Complexity: O(1)
548
512
  *
549
- * The function `getNodeByKey` searches for a node in a binary tree based on a given key, using
550
- * either recursive or iterative methods.
551
- * @param {K} key - The `key` parameter is the key value that we are searching for in the tree.
552
- * It is used to identify the node that we want to retrieve.
553
- * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
554
- * type of iteration to use when searching for a node in the binary tree. It can have two possible
555
- * values:
556
- * @returns The function `getNodeByKey` returns a node (`NODE`) if a node with the specified key is
557
- * found in the binary tree. If no node is found, it returns `undefined`.
513
+ * The function `getNodeByKey` returns a node with a specific key from a tree data structure.
514
+ * @param {K} key - The key parameter is the value used to search for a specific node in the tree. It
515
+ * is typically a unique identifier or a value that can be used to determine the position of the node
516
+ * in the tree structure.
517
+ * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional
518
+ * parameter that specifies the type of iteration to be used when searching for a node in the tree.
519
+ * It has a default value of `'ITERATIVE'`.
520
+ * @returns The method is returning a NODE object or undefined.
558
521
  */
559
522
  override getNodeByKey(key: K, iterationType: IterationType = 'ITERATIVE'): NODE | undefined {
560
523
  return this.getNode(key, this._DEFAULT_CALLBACK, this.root, iterationType);
561
524
  }
562
525
 
563
526
  /**
564
- * Time complexity: O(n)
565
- * Space complexity: O(n)
527
+ * Time Complexity: O(log n)
528
+ * Space Complexity: O(k + log n)
566
529
  */
567
530
 
568
531
  /**
@@ -572,30 +535,31 @@ export class BST<
572
535
  * The function overrides the depth-first search method and returns an array of the return types of
573
536
  * the callback function.
574
537
  * @param {C} callback - The `callback` parameter is a function that will be called for each node
575
- * during the depth-first search traversal. It is an optional parameter and if not provided, a
576
- * default callback function will be used.
577
- * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter specifies the order in which the
578
- * nodes are visited during the depth-first search. It can have one of the following values:
579
- * @param beginRoot - The `beginRoot` parameter is used to specify the starting point for the
580
- * Depth-First Search (DFS) traversal. It can be either a key, a node, or an entry in the tree. If no
581
- * value is provided, the DFS traversal will start from the root of the tree.
582
- * @param {IterationType} iterationType - The `iterationType` parameter specifies the type of
583
- * iteration to be used during the Depth-First Search (DFS) traversal. It can have one of the
538
+ * during the depth-first search traversal. It is an optional parameter and defaults to
539
+ * `this._DEFAULT_CALLBACK`. The type `C` represents the type of the callback function.
540
+ * @param {DFSOrderPattern} [pattern=IN] - The "pattern" parameter in the code snippet refers to the
541
+ * order in which the Depth-First Search (DFS) algorithm visits the nodes in a tree or graph. It can
542
+ * take one of the following values:
543
+ * @param {R | KeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter is the starting
544
+ * point for the depth-first search traversal. It can be either a root node, a key-value pair, or a
545
+ * node entry. If not specified, the default value is the root of the tree.
546
+ * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter specifies the
547
+ * type of iteration to be used during the Depth-First Search (DFS) traversal. It can have one of the
584
548
  * following values:
585
549
  * @returns The method is returning an array of the return type of the callback function.
586
550
  */
587
551
  override dfs<C extends BTNCallback<NODE>>(
588
552
  callback: C = this._DEFAULT_CALLBACK as C,
589
553
  pattern: DFSOrderPattern = 'IN',
590
- beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
554
+ beginRoot: R | KeyOrNodeOrEntry<K, V, NODE> = this.root,
591
555
  iterationType: IterationType = 'ITERATIVE'
592
556
  ): ReturnType<C>[] {
593
557
  return super.dfs(callback, pattern, beginRoot, iterationType, false);
594
558
  }
595
559
 
596
560
  /**
597
- * Time complexity: O(n)
598
- * Space complexity: O(n)
561
+ * Time Complexity: O(log n)
562
+ * Space Complexity: O(1)
599
563
  */
600
564
 
601
565
  /**
@@ -605,134 +569,98 @@ export class BST<
605
569
  * The function overrides the breadth-first search method and returns an array of the return types of
606
570
  * the callback function.
607
571
  * @param {C} callback - The `callback` parameter is a function that will be called for each node
608
- * visited during the breadth-first search traversal. It is an optional parameter and if not
609
- * provided, a default callback function will be used.
610
- * @param beginRoot - The `beginRoot` parameter is the starting point for the breadth-first search
611
- * traversal. It can be either a key, a node, or an entry in the tree. If not specified, the root of
612
- * the tree is used as the starting point.
613
- * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
614
- * be performed during the breadth-first search (BFS) traversal. It determines the order in which the
615
- * nodes are visited.
616
- * @returns The method is returning an array of the return type of the callback function.
572
+ * visited during the breadth-first search. It should take a single argument, which is the current
573
+ * node being visited, and it can return a value of any type.
574
+ * @param {R | KeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter is the starting
575
+ * point for the breadth-first search. It can be either a root node, a key-value pair, or an entry
576
+ * object. If no value is provided, the default value is the root of the tree.
577
+ * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type
578
+ * of iteration to be performed during the breadth-first search (BFS) traversal. It can have one of
579
+ * the following values:
580
+ * @returns an array of the return type of the callback function.
617
581
  */
618
582
  override bfs<C extends BTNCallback<NODE>>(
619
583
  callback: C = this._DEFAULT_CALLBACK as C,
620
- beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
584
+ beginRoot: R | KeyOrNodeOrEntry<K, V, NODE> = this.root,
621
585
  iterationType: IterationType = this.iterationType
622
586
  ): ReturnType<C>[] {
623
587
  return super.bfs(callback, beginRoot, iterationType, false);
624
588
  }
625
589
 
626
590
  /**
627
- * Time complexity: O(n)
628
- * Space complexity: O(n)
591
+ * Time Complexity: O(log n)
592
+ * Space Complexity: O(1)
629
593
  */
630
594
 
631
595
  /**
632
596
  * Time complexity: O(n)
633
597
  * Space complexity: O(n)
634
598
  *
635
- * The function overrides the listLevels method and returns an array of arrays containing the return
636
- * type of the callback function for each level of the tree.
599
+ * The function overrides the listLevels method from the superclass and returns an array of arrays
600
+ * containing the results of the callback function applied to each level of the tree.
637
601
  * @param {C} callback - The `callback` parameter is a generic type `C` that extends
638
- * `BTNCallback<NODE>`. It represents a callback function that will be called for each node in the tree
639
- * during the level listing process.
640
- * @param beginRoot - The `beginRoot` parameter is used to specify the starting point for listing the
641
- * levels of a binary tree. It can be either a key, a node, or an entry in the binary tree. If not
642
- * provided, the root of the binary tree is used as the starting point.
643
- * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
644
- * be performed on the tree. It determines the order in which the nodes are visited during the
645
- * iteration.
602
+ * `BTNCallback<NODE>`. It represents a callback function that will be called for each node in the
603
+ * tree during the iteration process.
604
+ * @param {R | KeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter is the starting
605
+ * point for listing the levels of the binary tree. It can be either a root node of the tree, a
606
+ * key-value pair representing a node in the tree, or a key representing a node in the tree. If no
607
+ * value is provided, the root of
608
+ * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type
609
+ * of iteration to be performed on the tree. It can have one of the following values:
646
610
  * @returns The method is returning a two-dimensional array of the return type of the callback
647
611
  * function.
648
612
  */
649
613
  override listLevels<C extends BTNCallback<NODE>>(
650
614
  callback: C = this._DEFAULT_CALLBACK as C,
651
- beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
615
+ beginRoot: R | KeyOrNodeOrEntry<K, V, NODE> = this.root,
652
616
  iterationType: IterationType = this.iterationType
653
617
  ): ReturnType<C>[][] {
654
618
  return super.listLevels(callback, beginRoot, iterationType, false);
655
619
  }
656
620
 
657
621
  /**
658
- * Time Complexity: O(log n)
659
- * Space Complexity: O(1)
660
- */
661
-
662
- /**
663
- * Time Complexity: O(log n)
664
- * Space Complexity: O(1)
665
- *
666
- * The `lastKey` function returns the key of the rightmost node in a binary tree, or the key of the
667
- * leftmost node if the comparison result is greater than.
668
- * @param {K | NODE | undefined} beginRoot - The `beginRoot` parameter is optional and can be of
669
- * type `K`, `NODE`, or `undefined`. It represents the starting point for finding the last key in
670
- * the binary tree. If not provided, it defaults to the root of the binary tree (`this.root`).
671
- * @returns the key of the rightmost node in the binary tree if the comparison result is less than,
672
- * the key of the leftmost node if the comparison result is greater than, and the key of the
673
- * rightmost node otherwise. If no node is found, it returns 0.
674
- */
675
- lastKey(beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root): K | undefined {
676
- let current = this.ensureNode(beginRoot);
677
- if (!current) return undefined;
678
-
679
- if (this._variant === 'STANDARD') {
680
- // For 'STANDARD', find the rightmost node
681
- while (current.right !== undefined) {
682
- current = current.right;
683
- }
684
- } else {
685
- // For BSTVariant.MAX, find the leftmost node
686
- while (current.left !== undefined) {
687
- current = current.left;
688
- }
689
- }
690
- return current.key;
691
- }
692
-
693
- /**
694
- * Time Complexity: O(log n)
695
- * Space Complexity: O(log n)
622
+ * Time complexity: O(n)
623
+ * Space complexity: O(n)
696
624
  */
697
625
 
698
626
  /**
699
- * Time Complexity: O(log n)
700
- * Space Complexity: O(log n)
627
+ * Time complexity: O(n)
628
+ * Space complexity: O(n)
701
629
  *
702
- * The `lesserOrGreaterTraverse` function traverses a binary tree and returns an array of nodes that
703
- * are either lesser or greater than a target node, depending on the specified comparison type.
630
+ * The `lesserOrGreaterTraverse` function traverses a binary tree and applies a callback function to
631
+ * each node that meets a certain condition based on a target node and a comparison value.
704
632
  * @param {C} callback - The `callback` parameter is a function that will be called for each node
705
- * that satisfies the condition specified by the `lesserOrGreater` parameter. It takes a single
706
- * parameter of type `NODE` (the node type) and returns a value of any type.
633
+ * that meets the condition specified by the `lesserOrGreater` parameter. It takes a single argument,
634
+ * which is the current node being traversed, and returns a value of any type.
707
635
  * @param {CP} lesserOrGreater - The `lesserOrGreater` parameter is used to determine whether to
708
- * traverse nodes that are lesser than, greater than, or equal to the `targetNode`. It is of type
709
- * `CP`, which is a custom type representing the comparison operator. The possible values for
710
- * `lesserOrGreater` are
711
- * @param {K | NODE | undefined} targetNode - The `targetNode` parameter represents the node in the
712
- * binary tree that you want to traverse from. It can be specified either by its key, by the node
713
- * object itself, or it can be left undefined to start the traversal from the root of the tree.
714
- * @param iterationType - The `iterationType` parameter determines the type of traversal to be
715
- * performed on the binary tree. It can have two possible values:
636
+ * traverse nodes that are lesser, greater, or both than the `targetNode`. It accepts the values -1,
637
+ * 0, or 1, where:
638
+ * @param {R | KeyOrNodeOrEntry<K, V, NODE>} targetNode - The `targetNode` parameter is the node in
639
+ * the binary tree that you want to start traversing from. It can be specified either by providing
640
+ * the key of the node, the node itself, or an entry containing the key and value of the node. If no
641
+ * `targetNode` is provided,
642
+ * @param {IterationType} iterationType - The `iterationType` parameter determines the type of
643
+ * traversal to be performed on the binary tree. It can have two possible values:
716
644
  * @returns The function `lesserOrGreaterTraverse` returns an array of values of type
717
645
  * `ReturnType<C>`, which is the return type of the callback function passed as an argument.
718
646
  */
719
647
  lesserOrGreaterTraverse<C extends BTNCallback<NODE>>(
720
648
  callback: C = this._DEFAULT_CALLBACK as C,
721
- lesserOrGreater: CP = 'LT',
722
- targetNode: KeyOrNodeOrEntry<K, V, NODE> = this.root,
649
+ lesserOrGreater: CP = -1,
650
+ targetNode: R | KeyOrNodeOrEntry<K, V, NODE> = this.root,
723
651
  iterationType: IterationType = this.iterationType
724
652
  ): ReturnType<C>[] {
725
- targetNode = this.ensureNode(targetNode);
653
+ const targetNodeEnsured = this.ensureNode(targetNode);
726
654
  const ans: ReturnType<BTNCallback<NODE>>[] = [];
727
- if (!targetNode) return ans;
655
+ if (!targetNodeEnsured) return ans;
728
656
  if (!this.root) return ans;
729
657
 
730
- const targetKey = targetNode.key;
658
+ const targetKey = targetNodeEnsured.key;
731
659
 
732
660
  if (iterationType === 'RECURSIVE') {
733
661
  const dfs = (cur: NODE) => {
734
- const compared = this._compare(cur.key, targetKey);
735
- if (compared === lesserOrGreater) ans.push(callback(cur));
662
+ const compared = this.comparator(cur.key, targetKey);
663
+ if (Math.sign(compared) === lesserOrGreater) ans.push(callback(cur));
736
664
 
737
665
  if (this.isRealNode(cur.left)) dfs(cur.left);
738
666
  if (this.isRealNode(cur.right)) dfs(cur.right);
@@ -745,8 +673,8 @@ export class BST<
745
673
  while (queue.size > 0) {
746
674
  const cur = queue.shift();
747
675
  if (this.isRealNode(cur)) {
748
- const compared = this._compare(cur.key, targetKey);
749
- if (compared === lesserOrGreater) ans.push(callback(cur));
676
+ const compared = this.comparator(cur.key, targetKey);
677
+ if (Math.sign(compared) === lesserOrGreater) ans.push(callback(cur));
750
678
 
751
679
  if (this.isRealNode(cur.left)) queue.push(cur.left);
752
680
  if (this.isRealNode(cur.right)) queue.push(cur.right);
@@ -757,19 +685,20 @@ export class BST<
757
685
  }
758
686
 
759
687
  /**
760
- * Time Complexity: O(log n)
761
- * Space Complexity: O(log n)
688
+ * Time complexity: O(n)
689
+ * Space complexity: O(n)
762
690
  */
763
691
 
764
692
  /**
765
- * Time Complexity: O(log n)
766
- * Space Complexity: O(log n)
693
+ * Time complexity: O(n)
694
+ * Space complexity: O(n)
767
695
  *
768
- * The `perfectlyBalance` function balances a binary search tree by adding nodes in a way that
769
- * ensures the tree is perfectly balanced.
770
- * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
771
- * type of iteration to use when building a balanced binary search tree. It can have two possible
772
- * values:
696
+ * The `perfectlyBalance` function takes an optional `iterationType` parameter and returns `true` if
697
+ * the binary search tree is perfectly balanced, otherwise it returns `false`.
698
+ * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that
699
+ * specifies the type of iteration to use when building a balanced binary search tree. It has a
700
+ * default value of `this.iterationType`, which means it will use the iteration type specified in the
701
+ * current instance of the class.
773
702
  * @returns The function `perfectlyBalance` returns a boolean value.
774
703
  */
775
704
  perfectlyBalance(iterationType: IterationType = this.iterationType): boolean {
@@ -810,27 +739,20 @@ export class BST<
810
739
  }
811
740
 
812
741
  /**
813
- * Balancing Adjustment:
814
- * Perfectly Balanced Binary Tree: Since the balance of a perfectly balanced binary tree is already fixed, no additional balancing adjustment is needed. Any insertion or deletion operation will disrupt the perfect balance, often requiring a complete reconstruction of the tree.
815
- * AVL Tree: After insertion or deletion operations, an AVL tree performs rotation adjustments based on the balance factor of nodes to restore the tree's balance. These rotations can be left rotations, right rotations, left-right rotations, or right-left rotations, performed as needed.
816
- *
817
- * Use Cases and Efficiency:
818
- * Perfectly Balanced Binary Tree: Perfectly balanced binary trees are typically used in specific scenarios such as complete binary heaps in heap sort or certain types of Huffman trees. However, they are not suitable for dynamic operations requiring frequent insertions and deletions, as these operations often necessitate full tree reconstruction.
819
- * AVL Tree: AVL trees are well-suited for scenarios involving frequent searching, insertion, and deletion operations. Through rotation adjustments, AVL trees maintain their balance, ensuring average and worst-case time complexity of O(log n).
820
- */
821
-
822
- /**
823
- * Time Complexity: O(n)
824
- * Space Complexity: O(log n)
742
+ * Time complexity: O(n)
743
+ * Space complexity: O(n)
825
744
  */
826
745
 
827
746
  /**
828
747
  * Time Complexity: O(n)
829
748
  * Space Complexity: O(log n)
830
749
  *
831
- * The function checks if a binary tree is AVL balanced using either recursive or iterative approach.
832
- * @param iterationType - The `iterationType` parameter is used to determine the method of iteration
833
- * to check if the AVL tree is balanced. It can have two possible values:
750
+ * The function `isAVLBalanced` checks if a binary tree is AVL balanced using either a recursive or
751
+ * iterative approach.
752
+ * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that
753
+ * specifies the type of iteration to use when checking if the AVL tree is balanced. It has a default
754
+ * value of `this.iterationType`, which means it will use the iteration type specified in the current
755
+ * instance of the AVL tree.
834
756
  * @returns a boolean value.
835
757
  */
836
758
  isAVLBalanced(iterationType: IterationType = this.iterationType): boolean {
@@ -878,61 +800,50 @@ export class BST<
878
800
  }
879
801
 
880
802
  /**
881
- * The function sets the root property of an object and updates the parent property of the new root.
882
- * @param {NODE | undefined} v - The parameter `v` is of type `NODE | undefined`. This means that it
883
- * can either be an object of type `NODE` or it can be `undefined`.
803
+ * Time complexity: O(n)
804
+ * Space complexity: O(n)
884
805
  */
885
- protected override _setRoot(v: NODE | undefined) {
886
- if (v) {
887
- v.parent = undefined;
806
+
807
+ protected _DEFAULT_COMPARATOR = (a: K, b: K): number => {
808
+ if (typeof a === 'object' && typeof b === 'object' && this.comparator === this._DEFAULT_COMPARATOR) {
809
+ throw TypeError(
810
+ 'When comparing two object types, it is necessary to customize a [comparator] function of options parameter during the instantiation of the data structure.'
811
+ );
888
812
  }
889
- this._root = v;
890
- }
813
+ if (a > b) return 1;
814
+ if (a < b) return -1;
815
+ return 0;
816
+ };
891
817
 
892
818
  /**
893
- * The function compares two values using a comparator function and returns whether the first value
894
- * is greater than, less than, or equal to the second value.
895
- * @param {K} a - The parameter "a" is of type K.
896
- * @param {K} b - The parameter "b" in the above code represents a K.
897
- * @returns a value of type CP (ComparisonResult). The possible return values are 'GT' (greater
898
- * than), 'LT' (less than), or 'EQ' (equal).
819
+ * Time complexity: O(n)
820
+ * Space complexity: O(n)
899
821
  */
900
- protected _compare(a: K, b: K): CP {
901
- const extractedA = this.extractor(a);
902
- const extractedB = this.extractor(b);
903
- const compared = this.variant === 'STANDARD' ? extractedA - extractedB : extractedB - extractedA;
904
822
 
905
- if (compared > 0) return 'GT';
906
- if (compared < 0) return 'LT';
907
- return 'EQ';
908
- }
823
+ protected _comparator: Comparator<K> = this._DEFAULT_COMPARATOR;
909
824
 
910
825
  /**
911
- * The function `_lt` compares two values `a` and `b` using an extractor function and returns true if
912
- * `a` is less than `b` based on the specified variant.
913
- * @param {K} a - The parameter "a" is of type "K", which means it can be any type. It represents the
914
- * first value to be compared in the function.
915
- * @param {K} b - The parameter `b` is of type `K`, which means it can be any type. It is used as one
916
- * of the arguments for the comparison in the `_lt` function.
917
- * @returns a boolean value.
826
+ * Time Complexity: O(n)
827
+ * Space Complexity: O(log n)
828
+ */
829
+
830
+ /**
831
+ * The function returns the value of the _comparator property.
832
+ * @returns The `_comparator` property is being returned.
918
833
  */
919
- protected _lt(a: K, b: K): boolean {
920
- const extractedA = this.extractor(a);
921
- const extractedB = this.extractor(b);
922
- return this.variant === 'STANDARD' ? extractedA < extractedB : extractedA > extractedB;
834
+ get comparator() {
835
+ return this._comparator;
923
836
  }
924
837
 
925
838
  /**
926
- * The function compares two values using a custom extractor function and returns true if the first
927
- * value is greater than the second value.
928
- * @param {K} a - The parameter "a" is of type K, which means it can be any type.
929
- * @param {K} b - The parameter "b" is of type K, which means it can be any type. It is used as one
930
- * of the arguments for the comparison in the function.
931
- * @returns a boolean value.
839
+ * The function sets the root of a tree-like structure and updates the parent property of the new
840
+ * root.
841
+ * @param {NODE | undefined} v - v is a parameter of type NODE or undefined.
932
842
  */
933
- protected _gt(a: K, b: K): boolean {
934
- const extractedA = this.extractor(a);
935
- const extractedB = this.extractor(b);
936
- return this.variant === 'STANDARD' ? extractedA > extractedB : extractedA < extractedB;
843
+ protected override _setRoot(v: NODE | undefined) {
844
+ if (v) {
845
+ v.parent = undefined;
846
+ }
847
+ this._root = v;
937
848
  }
938
849
  }