priority-queue-typed 1.47.5 → 1.47.7

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 (71) hide show
  1. package/dist/data-structures/binary-tree/avl-tree.d.ts +36 -18
  2. package/dist/data-structures/binary-tree/avl-tree.js +46 -29
  3. package/dist/data-structures/binary-tree/binary-tree.d.ts +158 -129
  4. package/dist/data-structures/binary-tree/binary-tree.js +182 -184
  5. package/dist/data-structures/binary-tree/bst.d.ts +73 -63
  6. package/dist/data-structures/binary-tree/bst.js +168 -169
  7. package/dist/data-structures/binary-tree/rb-tree.d.ts +54 -17
  8. package/dist/data-structures/binary-tree/rb-tree.js +77 -31
  9. package/dist/data-structures/binary-tree/tree-multimap.d.ts +29 -40
  10. package/dist/data-structures/binary-tree/tree-multimap.js +66 -136
  11. package/dist/data-structures/graph/abstract-graph.js +1 -1
  12. package/dist/data-structures/hash/hash-map.d.ts +2 -6
  13. package/dist/data-structures/hash/hash-map.js +5 -8
  14. package/dist/data-structures/heap/heap.d.ts +19 -21
  15. package/dist/data-structures/heap/heap.js +52 -34
  16. package/dist/data-structures/heap/max-heap.d.ts +2 -5
  17. package/dist/data-structures/heap/max-heap.js +2 -2
  18. package/dist/data-structures/heap/min-heap.d.ts +2 -5
  19. package/dist/data-structures/heap/min-heap.js +2 -2
  20. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +2 -1
  21. package/dist/data-structures/linked-list/doubly-linked-list.js +9 -1
  22. package/dist/data-structures/linked-list/singly-linked-list.d.ts +2 -1
  23. package/dist/data-structures/linked-list/singly-linked-list.js +8 -1
  24. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +2 -5
  25. package/dist/data-structures/priority-queue/max-priority-queue.js +2 -2
  26. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +2 -5
  27. package/dist/data-structures/priority-queue/min-priority-queue.js +2 -2
  28. package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -5
  29. package/dist/data-structures/priority-queue/priority-queue.js +2 -2
  30. package/dist/data-structures/queue/deque.d.ts +1 -0
  31. package/dist/data-structures/queue/deque.js +3 -0
  32. package/dist/data-structures/queue/queue.d.ts +1 -0
  33. package/dist/data-structures/queue/queue.js +3 -0
  34. package/dist/data-structures/stack/stack.d.ts +2 -1
  35. package/dist/data-structures/stack/stack.js +10 -2
  36. package/dist/data-structures/trie/trie.d.ts +3 -0
  37. package/dist/data-structures/trie/trie.js +19 -4
  38. package/dist/interfaces/binary-tree.d.ts +4 -2
  39. package/dist/types/common.d.ts +7 -0
  40. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
  41. package/dist/types/data-structures/binary-tree/bst.d.ts +2 -2
  42. package/dist/types/data-structures/hash/hash-map.d.ts +1 -2
  43. package/dist/types/data-structures/heap/heap.d.ts +4 -1
  44. package/dist/types/data-structures/priority-queue/priority-queue.d.ts +2 -1
  45. package/package.json +2 -2
  46. package/src/data-structures/binary-tree/avl-tree.ts +61 -31
  47. package/src/data-structures/binary-tree/binary-tree.ts +283 -254
  48. package/src/data-structures/binary-tree/bst.ts +193 -170
  49. package/src/data-structures/binary-tree/rb-tree.ts +87 -32
  50. package/src/data-structures/binary-tree/tree-multimap.ts +76 -136
  51. package/src/data-structures/graph/abstract-graph.ts +1 -1
  52. package/src/data-structures/hash/hash-map.ts +8 -8
  53. package/src/data-structures/heap/heap.ts +57 -39
  54. package/src/data-structures/heap/max-heap.ts +5 -5
  55. package/src/data-structures/heap/min-heap.ts +5 -5
  56. package/src/data-structures/linked-list/doubly-linked-list.ts +10 -1
  57. package/src/data-structures/linked-list/singly-linked-list.ts +9 -1
  58. package/src/data-structures/priority-queue/max-priority-queue.ts +4 -3
  59. package/src/data-structures/priority-queue/min-priority-queue.ts +12 -12
  60. package/src/data-structures/priority-queue/priority-queue.ts +3 -3
  61. package/src/data-structures/queue/deque.ts +4 -0
  62. package/src/data-structures/queue/queue.ts +4 -0
  63. package/src/data-structures/stack/stack.ts +12 -3
  64. package/src/data-structures/trie/trie.ts +23 -4
  65. package/src/interfaces/binary-tree.ts +14 -2
  66. package/src/types/common.ts +15 -1
  67. package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
  68. package/src/types/data-structures/binary-tree/bst.ts +2 -3
  69. package/src/types/data-structures/hash/hash-map.ts +1 -2
  70. package/src/types/data-structures/heap/heap.ts +3 -1
  71. package/src/types/data-structures/priority-queue/priority-queue.ts +3 -1
