directed-graph-typed 1.48.0 → 1.49.0

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 (89) hide show
  1. package/dist/data-structures/base/index.d.ts +1 -0
  2. package/dist/data-structures/base/index.js +17 -0
  3. package/dist/data-structures/base/iterable-base.d.ts +232 -0
  4. package/dist/data-structures/base/iterable-base.js +312 -0
  5. package/dist/data-structures/binary-tree/avl-tree.d.ts +28 -19
  6. package/dist/data-structures/binary-tree/avl-tree.js +22 -11
  7. package/dist/data-structures/binary-tree/binary-tree.d.ts +158 -152
  8. package/dist/data-structures/binary-tree/binary-tree.js +241 -215
  9. package/dist/data-structures/binary-tree/bst.d.ts +64 -48
  10. package/dist/data-structures/binary-tree/bst.js +94 -65
  11. package/dist/data-structures/binary-tree/rb-tree.d.ts +39 -39
  12. package/dist/data-structures/binary-tree/rb-tree.js +42 -49
  13. package/dist/data-structures/binary-tree/tree-multimap.d.ts +60 -34
  14. package/dist/data-structures/binary-tree/tree-multimap.js +59 -27
  15. package/dist/data-structures/graph/abstract-graph.d.ts +92 -53
  16. package/dist/data-structures/graph/abstract-graph.js +130 -103
  17. package/dist/data-structures/graph/directed-graph.d.ts +70 -52
  18. package/dist/data-structures/graph/directed-graph.js +111 -65
  19. package/dist/data-structures/graph/map-graph.d.ts +5 -5
  20. package/dist/data-structures/graph/map-graph.js +8 -8
  21. package/dist/data-structures/graph/undirected-graph.d.ts +51 -32
  22. package/dist/data-structures/graph/undirected-graph.js +117 -54
  23. package/dist/data-structures/hash/hash-map.d.ts +160 -44
  24. package/dist/data-structures/hash/hash-map.js +314 -82
  25. package/dist/data-structures/heap/heap.d.ts +50 -7
  26. package/dist/data-structures/heap/heap.js +60 -30
  27. package/dist/data-structures/index.d.ts +1 -0
  28. package/dist/data-structures/index.js +1 -0
  29. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +42 -55
  30. package/dist/data-structures/linked-list/doubly-linked-list.js +50 -77
  31. package/dist/data-structures/linked-list/singly-linked-list.d.ts +36 -55
  32. package/dist/data-structures/linked-list/singly-linked-list.js +44 -77
  33. package/dist/data-structures/queue/deque.d.ts +35 -167
  34. package/dist/data-structures/queue/deque.js +43 -249
  35. package/dist/data-structures/queue/queue.d.ts +49 -48
  36. package/dist/data-structures/queue/queue.js +69 -82
  37. package/dist/data-structures/stack/stack.d.ts +43 -10
  38. package/dist/data-structures/stack/stack.js +50 -31
  39. package/dist/data-structures/trie/trie.d.ts +41 -6
  40. package/dist/data-structures/trie/trie.js +53 -32
  41. package/dist/interfaces/binary-tree.d.ts +6 -6
  42. package/dist/types/common.d.ts +11 -8
  43. package/dist/types/common.js +6 -1
  44. package/dist/types/data-structures/base/base.d.ts +5 -0
  45. package/dist/types/data-structures/base/base.js +2 -0
  46. package/dist/types/data-structures/base/index.d.ts +1 -0
  47. package/dist/types/data-structures/base/index.js +17 -0
  48. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +3 -3
  49. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +4 -4
  50. package/dist/types/data-structures/binary-tree/bst.d.ts +6 -6
  51. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +3 -3
  52. package/dist/types/data-structures/binary-tree/tree-multimap.d.ts +3 -3
  53. package/dist/types/data-structures/hash/hash-map.d.ts +4 -0
  54. package/dist/types/data-structures/index.d.ts +1 -0
  55. package/dist/types/data-structures/index.js +1 -0
  56. package/package.json +2 -2
  57. package/src/data-structures/base/index.ts +1 -0
  58. package/src/data-structures/base/iterable-base.ts +329 -0
  59. package/src/data-structures/binary-tree/avl-tree.ts +37 -25
  60. package/src/data-structures/binary-tree/binary-tree.ts +336 -296
  61. package/src/data-structures/binary-tree/bst.ts +135 -89
  62. package/src/data-structures/binary-tree/rb-tree.ts +60 -69
  63. package/src/data-structures/binary-tree/tree-multimap.ts +86 -49
  64. package/src/data-structures/graph/abstract-graph.ts +136 -104
  65. package/src/data-structures/graph/directed-graph.ts +114 -65
  66. package/src/data-structures/graph/map-graph.ts +8 -8
  67. package/src/data-structures/graph/undirected-graph.ts +124 -56
  68. package/src/data-structures/hash/hash-map.ts +335 -84
  69. package/src/data-structures/heap/heap.ts +63 -36
  70. package/src/data-structures/index.ts +1 -0
  71. package/src/data-structures/linked-list/doubly-linked-list.ts +54 -83
  72. package/src/data-structures/linked-list/singly-linked-list.ts +49 -84
  73. package/src/data-structures/queue/deque.ts +43 -275
  74. package/src/data-structures/queue/queue.ts +71 -86
  75. package/src/data-structures/stack/stack.ts +53 -34
  76. package/src/data-structures/trie/trie.ts +58 -35
  77. package/src/interfaces/binary-tree.ts +5 -6
  78. package/src/types/common.ts +11 -8
  79. package/src/types/data-structures/base/base.ts +6 -0
  80. package/src/types/data-structures/base/index.ts +1 -0
  81. package/src/types/data-structures/binary-tree/avl-tree.ts +3 -3
  82. package/src/types/data-structures/binary-tree/binary-tree.ts +6 -5
  83. package/src/types/data-structures/binary-tree/bst.ts +6 -6
  84. package/src/types/data-structures/binary-tree/rb-tree.ts +3 -3
  85. package/src/types/data-structures/binary-tree/tree-multimap.ts +3 -3
  86. package/src/types/data-structures/hash/hash-map.ts +2 -0
  87. package/src/types/data-structures/heap/heap.ts +1 -1
  88. package/src/types/data-structures/index.ts +1 -0
  89. package/src/types/data-structures/priority-queue/priority-queue.ts +1 -1