@@ -5,7 +5,17 @@
5
5
  * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
6
6
  * @license MIT License
7
7
  */
8
- import type { BSTNested, BSTNodeNested, BSTOptions, BTNCallback, BTNKey } from '../../types';
8
+ import type {
9
+ BSTNested,
10
+ BSTNodeKeyOrNode,
11
+ BSTNodeNested,
12
+ BSTOptions,
13
+ BTNCallback,
14
+ BTNKey,
15
+ BTNodeExemplar,
16
+ BTNodePureExemplar,
17
+ Comparator
18
+ } from '../../types';
9
19
  import { CP, IterationType } from '../../types';
10
20
  import { BinaryTree, BinaryTreeNode } from './binary-tree';
11
21
  import { IBinaryTree } from '../../interfaces';
@@ -62,36 +72,51 @@ export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extend
62
72
  }
63
73
  }
64
74
 
75
+ /**
76
+ * 1. Node Order: Each node's left child has a lesser value, and the right child has a greater value.
77
+ * 2. Unique Keys: No duplicate keys in a standard BST.
78
+ * 3. Efficient Search: Enables quick search, minimum, and maximum operations.
79
+ * 4. Inorder Traversal: Yields nodes in ascending order.
80
+ * 5. Logarithmic Operations: Ideal operations like insertion, deletion, and searching are O(log n) time-efficient.
81
+ * 6. Balance Variability: Can become unbalanced; special types maintain balance.
82
+ * 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.
83
+ */
65
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>>>
66
85
  extends BinaryTree<V, N, TREE>
67
86
  implements IBinaryTree<V, N, TREE> {
68
87
 
69
- override options: BSTOptions;
70
88
 
71
89
  /**
72
- * The constructor function initializes a binary search tree with an optional comparator function.
73
- * @param {BSTOptions} [options] - An optional object that contains additional configuration options
74
- * for the binary search tree.
90
+ * This is the constructor function for a binary search tree class in TypeScript, which initializes
91
+ * the tree with optional elements and options.
92
+ * @param [elements] - An optional iterable of BTNodeExemplar objects that will be added to the
93
+ * binary search tree.
94
+ * @param [options] - The `options` parameter is an optional object that can contain additional
95
+ * configuration options for the binary search tree. It can have the following properties:
75
96
  */
76
- constructor(options?: BSTOptions) {
77
- super(options);
97
+ constructor(elements?: Iterable<BTNodeExemplar<V, N>>, options?: Partial<BSTOptions>) {
98
+ super([], options);
99
+
78
100
  if (options) {
79
- this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b, ...options }
80
- } else {
81
- this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b };
101
+ const { comparator } = options;
102
+ if (comparator) {
103
+ this.comparator = comparator;
104
+ }
82
105
  }
106
+
83
107
  this._root = undefined;
108
+
109
+ if (elements) this.addMany(elements);
84
110
  }
85
111
 
86
112
  protected override _root?: N;
87
113
 
88
- /**
89
- * Get the root node of the binary tree.
90
- */
91
114
  override get root(): N | undefined {
92
115
  return this._root;
93
116
  }
94
117
 
118
+ comparator: Comparator<BTNKey> = (a, b) => a - b
119
+
95
120
  /**
96
121
  * The function creates a new binary search tree node with the given key and value.
97
122
  * @param {BTNKey} key - The key parameter is the key value that will be associated with
@@ -104,8 +129,18 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
104
129
  return new BSTNode<V, N>(key, value) as N;
105
130
  }
106
131
 
107
- override createTree(options?: BSTOptions): TREE {
108
- return new BST<V, N, TREE>({ ...this.options, ...options }) as TREE;
132
+ /**
133
+ * The function creates a new binary search tree with the specified options.
134
+ * @param [options] - The `options` parameter is an optional object that allows you to customize the
135
+ * behavior of the `createTree` method. It accepts a partial `BSTOptions` object, which is a type
136
+ * that defines various options for creating a binary search tree.
137
+ * @returns a new instance of the BST class with the specified options.
138
+ */
139
+ override createTree(options?: Partial<BSTOptions>): TREE {
140
+ return new BST<V, N, TREE>([], {
141
+ iterationType: this.iterationType,
142
+ comparator: this.comparator, ...options
143
+ }) as TREE;
109
144
  }
110
145
 
111
146
  /**
@@ -117,158 +152,145 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
117
152
  * Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n).
118
153
  * Space Complexity: O(1) - Constant space is used.
119
154
  *
120
- * The `add` function adds a new node to a binary search tree based on the provided key and value.
121
- * @param {BTNKey | N | null | undefined} keyOrNode - The `keyOrNode` parameter can be one of the
122
- * following types:
123
- * @param {V} [value] - The `value` parameter is an optional value that can be associated with the
124
- * key or node being added to the binary search tree.
125
- * @returns The method `add` returns a node (`N`) that was inserted into the binary search tree. If
126
- * no node was inserted, it returns `undefined`.
155
+ * The `add` function adds a new node to a binary search tree, either by key or by providing a node
156
+ * object.
157
+ * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be one of the following:
158
+ * @returns The method returns either the newly added node (`newNode`) or `undefined` if the input
159
+ * (`keyOrNodeOrEntry`) is null, undefined, or does not match any of the expected types.
127
160
  */