@@ -11,20 +11,18 @@ import type {
11
11
  BSTNodeNested,
12
12
  BSTOptions,
13
13
  BTNCallback,
14
- BTNKey,
15
14
  BTNodeExemplar,
16
- BTNodePureExemplar,
17
- Comparator
15
+ BTNodePureExemplar
18
16
  } from '../../types';
19
- import { CP, IterationType } from '../../types';
17
+ import { BSTVariant, BTNodeKeyOrNode, CP, IterationType } from '../../types';
20
18
  import { BinaryTree, BinaryTreeNode } from './binary-tree';
21
19
  import { IBinaryTree } from '../../interfaces';
22
20
  import { Queue } from '../queue';
23
21
 
24
- export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extends BinaryTreeNode<V, N> {
22
+ export class BSTNode<K = any, V = any, N extends BSTNode<K, V, N> = BSTNodeNested<K, V>> extends BinaryTreeNode<K, V, N> {
25
23
  override parent?: N;
26
24
 
27
- constructor(key: BTNKey, value?: V) {
25
+ constructor(key: K, value?: V) {
28
26
  super(key, value);
29
27
  this.parent = undefined;
30
28
  this._left = undefined;
@@ -81,9 +79,9 @@ export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extend
81
79
  * 6. Balance Variability: Can become unbalanced; special types maintain balance.
82
80
  * 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.
83
81
  */
84
- export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>, TREE extends BST<V, N, TREE> = BST<V, N, BSTNested<V, N>>>
85
- extends BinaryTree<V, N, TREE>
86
- implements IBinaryTree<V, N, TREE> {
82
+ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BSTNodeNested<K, V>>, TREE extends BST<K, V, N, TREE> = BST<K, V, N, BSTNested<K, V, N>>>
83
+ extends BinaryTree<K, V, N, TREE>
84
+ implements IBinaryTree<K, V, N, TREE> {
87
85
 
88
86
 
89
87
  /**
@@ -94,13 +92,13 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
94
92
  * @param [options] - The `options` parameter is an optional object that can contain additional
95
93
  * configuration options for the binary search tree. It can have the following properties:
96
94
  */
97
- constructor(elements?: Iterable<BTNodeExemplar<V, N>>, options?: Partial<BSTOptions>) {
95
+ constructor(elements?: Iterable<BTNodeExemplar<K, V, N>>, options?: Partial<BSTOptions<K>>) {
98
96
  super([], options);
99
97
 
100
98
  if (options) {
101
- const { comparator } = options;
102
- if (comparator) {
103
- this.comparator = comparator;
99
+ const { variant } = options;
100
+ if (variant) {
101
+ this._variant = variant;
104
102
  }
105
103
  }
106
104
 
@@ -115,18 +113,22 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
115
113
  return this._root;
116
114
  }
117
115
 
118
- comparator: Comparator<BTNKey> = (a, b) => a - b
116
+ protected _variant = BSTVariant.MIN
117
+
118
+ get variant() {
119
+ return this._variant;
120
+ }
119
121
 
120
122
  /**
121
123
  * The function creates a new binary search tree node with the given key and value.
122
- * @param {BTNKey} key - The key parameter is the key value that will be associated with
124
+ * @param {K} key - The key parameter is the key value that will be associated with
123
125
  * the new node. It is used to determine the position of the node in the binary search tree.
124
126
  * @param [value] - The parameter `value` is an optional value that can be assigned to the node. It
125
127
  * represents the value associated with the node in a binary search tree.
126
128
  * @returns a new instance of the BSTNode class with the specified key and value.
127
129
  */
128
- override createNode(key: BTNKey, value?: V): N {
129
- return new BSTNode<V, N>(key, value) as N;
130
+ override createNode(key: K, value?: V): N {
131
+ return new BSTNode<K, V, N>(key, value) as N;
130
132
  }
131
133
 
132
134
  /**
@@ -136,29 +138,32 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
136
138
  * that defines various options for creating a binary search tree.
137
139
  * @returns a new instance of the BST class with the specified options.
138
140
  */
139
- override createTree(options?: Partial<BSTOptions>): TREE {
140
- return new BST<V, N, TREE>([], {
141
+ override createTree(options?: Partial<BSTOptions<K>>): TREE {
142
+ return new BST<K, V, N, TREE>([], {
141
143
  iterationType: this.iterationType,
142
- comparator: this.comparator, ...options
144
+ variant: this.variant, ...options
143
145
  }) as TREE;
144
146
  }
145
147
 
146
148
  /**
147
149
  * The function checks if an exemplar is an instance of BSTNode.
148
- * @param exemplar - The `exemplar` parameter is a variable of type `BTNodeExemplar<V, N>`.
150
+ * @param exemplar - The `exemplar` parameter is a variable of type `BTNodeExemplar<K, V, N>`.
149
151
  * @returns a boolean value indicating whether the exemplar is an instance of the BSTNode class.
150
152
  */
151
- override isNode(exemplar: BTNodeExemplar<V, N>): exemplar is N {
153
+ override isNode(exemplar: BTNodeExemplar<K, V, N>): exemplar is N {
152
154
  return exemplar instanceof BSTNode;
153
155
  }
154
156
 
157
+
155
158
  /**
156
- * The function `exemplarToNode` takes an exemplar and returns a corresponding node if the exemplar
157
- * is valid, otherwise it returns undefined.
158
- * @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<V, N>`.
159
- * @returns a variable `node` which is of type `N` or `undefined`.
159
+ * The function `exemplarToNode` takes an exemplar and returns a node if the exemplar is valid,
160
+ * otherwise it returns undefined.
161
+ * @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<K, V, N>`, where:
162
+ * @param {V} [value] - The `value` parameter is an optional value that can be passed to the
163
+ * `exemplarToNode` function. It represents the value associated with the exemplar node.
164
+ * @returns a node of type N or undefined.
160
165
  */
161
- override exemplarToNode(exemplar: BTNodeExemplar<V, N>): N | undefined {
166
+ override exemplarToNode(exemplar: BTNodeExemplar<K, V, N>, value?: V): N | undefined {
162
167
  let node: N | undefined;
163
168
  if (exemplar === null || exemplar === undefined) {
164
169
  return;
@@ -171,8 +176,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
171
176
  } else {
172
177
  node = this.createNode(key, value);
173
178
  }
174
- } else if (this.isNodeKey(exemplar)) {
175
- node = this.createNode(exemplar);
179
+ } else if (this.isNotNodeInstance(exemplar)) {
180
+ node = this.createNode(exemplar, value);
176
181
  } else {
177
182
  return;
178
183
  }
@@ -188,14 +193,16 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
188
193
  * Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n).
189
194
  * Space Complexity: O(1) - Constant space is used.
190
195
  *
191
- * The `add` function adds a new node to a binary search tree, either by key or by providing a node
192
- * object.
193
- * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be one of the following:
194
- * @returns The method returns either the newly added node (`newNode`) or `undefined` if the input
195
- * (`keyOrNodeOrEntry`) is null, undefined, or does not match any of the expected types.
196
+ * The `add` function adds a new node to a binary tree, updating the value if the key already exists
197
+ * or inserting a new node if the key is unique.
198
+ * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can accept three types of values:
199
+ * @param {V} [value] - The `value` parameter represents the value associated with the key that is
200
+ * being added to the binary tree.
201
+ * @returns The method `add` returns either the newly added node (`newNode`) or `undefined` if the
202
+ * node was not added.
196
203
  */
197
- override add(keyOrNodeOrEntry: BTNodeExemplar<V, N>): N | undefined {
198
- const newNode = this.exemplarToNode(keyOrNodeOrEntry);
204
+ override add(keyOrNodeOrEntry: BTNodeExemplar<K, V, N>, value?: V): N | undefined {
205
+ const newNode = this.exemplarToNode(keyOrNodeOrEntry, value);
199
206
  if (newNode === undefined) return;
200
207
 
201
208
  if (this.root === undefined) {
@@ -249,34 +256,48 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
249
256
  * Time Complexity: O(k log n) - Adding each element individually in a balanced tree.
250
257
  * Space Complexity: O(k) - Additional space is required for the sorted array.
251
258
  *
252
- * The `addMany` function in TypeScript adds multiple nodes to a binary tree, either in a balanced or
253
- * unbalanced manner, and returns an array of the inserted nodes.
254
- * @param keysOrNodesOrEntries - An iterable containing keys, nodes, or entries to be added to the
255
- * binary tree.
256
- * @param [isBalanceAdd=true] - A boolean flag indicating whether the tree should be balanced after
257
- * adding the nodes. The default value is true.
259
+ * The `addMany` function in TypeScript adds multiple keys or nodes to a binary tree, optionally
260
+ * balancing the tree after each addition.
261
+ * @param keysOrNodesOrEntries - An iterable containing the keys, nodes, or entries to be added to
262
+ * the binary tree.
263
+ * @param [values] - An optional iterable of values to be associated with the keys or nodes being
264
+ * added. If provided, the values will be assigned to the corresponding keys or nodes in the same
265
+ * order. If not provided, undefined will be assigned as the value for each key or node.
266
+ * @param [isBalanceAdd=true] - A boolean flag indicating whether the add operation should be
267
+ * balanced or not. If set to true, the add operation will be balanced using a binary search tree
268
+ * algorithm. If set to false, the add operation will not be balanced and the elements will be added
269
+ * in the order they appear in the input.
258
270
  * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
259
- * type of iteration to use when adding multiple keys or nodes to the binary tree. It has a default
260
- * value of `this.iterationType`, which means it will use the iteration type specified by the binary
261
- * tree instance.
262
- * @returns The `addMany` function returns an array of `N` or `undefined` values.
271
+ * type of iteration to use when adding multiple keys or nodes. It has a default value of
272
+ * `this.iterationType`, which suggests that it is a property of the current object.
273
+ * @returns The function `addMany` returns an array of nodes (`N`) or `undefined` values.
263
274
  */
264
275
  override addMany(
265
- keysOrNodesOrEntries: Iterable<BTNodeExemplar<V, N>>,
276
+ keysOrNodesOrEntries: Iterable<BTNodeExemplar<K, V, N>>,
277
+ values?: Iterable<V | undefined>,
266
278
  isBalanceAdd = true,
267
279
  iterationType = this.iterationType
268
280
  ): (N | undefined)[] {
269
- const inserted: (N | undefined)[] = []
281
+ const inserted: (N | undefined)[] = [];
282
+
283
+ let valuesIterator: Iterator<V | undefined> | undefined;
284
+
285
+ if (values) {
286
+ valuesIterator = values[Symbol.iterator]();
287
+ }
288
+
270
289
  if (!isBalanceAdd) {
271
290
  for (const kve of keysOrNodesOrEntries) {
272
- const nn = this.add(kve)
291
+ const value = valuesIterator?.next().value;
292
+ const nn = this.add(kve, value);
273
293
  inserted.push(nn);
274
294
  }
275
295
  return inserted;
276
296
  }
277
- const realBTNExemplars: BTNodePureExemplar<V, N>[] = [];
278
297
 
279
- const isRealBTNExemplar = (kve: BTNodeExemplar<V, N>): kve is BTNodePureExemplar<V, N> => {
298
+ const realBTNExemplars: BTNodePureExemplar<K, V, N>[] = [];
299
+
300
+ const isRealBTNExemplar = (kve: BTNodeExemplar<K, V, N>): kve is BTNodePureExemplar<K, V, N> => {
280
301
  if (kve === undefined || kve === null) return false;
281
302
  return !(this.isEntry(kve) && (kve[0] === undefined || kve[0] === null));
282
303
  }
@@ -285,24 +306,22 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
285
306
  isRealBTNExemplar(kve) && realBTNExemplars.push(kve);
286
307
  }
287
308
 
288
- // TODO this addMany function is inefficient, it should be optimized
289
- let sorted: BTNodePureExemplar<V, N>[] = [];
309
+ let sorted: BTNodePureExemplar<K, V, N>[] = [];
290
310
 
291
311
  sorted = realBTNExemplars.sort((a, b) => {
292
312
  let aR: number, bR: number;
293
- if (this.isEntry(a)) aR = a[0]
294
- else if (this.isRealNode(a)) aR = a.key
295
- else aR = a;
313
+ if (this.isEntry(a)) aR = this.extractor(a[0]);
314
+ else if (this.isRealNode(a)) aR = this.extractor(a.key);
315
+ else aR = this.extractor(a);
296
316
 
297
- if (this.isEntry(b)) bR = b[0]
298
- else if (this.isRealNode(b)) bR = b.key
299
- else bR = b;
317
+ if (this.isEntry(b)) bR = this.extractor(b[0]);
318
+ else if (this.isRealNode(b)) bR = this.extractor(b.key);
319
+ else bR = this.extractor(b);
300
320
 
301
321
  return aR - bR;
302
- })
303
-
322
+ });
304
323
 
305
- const _dfs = (arr: BTNodePureExemplar<V, N>[]) => {
324
+ const _dfs = (arr: BTNodePureExemplar<K, V, N>[]) => {
306
325
  if (arr.length === 0) return;
307
326
 
308
327
  const mid = Math.floor((arr.length - 1) / 2);
@@ -311,6 +330,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
311
330
  _dfs(arr.slice(0, mid));
312
331
  _dfs(arr.slice(mid + 1));
313
332
  };
333
+
314
334
  const _iterate = () => {
315
335
  const n = sorted.length;
316
336
  const stack: [[number, number]] = [[0, n - 1]];
@@ -328,6 +348,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
328
348
  }
329
349
  }
330
350
  };
351
+
331
352
  if (iterationType === IterationType.RECURSIVE) {
332
353
  _dfs(sorted);
333
354
  } else {
@@ -337,6 +358,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
337
358
  return inserted;
338
359
  }
339
360
 
361
+
340
362
  /**
341
363
  * Time Complexity: O(n log n) - Adding each element individually in a balanced tree.
342
364
  * Space Complexity: O(n) - Additional space is required for the sorted array.
@@ -348,8 +370,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
348
370
  *
349
371
  * The `lastKey` function returns the key of the rightmost node in a binary tree, or the key of the
350
372
  * leftmost node if the comparison result is greater than.
351
- * @param {BTNKey | N | undefined} beginRoot - The `beginRoot` parameter is optional and can be of
352
- * type `BTNKey`, `N`, or `undefined`. It represents the starting point for finding the last key in
373
+ * @param {K | N | undefined} beginRoot - The `beginRoot` parameter is optional and can be of
374
+ * type `K`, `N`, or `undefined`. It represents the starting point for finding the last key in
353
375
  * the binary tree. If not provided, it defaults to the root of the binary tree (`this.root`).
354
376
  * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
355
377
  * be performed. It can have one of the following values:
@@ -357,12 +379,25 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
357
379
  * the key of the leftmost node if the comparison result is greater than, and the key of the
358
380
  * rightmost node otherwise. If no node is found, it returns 0.
359
381
  */
360
- lastKey(beginRoot: BSTNodeKeyOrNode<N> = this.root, iterationType = this.iterationType): BTNKey {
361
- if (this._compare(0, 1) === CP.lt) return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
362
- else if (this._compare(0, 1) === CP.gt) return this.getLeftMost(beginRoot, iterationType)?.key ?? 0;
363
- else return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
382
+ lastKey(beginRoot: BSTNodeKeyOrNode<K, N> = this.root): K | undefined {
383
+ let current = this.ensureNode(beginRoot);
384
+ if (!current) return undefined;
385
+
386
+ if (this._variant === BSTVariant.MIN) {
387
+ // For BSTVariant.MIN, find the rightmost node
388
+ while (current.right !== undefined) {
389
+ current = current.right;
390
+ }
391
+ } else {
392
+ // For BSTVariant.MAX, find the leftmost node
393
+ while (current.left !== undefined) {
394
+ current = current.left;
395
+ }
396
+ }
397
+ return current.key;
364
398
  }
365
399
 
400
+
366
401
  /**
367
402
  * Time Complexity: O(log n) - Average case for a balanced tree.
368
403
  * Space Complexity: O(1) - Constant space is used.
@@ -374,7 +409,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
374
409
  *
375
410
  * The function `getNodeByKey` searches for a node in a binary tree based on a given key, using
376
411
  * either recursive or iterative methods.
377
- * @param {BTNKey} key - The `key` parameter is the key value that we are searching for in the tree.
412
+ * @param {K} key - The `key` parameter is the key value that we are searching for in the tree.
378
413
  * It is used to identify the node that we want to retrieve.
379
414
  * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
380
415
  * type of iteration to use when searching for a node in the binary tree. It can have two possible
@@ -382,7 +417,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
382
417
  * @returns The function `getNodeByKey` returns a node (`N`) if a node with the specified key is
383
418
  * found in the binary tree. If no node is found, it returns `undefined`.
384
419
  */
385
- override getNodeByKey(key: BTNKey, iterationType = IterationType.ITERATIVE): N | undefined {
420
+ override getNodeByKey(key: K, iterationType = IterationType.ITERATIVE): N | undefined {
386
421
  if (!this.root) return undefined;
387
422
  if (iterationType === IterationType.RECURSIVE) {
388
423
  const _dfs = (cur: N): N | undefined => {
@@ -407,6 +442,16 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
407
442
  }
408
443
  }
409
444
 
445
+ /**
446
+ * The function "isNotNodeInstance" checks if a potential key is a K.
447
+ * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any
448
+ * data type.
449
+ * @returns a boolean value indicating whether the potentialKey is of type number or not.
450
+ */
451
+ override isNotNodeInstance(potentialKey: BTNodeKeyOrNode<K, N>): potentialKey is K {
452
+ return !(potentialKey instanceof BSTNode)
453
+ }
454
+
410
455
  /**
411
456
  * Time Complexity: O(log n) - Average case for a balanced tree.
412
457
  * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
@@ -415,14 +460,14 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
415
460
  /**
416
461
  * The function `ensureNode` returns the node corresponding to the given key if it is a node key,
417
462
  * otherwise it returns the key itself.
418
- * @param {BTNKey | N | undefined} key - The `key` parameter can be of type `BTNKey`, `N`, or
463
+ * @param {K | N | undefined} key - The `key` parameter can be of type `K`, `N`, or
419
464
  * `undefined`.
420
465
  * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
421
466
  * type of iteration to be performed. It has a default value of `IterationType.ITERATIVE`.
422
467
  * @returns either a node object (N) or undefined.
423
468
  */
424
- override ensureNode(key: BSTNodeKeyOrNode<N>, iterationType = IterationType.ITERATIVE): N | undefined {
425
- return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key;
469
+ override ensureNode(key: BSTNodeKeyOrNode<K, N>, iterationType = IterationType.ITERATIVE): N | undefined {
470
+ return this.isNotNodeInstance(key) ? this.getNodeByKey(key, iterationType) : key;
426
471
  }
427
472
 
428
473
  /**
@@ -441,7 +486,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
441
486
  * first node that matches the identifier. If set to true, the function will return an array
442
487
  * containing only the first matching node. If set to false (default), the function will continue
443
488
  * searching for all nodes that match the identifier and return an array containing
444
- * @param {BTNKey | N | undefined} beginRoot - The `beginRoot` parameter represents the starting node
489
+ * @param {K | N | undefined} beginRoot - The `beginRoot` parameter represents the starting node
445
490
  * for the traversal. It can be either a key value or a node object. If it is undefined, the
446
491
  * traversal will start from the root of the tree.
447
492
  * @param iterationType - The `iterationType` parameter determines the type of iteration to be
@@ -452,7 +497,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
452
497
  identifier: ReturnType<C> | undefined,
453
498
  callback: C = this._defaultOneParamCallback as C,
454
499
  onlyOne = false,
455
- beginRoot: BSTNodeKeyOrNode<N> = this.root,
500
+ beginRoot: BSTNodeKeyOrNode<K, N> = this.root,
456
501
  iterationType = this.iterationType
457
502
  ): N[] {
458
503
  beginRoot = this.ensureNode(beginRoot);
@@ -470,8 +515,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
470
515
  if (!cur.left && !cur.right) return;
471
516
  // TODO potential bug
472
517
  if (callback === this._defaultOneParamCallback) {
473
- if (this._compare(cur.key, identifier as number) === CP.gt) cur.left && _traverse(cur.left);
474
- if (this._compare(cur.key, identifier as number) === CP.lt) cur.right && _traverse(cur.right);
518
+ if (this._compare(cur.key, identifier as K) === CP.gt) cur.left && _traverse(cur.left);
519
+ if (this._compare(cur.key, identifier as K) === CP.lt) cur.right && _traverse(cur.right);
475
520
  } else {
476
521
  cur.left && _traverse(cur.left);
477
522
  cur.right && _traverse(cur.right);
@@ -491,8 +536,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
491
536
  }
492
537
  // TODO potential bug
493
538
  if (callback === this._defaultOneParamCallback) {
494
- if (this._compare(cur.key, identifier as number) === CP.gt) cur.left && queue.push(cur.left);
495
- if (this._compare(cur.key, identifier as number) === CP.lt) cur.right && queue.push(cur.right);
539
+ if (this._compare(cur.key, identifier as K) === CP.gt) cur.left && queue.push(cur.left);
540
+ if (this._compare(cur.key, identifier as K) === CP.lt) cur.right && queue.push(cur.right);
496
541
  } else {
497
542
  cur.left && queue.push(cur.left);
498
543
  cur.right && queue.push(cur.right);
@@ -522,7 +567,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
522
567
  * traverse nodes that are lesser than, greater than, or equal to the `targetNode`. It is of type
523
568
  * `CP`, which is a custom type representing the comparison operator. The possible values for
524
569
  * `lesserOrGreater` are
525
- * @param {BTNKey | N | undefined} targetNode - The `targetNode` parameter represents the node in the
570
+ * @param {K | N | undefined} targetNode - The `targetNode` parameter represents the node in the
526
571
  * binary tree that you want to traverse from. It can be specified either by its key, by the node
527
572
  * object itself, or it can be left undefined to start the traversal from the root of the tree.
528
573
  * @param iterationType - The `iterationType` parameter determines the type of traversal to be
@@ -533,7 +578,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
533
578
  lesserOrGreaterTraverse<C extends BTNCallback<N>>(
534
579
  callback: C = this._defaultOneParamCallback as C,
535
580
  lesserOrGreater: CP = CP.lt,
536
- targetNode: BSTNodeKeyOrNode<N> = this.root,
581
+ targetNode: BSTNodeKeyOrNode<K, N> = this.root,
537
582
  iterationType = this.iterationType
538
583
  ): ReturnType<C>[] {
539
584
  targetNode = this.ensureNode(targetNode);
@@ -614,7 +659,6 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
614
659
  if (l <= r) {
615
660
  const m = l + Math.floor((r - l) / 2);
616
661
  const midNode = sorted[m];
617
- debugger;
618
662
  this.add([midNode.key, midNode.value]);
619
663
  stack.push([m + 1, r]);
620
664
  stack.push([l, m - 1]);
@@ -704,15 +748,17 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
704
748
  /**
705
749
  * The function compares two values using a comparator function and returns whether the first value
706
750
  * is greater than, less than, or equal to the second value.
707
- * @param {BTNKey} a - The parameter "a" is of type BTNKey.
708
- * @param {BTNKey} b - The parameter "b" in the above code represents a BTNKey.
751
+ * @param {K} a - The parameter "a" is of type K.
752
+ * @param {K} b - The parameter "b" in the above code represents a K.
709
753
  * @returns a value of type CP (ComparisonResult). The possible return values are CP.gt (greater
710
754
  * than), CP.lt (less than), or CP.eq (equal).
711
755
  */
712
- protected _compare(a: BTNKey, b: BTNKey): CP {
713
- const compared = this.comparator(a, b);
714
- if (compared > 0) return CP.gt;
715
- else if (compared < 0) return CP.lt;
716
- else return CP.eq;
756
+ protected _compare(a: K, b: K): CP {
757
+ const extractedA = this.extractor(a);
758
+ const extractedB = this.extractor(b);
759
+ const compared = this.variant === BSTVariant.MIN ? extractedA - extractedB : extractedB - extractedA;
760
+
761
+ return compared > 0 ? CP.gt : compared < 0 ? CP.lt : CP.eq;
717
762
  }
763
+
718
764
  }