128
- override add(keyOrNode: BTNKey | N | null | undefined, value?: V): N | undefined {
129
- if (keyOrNode === null) return undefined;
130
- // TODO support node as a parameter
131
- let inserted: N | undefined;
161
+ override add(keyOrNodeOrEntry: BTNodeExemplar<V, N>): N | undefined {
162
+ if (keyOrNodeOrEntry === null || keyOrNodeOrEntry === undefined) {
163
+ return undefined;
164
+ }
165
+
132
166
  let newNode: N | undefined;
133
- if (keyOrNode instanceof BSTNode) {
134
- newNode = keyOrNode;
135
- } else if (this.isNodeKey(keyOrNode)) {
136
- newNode = this.createNode(keyOrNode, value);
167
+ if (keyOrNodeOrEntry instanceof BSTNode) {
168
+ newNode = keyOrNodeOrEntry;
169
+ } else if (this.isNodeKey(keyOrNodeOrEntry)) {
170
+ newNode = this.createNode(keyOrNodeOrEntry);
171
+ } else if (this.isEntry(keyOrNodeOrEntry)) {
172
+ const [key, value] = keyOrNodeOrEntry;
173
+ if (key === undefined || key === null) {
174
+ return;
175
+ } else {
176
+ newNode = this.createNode(key, value);
177
+ }
137
178
  } else {
138
- newNode = undefined;
179
+ return;
139
180
  }
181
+
140
182
  if (this.root === undefined) {
141
183
  this._setRoot(newNode);
142
- this._size = this.size + 1;
143
- inserted = this.root;
144
- } else {
145
- let cur = this.root;
146
- let traversing = true;
147
- while (traversing) {
148
- if (cur !== undefined && newNode !== undefined) {
149
- if (this._compare(cur.key, newNode.key) === CP.eq) {
150
- if (newNode) {
151
- cur.value = newNode.value;
152
- }
153
- //Duplicates are not accepted.
154
- traversing = false;
155
- inserted = cur;
156
- } else if (this._compare(cur.key, newNode.key) === CP.gt) {
157
- // Traverse left of the node
158
- if (cur.left === undefined) {
159
- if (newNode) {
160
- newNode.parent = cur;
161
- }
162
- //Add to the left of the current node
163
- cur.left = newNode;
164
- this._size = this.size + 1;
165
- traversing = false;
166
- inserted = cur.left;
167
- } else {
168
- //Traverse the left of the current node
169
- if (cur.left) cur = cur.left;
170
- }
171
- } else if (this._compare(cur.key, newNode.key) === CP.lt) {
172
- // Traverse right of the node
173
- if (cur.right === undefined) {
174
- if (newNode) {
175
- newNode.parent = cur;
176
- }
177
- //Add to the right of the current node
178
- cur.right = newNode;
179
- this._size = this.size + 1;
180
- traversing = false;
181
- inserted = cur.right;
182
- } else {
183
- //Traverse the left of the current node
184
- if (cur.right) cur = cur.right;
185
- }
186
- }
187
- } else {
188
- traversing = false;
184
+ this._size++;
185
+ return this.root;
186
+ }
187
+
188
+ let current = this.root;
189
+ while (current !== undefined) {
190
+ if (this._compare(current.key, newNode.key) === CP.eq) {
191
+ // if (current !== newNode) {
192
+ // The key value is the same but the reference is different, update the value of the existing node
193
+ this._replaceNode(current, newNode);
194
+ return newNode;
195
+
196
+ // } else {
197
+ // The key value is the same and the reference is the same, replace the entire node
198
+ // this._replaceNode(current, newNode);
199
+
200
+ // return;
201
+ // }
202
+ } else if (this._compare(current.key, newNode.key) === CP.gt) {
203
+ if (current.left === undefined) {
204
+ current.left = newNode;
205
+ newNode.parent = current;
206
+ this._size++;
207
+ return newNode;
208
+ }
209
+ current = current.left;
210
+ } else {
211
+ if (current.right === undefined) {
212
+ current.right = newNode;
213
+ newNode.parent = current;
214
+ this._size++;
215
+ return newNode;
189
216
  }
217
+ current = current.right;
190
218
  }
191
219
  }
192
- return inserted;
220
+
221
+ return undefined;
193
222
  }
194
223
 
195
224
  /**
196
- * Time Complexity: O(n log n) - Adding each element individually in a balanced tree.
197
- * Space Complexity: O(n) - Additional space is required for the sorted array.
225
+ * Time Complexity: O(k log n) - Adding each element individually in a balanced tree.
226
+ * Space Complexity: O(k) - Additional space is required for the sorted array.
198
227
  */
199
228
 
200
229
  /**
201
- * Time Complexity: O(n log n) - Adding each element individually in a balanced tree.
202
- * Space Complexity: O(n) - Additional space is required for the sorted array.
230
+ * Time Complexity: O(k log n) - Adding each element individually in a balanced tree.
231
+ * Space Complexity: O(k) - Additional space is required for the sorted array.
203
232
  *
204
- * The `addMany` function is used to efficiently add multiple keys or nodes with corresponding data
205
- * to a binary search tree.
206
- * @param {(BTNKey | N | undefined)[]} keysOrNodes - An array of keys or nodes to be added to the
207
- * binary search tree. Each element can be of type `BTNKey` (binary tree node key), `N` (binary tree
208
- * node), or `undefined`.
209
- * @param {(V | undefined)[]} [data] - An optional array of values to associate with the keys or
210
- * nodes being added. If provided, the length of the `data` array must be the same as the length of
211
- * the `keysOrNodes` array.
233
+ * The `addMany` function in TypeScript adds multiple nodes to a binary tree, either in a balanced or
234
+ * unbalanced manner, and returns an array of the inserted nodes.
235
+ * @param keysOrNodesOrEntries - An iterable containing keys, nodes, or entries to be added to the
236
+ * binary tree.
212
237
  * @param [isBalanceAdd=true] - A boolean flag indicating whether the tree should be balanced after
213
- * adding the nodes. The default value is `true`.
238
+ * adding the nodes. The default value is true.
214
239
  * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
215
- * type of iteration to use when adding multiple keys or nodes to the binary search tree. It has a
216
- * default value of `this.iterationType`, which means it will use the iteration type specified in the
217
- * current instance of the binary search tree
218
- * @returns The function `addMany` returns an array of nodes (`N`) or `undefined` values.
240
+ * type of iteration to use when adding multiple keys or nodes to the binary tree. It has a default
241
+ * value of `this.iterationType`, which means it will use the iteration type specified by the binary
242
+ * tree instance.
243
+ * @returns The `addMany` function returns an array of `N` or `undefined` values.
219
244
  */
220
245
  override addMany(
221
- keysOrNodes: (BTNKey | N | undefined)[],
222
- data?: (V | undefined)[],
246
+ keysOrNodesOrEntries: Iterable<BTNodeExemplar<V, N>>,
223
247
  isBalanceAdd = true,
224
- iterationType = this.options.iterationType
248
+ iterationType = this.iterationType
225
249
  ): (N | undefined)[] {
226
- // TODO this addMany function is inefficient, it should be optimized
227
- function hasNoUndefined(arr: (BTNKey | N | undefined)[]): arr is (BTNKey | N)[] {
228
- return arr.indexOf(undefined) === -1;
250
+ const inserted: (N | undefined)[] = []
251
+ if (!isBalanceAdd) {
252
+ for (const kve of keysOrNodesOrEntries) {
253
+ const nn = this.add(kve)
254
+ inserted.push(nn);
255
+ }
256
+ return inserted;
229
257
  }
258
+ const realBTNExemplars: BTNodePureExemplar<V, N>[] = [];
230
259
 
231
- if (!isBalanceAdd || !hasNoUndefined(keysOrNodes)) {
232
- return super.addMany(keysOrNodes, data).map(n => n ?? undefined);
260
+ const isRealBTNExemplar = (kve: BTNodeExemplar<V, N>): kve is BTNodePureExemplar<V, N> => {
261
+ if (kve === undefined || kve === null) return false;
262
+ return !(this.isEntry(kve) && (kve[0] === undefined || kve[0] === null));
233
263
  }
234
264
 
235
- const inserted: (N | undefined)[] = [];
236
- const combinedArr: [BTNKey | N, V][] = keysOrNodes.map(
237
- (value: BTNKey | N, index) => [value, data?.[index]] as [BTNKey | N, V]
238
- );
265
+ for (const kve of keysOrNodesOrEntries) {
266
+ isRealBTNExemplar(kve) && realBTNExemplars.push(kve);
267
+ }
239
268
 
240
- let sorted = [];
269
+ // TODO this addMany function is inefficient, it should be optimized
270
+ let sorted: BTNodePureExemplar<V, N>[] = [];
241
271
 
242
- function _isNodeOrUndefinedTuple(arr: [BTNKey | N, V][]): arr is [N, V][] {
243
- for (const [keyOrNode] of arr) if (keyOrNode instanceof BSTNode) return true;
244
- return false;
245
- }
272
+ sorted = realBTNExemplars.sort((a, b) => {
273
+ let aR: number, bR: number;
274
+ if (this.isEntry(a)) aR = a[0]
275
+ else if (this.isRealNode(a)) aR = a.key
276
+ else aR = a;
246
277
 
247
- const _isBinaryTreeKeyOrNullTuple = (arr: [BTNKey | N, V][]): arr is [BTNKey, V][] => {
248
- for (const [keyOrNode] of arr) if (this.isNodeKey(keyOrNode)) return true;
249
- return false;
250
- };
278
+ if (this.isEntry(b)) bR = b[0]
279
+ else if (this.isRealNode(b)) bR = b.key
280
+ else bR = b;
251
281
 
252
- let sortedKeysOrNodes: (number | N | undefined)[] = [],
253
- sortedData: (V | undefined)[] | undefined = [];
282
+ return aR - bR;
283
+ })
254
284
 
255
- if (_isNodeOrUndefinedTuple(combinedArr)) {
256
- sorted = combinedArr.sort((a, b) => a[0].key - b[0].key);
257
- } else if (_isBinaryTreeKeyOrNullTuple(combinedArr)) {
258
- sorted = combinedArr.sort((a, b) => a[0] - b[0]);
259
- } else {
260
- throw new Error('Invalid input keysOrNodes');
261
- }
262
- sortedKeysOrNodes = sorted.map(([keyOrNode]) => keyOrNode);
263
- sortedData = sorted.map(([, value]) => value);
264
- const _dfs = (arr: (BTNKey | undefined | N)[], data?: (V | undefined)[]) => {
285
+
286
+ const _dfs = (arr: BTNodePureExemplar<V, N>[]) => {
265
287
  if (arr.length === 0) return;
266
288
 
267
289
  const mid = Math.floor((arr.length - 1) / 2);
268
- const newNode = this.add(arr[mid], data?.[mid]);
290
+ const newNode = this.add(arr[mid]);
269
291
  inserted.push(newNode);
270
- _dfs(arr.slice(0, mid), data?.slice(0, mid));
271
- _dfs(arr.slice(mid + 1), data?.slice(mid + 1));
292
+ _dfs(arr.slice(0, mid));
293
+ _dfs(arr.slice(mid + 1));
272
294
  };
273
295
  const _iterate = () => {
274
296
  const n = sorted.length;
@@ -279,7 +301,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
279
301
  const [l, r] = popped;
280
302
  if (l <= r) {
281
303
  const m = l + Math.floor((r - l) / 2);
282
- const newNode = this.add(sortedKeysOrNodes[m], sortedData?.[m]);
304
+ const newNode = this.add(sorted[m]);
283
305
  inserted.push(newNode);
284
306
  stack.push([m + 1, r]);
285
307
  stack.push([l, m - 1]);
@@ -288,7 +310,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
288
310
  }
289
311
  };
290
312
  if (iterationType === IterationType.RECURSIVE) {
291
- _dfs(sortedKeysOrNodes, sortedData);
313
+ _dfs(sorted);
292
314
  } else {
293
315
  _iterate();
294
316
  }
@@ -297,8 +319,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
297
319
  }
298
320
 
299
321
  /**
300
- * Time Complexity: O(log n) - Average case for a balanced tree.
301
- * Space Complexity: O(1) - Constant space is used.
322
+ * Time Complexity: O(n log n) - Adding each element individually in a balanced tree.
323
+ * Space Complexity: O(n) - Additional space is required for the sorted array.
302
324
  */
303
325
 
304
326
  /**
@@ -316,7 +338,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
316
338
  * the key of the leftmost node if the comparison result is greater than, and the key of the
317
339
  * rightmost node otherwise. If no node is found, it returns 0.
318
340
  */
319
- lastKey(beginRoot: BTNKey | N | undefined = this.root, iterationType = this.options.iterationType): BTNKey {
341
+ lastKey(beginRoot: BSTNodeKeyOrNode<N> = this.root, iterationType = this.iterationType): BTNKey {
320
342
  if (this._compare(0, 1) === CP.lt) return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
321
343
  else if (this._compare(0, 1) === CP.gt) return this.getLeftMost(beginRoot, iterationType)?.key ?? 0;
322
344
  else return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
@@ -324,7 +346,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
324
346
 
325
347
  /**
326
348
  * Time Complexity: O(log n) - Average case for a balanced tree.
327
- * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
349
+ * Space Complexity: O(1) - Constant space is used.
328
350
  */
329
351
 
330
352
  /**
@@ -367,7 +389,12 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
367
389
  }
368
390
 
369
391
  /**
370
- * The function `ensureNotKey` returns the node corresponding to the given key if it is a node key,
392
+ * Time Complexity: O(log n) - Average case for a balanced tree.
393
+ * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
394
+ */
395
+
396
+ /**
397
+ * The function `ensureNode` returns the node corresponding to the given key if it is a node key,
371
398
  * otherwise it returns the key itself.
372
399
  * @param {BTNKey | N | undefined} key - The `key` parameter can be of type `BTNKey`, `N`, or
373
400
  * `undefined`.
@@ -375,15 +402,10 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
375
402
  * type of iteration to be performed. It has a default value of `IterationType.ITERATIVE`.
376
403
  * @returns either a node object (N) or undefined.
377
404
  */
378
- override ensureNotKey(key: BTNKey | N | undefined, iterationType = IterationType.ITERATIVE): N | undefined {
405
+ override ensureNode(key: BSTNodeKeyOrNode<N>, iterationType = IterationType.ITERATIVE): N | undefined {
379
406
  return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key;
380
407
  }
381
408
 
382
- /**
383
- * Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key.
384
- * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
385
- */
386
-
387
409
  /**
388
410
  * Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key.
389
411
  * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
@@ -411,10 +433,10 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
411
433
  identifier: ReturnType<C> | undefined,
412
434
  callback: C = this._defaultOneParamCallback as C,
413
435
  onlyOne = false,
414
- beginRoot: BTNKey | N | undefined = this.root,
415
- iterationType = this.options.iterationType
436
+ beginRoot: BSTNodeKeyOrNode<N> = this.root,
437
+ iterationType = this.iterationType
416
438
  ): N[] {
417
- beginRoot = this.ensureNotKey(beginRoot);
439
+ beginRoot = this.ensureNode(beginRoot);
418
440
  if (!beginRoot) return [];
419
441
  const ans: N[] = [];
420
442
 
@@ -492,10 +514,10 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
492
514
  lesserOrGreaterTraverse<C extends BTNCallback<N>>(
493
515
  callback: C = this._defaultOneParamCallback as C,
494
516
  lesserOrGreater: CP = CP.lt,
495
- targetNode: BTNKey | N | undefined = this.root,
496
- iterationType = this.options.iterationType
517
+ targetNode: BSTNodeKeyOrNode<N> = this.root,
518
+ iterationType = this.iterationType
497
519
  ): ReturnType<C>[] {
498
- targetNode = this.ensureNotKey(targetNode);
520
+ targetNode = this.ensureNode(targetNode);
499
521
  const ans: ReturnType<BTNCallback<N>>[] = [];
500
522
  if (!targetNode) return ans;
501
523
  if (!this.root) return ans;
@@ -531,18 +553,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
531
553
  }
532
554
 
533
555
  /**
534
- * Balancing Adjustment:
535
- * 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.
536
- * 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.
537
- *
538
- * Use Cases and Efficiency:
539
- * 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.
540
- * 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).
541
- */
542
-
543
- /**
544
- * Time Complexity: O(n) - Building a balanced tree from a sorted array.
545
- * Space Complexity: O(n) - Additional space is required for the sorted array.
556
+ * Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key.
557
+ * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
546
558
  */
547
559
 
548
560
  /**
@@ -556,7 +568,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
556
568
  * values:
557
569
  * @returns The function `perfectlyBalance` returns a boolean value.
558
570
  */
559
- perfectlyBalance(iterationType = this.options.iterationType): boolean {
571
+ perfectlyBalance(iterationType = this.iterationType): boolean {
560
572
  const sorted = this.dfs(node => node, 'in'),
561
573
  n = sorted.length;
562
574
  this.clear();
@@ -567,7 +579,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
567
579
  if (l > r) return;
568
580
  const m = l + Math.floor((r - l) / 2);
569
581
  const midNode = sorted[m];
570
- this.add(midNode.key, midNode.value);
582
+ this.add([midNode.key, midNode.value]);
571
583
  buildBalanceBST(l, m - 1);
572
584
  buildBalanceBST(m + 1, r);
573
585
  };
@@ -584,7 +596,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
584
596
  const m = l + Math.floor((r - l) / 2);
585
597
  const midNode = sorted[m];
586
598
  debugger;
587
- this.add(midNode.key, midNode.value);
599
+ this.add([midNode.key, midNode.value]);
588
600
  stack.push([m + 1, r]);
589
601
  stack.push([l, m - 1]);
590
602
  }
@@ -595,8 +607,18 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
595
607
  }
596
608
 
597
609
  /**
598
- * Time Complexity: O(n) - Visiting each node once.
599
- * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
610
+ * Balancing Adjustment:
611
+ * 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.
612
+ * 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.
613
+ *
614
+ * Use Cases and Efficiency:
615
+ * 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.
616
+ * 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).
617
+ */
618
+
619
+ /**
620
+ * Time Complexity: O(n) - Building a balanced tree from a sorted array.
621
+ * Space Complexity: O(n) - Additional space is required for the sorted array.
600
622
  */
601
623
 
602
624
  /**
@@ -608,7 +630,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
608
630
  * to check if the AVL tree is balanced. It can have two possible values:
609
631
  * @returns a boolean value.
610
632
  */
611
- isAVLBalanced(iterationType = this.options.iterationType): boolean {
633
+ isAVLBalanced(iterationType = this.iterationType): boolean {
612
634
  if (!this.root) return true;
613
635
 
614
636
  let balanced = true;
@@ -652,6 +674,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
652
674
  return balanced;
653
675
  }
654
676
 
677
+
655
678
  protected _setRoot(v: N | undefined) {
656
679
  if (v) {
657
680
  v.parent = undefined;
@@ -668,7 +691,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
668
691
  * than), CP.lt (less than), or CP.eq (equal).
669
692
  */
670
693
  protected _compare(a: BTNKey, b: BTNKey): CP {
671
- const compared = this.options.comparator!(a, b);
694
+ const compared = this.comparator(a, b);
672
695
  if (compared > 0) return CP.gt;
673
696
  else if (compared < 0) return CP.lt;
674
697
  else return CP.eq;