bst-typed 1.51.5 → 1.51.8

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 (42) hide show
  1. package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +3 -12
  2. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +2 -10
  3. package/dist/data-structures/binary-tree/avl-tree.d.ts +3 -3
  4. package/dist/data-structures/binary-tree/avl-tree.js +12 -14
  5. package/dist/data-structures/binary-tree/binary-tree.d.ts +7 -13
  6. package/dist/data-structures/binary-tree/binary-tree.js +46 -78
  7. package/dist/data-structures/binary-tree/bst.d.ts +51 -96
  8. package/dist/data-structures/binary-tree/bst.js +120 -218
  9. package/dist/data-structures/binary-tree/rb-tree.d.ts +3 -4
  10. package/dist/data-structures/binary-tree/rb-tree.js +4 -2
  11. package/dist/data-structures/binary-tree/tree-multi-map.d.ts +3 -4
  12. package/dist/data-structures/binary-tree/tree-multi-map.js +1 -0
  13. package/dist/data-structures/heap/heap.d.ts +1 -3
  14. package/dist/interfaces/binary-tree.d.ts +3 -3
  15. package/dist/types/common.d.ts +1 -1
  16. package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +3 -2
  17. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +3 -2
  18. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +4 -4
  19. package/dist/types/data-structures/binary-tree/bst.d.ts +6 -5
  20. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +4 -3
  21. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +3 -2
  22. package/dist/types/utils/utils.d.ts +10 -1
  23. package/dist/utils/utils.d.ts +2 -1
  24. package/dist/utils/utils.js +29 -1
  25. package/package.json +2 -2
  26. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +5 -12
  27. package/src/data-structures/binary-tree/avl-tree.ts +15 -15
  28. package/src/data-structures/binary-tree/binary-tree.ts +56 -76
  29. package/src/data-structures/binary-tree/bst.ts +132 -224
  30. package/src/data-structures/binary-tree/rb-tree.ts +9 -6
  31. package/src/data-structures/binary-tree/tree-multi-map.ts +5 -3
  32. package/src/data-structures/heap/heap.ts +1 -1
  33. package/src/interfaces/binary-tree.ts +4 -3
  34. package/src/types/common.ts +1 -1
  35. package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +3 -2
  36. package/src/types/data-structures/binary-tree/avl-tree.ts +3 -2
  37. package/src/types/data-structures/binary-tree/binary-tree.ts +5 -5
  38. package/src/types/data-structures/binary-tree/bst.ts +6 -5
  39. package/src/types/data-structures/binary-tree/rb-tree.ts +4 -3
  40. package/src/types/data-structures/binary-tree/tree-multi-map.ts +3 -2
  41. package/src/types/utils/utils.ts +14 -1
  42. package/src/utils/utils.ts +20 -1
@@ -7,22 +7,27 @@
7
7
  */
8
8
  import type {
9
9
  BSTNested,
10
+ BSTNKeyOrNode,
10
11
  BSTNodeNested,
11
12
  BSTOptions,
12
13
  BTNCallback,
13
14
  BTNodePureExemplar,
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';
17
22
  import { BinaryTree, BinaryTreeNode } from './binary-tree';
18
23
  import { IBinaryTree } from '../../interfaces';
19
24
  import { Queue } from '../queue';
20
25
 
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
- > {
26
+ export class BSTNode<
27
+ K extends Comparable,
28
+ V = any,
29
+ NODE extends BSTNode<K, V, NODE> = BSTNodeNested<K, V>
30
+ > extends BinaryTreeNode<K, V, NODE> {
26
31
  override parent?: NODE;
27
32
 
28
33
  constructor(key: K, value?: V) {
@@ -88,7 +93,7 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
88
93
  * 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.
89
94
  */
90
95
  export class BST<
91
- K = any,
96
+ K extends Comparable,
92
97
  V = any,
93
98
  NODE extends BSTNode<K, V, NODE> = BSTNode<K, V, BSTNodeNested<K, V>>,
94
99
  TREE extends BST<K, V, NODE, TREE> = BST<K, V, NODE, BSTNested<K, V, NODE>>
@@ -96,10 +101,11 @@ export class BST<
96
101
  extends BinaryTree<K, V, NODE, TREE>
97
102
  implements IBinaryTree<K, V, NODE, TREE> {
98
103
  /**
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.
104
+ * This is the constructor function for a Binary Search Tree class in TypeScript, which initializes
105
+ * the tree with keys, nodes, or entries and optional options.
106
+ * @param keysOrNodesOrEntries - The `keysOrNodesOrEntries` parameter is an iterable object that can
107
+ * contain keys, nodes, or entries. It is used to initialize the binary search tree with the provided
108
+ * keys, nodes, or entries.
103
109
  * @param [options] - The `options` parameter is an optional object that can contain additional
104
110
  * configuration options for the binary search tree. It can have the following properties:
105
111
  */
@@ -107,16 +113,14 @@ export class BST<
107
113
  super([], options);
108
114
 
109
115
  if (options) {
110
- const { variant } = options;
111
- if (variant) this._variant = variant;
116
+ const { comparator } = options;
117
+ if (comparator) this._comparator = comparator;
112
118
  }
113
119
 
114
- this._root = undefined;
115
-
116
120
  if (keysOrNodesOrEntries) this.addMany(keysOrNodesOrEntries);
117
121
  }
118
122
 
119
- protected override _root?: NODE;
123
+ protected override _root?: NODE = undefined;
120
124
 
121
125
  /**
122
126
  * The function returns the root node of a tree structure.
@@ -126,14 +130,18 @@ export class BST<
126
130
  return this._root;
127
131
  }
128
132
 
129
- protected _variant: BSTVariant = 'STANDARD';
133
+ protected _comparator: Comparator<K> = (a: K, b: K): CP => {
134
+ if (a > b) return 1;
135
+ if (a < b) return -1;
136
+ return 0;
137
+ };
130
138
 
131
139
  /**
132
- * The function returns the value of the _variant property.
133
- * @returns The value of the `_variant` property.
140
+ * The function returns the value of the _comparator property.
141
+ * @returns The `_comparator` property is being returned.
134
142
  */
135
- get variant() {
136
- return this._variant;
143
+ get comparator() {
144
+ return this._comparator;
137
145
  }
138
146
 
139
147
  /**
@@ -159,7 +167,7 @@ export class BST<
159
167
  override createTree(options?: Partial<BSTOptions<K>>): TREE {
160
168
  return new BST<K, V, NODE, TREE>([], {
161
169
  iterationType: this.iterationType,
162
- variant: this.variant,
170
+ comparator: this.comparator,
163
171
  ...options
164
172
  }) as TREE;
165
173
  }
@@ -214,15 +222,20 @@ export class BST<
214
222
  keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>,
215
223
  iterationType: IterationType = 'ITERATIVE'
216
224
  ): NODE | undefined {
225
+ if (keyOrNodeOrEntry === this.NIL) return;
217
226
  if (this.isRealNode(keyOrNodeOrEntry)) {
218
227
  return keyOrNodeOrEntry;
219
- } else if (this.isEntry(keyOrNodeOrEntry)) {
220
- if (keyOrNodeOrEntry[0] === null || keyOrNodeOrEntry[0] === undefined) return;
221
- return this.getNodeByKey(keyOrNodeOrEntry[0], iterationType);
222
- } else {
223
- if (keyOrNodeOrEntry === null || keyOrNodeOrEntry === undefined) return;
224
- return this.getNodeByKey(keyOrNodeOrEntry, iterationType);
225
228
  }
229
+
230
+ if (this.isEntry(keyOrNodeOrEntry)) {
231
+ const key = keyOrNodeOrEntry[0];
232
+ if (key === null || key === undefined) return;
233
+ return this.getNodeByKey(key, iterationType);
234
+ }
235
+
236
+ const key = keyOrNodeOrEntry;
237
+ if (key === null || key === undefined) return;
238
+ return this.getNodeByKey(key, iterationType);
226
239
  }
227
240
 
228
241
  /**
@@ -243,13 +256,11 @@ export class BST<
243
256
  * Time Complexity: O(log n)
244
257
  * Space Complexity: O(1)
245
258
  *
246
- * The `add` function adds a new node to a binary tree, updating the value if the key already exists
247
- * or inserting a new node if the key is unique.
248
- * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can accept three types of values:
249
- * @param {V} [value] - The `value` parameter represents the value associated with the key that is
250
- * being added to the binary tree.
251
- * @returns The method `add` returns either the newly added node (`newNode`) or `undefined` if the
252
- * node was not added.
259
+ * The `add` function in TypeScript adds a new node to a binary search tree based on the key value,
260
+ * updating the value if the key already exists.
261
+ * @param keyOrNodeOrEntry - It is a parameter that can accept three types of values:
262
+ * @param {V} [value] - The value to be added to the binary search tree.
263
+ * @returns The method returns a boolean value.
253
264
  */
254
265
  override add(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>, value?: V): boolean {
255
266
  const newNode = this.keyValueOrEntryToNode(keyOrNodeOrEntry, value);
@@ -263,7 +274,7 @@ export class BST<
263
274
 
264
275
  let current = this.root;
265
276
  while (current !== undefined) {
266
- if (this._compare(current.key, newNode.key) === 'EQ') {
277
+ if (this.comparator(current.key, newNode.key) === 0) {
267
278
  // if (current !== newNode) {
268
279
  // The key value is the same but the reference is different, update the value of the existing node
269
280
  this._replaceNode(current, newNode);
@@ -275,7 +286,7 @@ export class BST<
275
286
 
276
287
  // return;
277
288
  // }
278
- } else if (this._compare(current.key, newNode.key) === 'GT') {
289
+ } else if (this.comparator(current.key, newNode.key) > 0) {
279
290
  if (current.left === undefined) {
280
291
  current.left = newNode;
281
292
  this._size++;
@@ -304,21 +315,24 @@ export class BST<
304
315
  * Time Complexity: O(k log n)
305
316
  * Space Complexity: O(k + log n)
306
317
  *
307
- * The `addMany` function in TypeScript adds multiple keys or nodes to a binary tree, optionally
308
- * balancing the tree after each addition.
309
- * @param keysOrNodesOrEntries - An iterable containing the keys, nodes, or entries to be added to
310
- * the binary tree.
318
+ * The `addMany` function in TypeScript adds multiple keys or nodes to a data structure, balancing
319
+ * the structure if specified, and returns an array indicating whether each key or node was
320
+ * successfully inserted.
321
+ * @param keysOrNodesOrEntries - An iterable containing keys, nodes, or entries to be added to the
322
+ * data structure.
311
323
  * @param [values] - An optional iterable of values to be associated with the keys or nodes being
312
324
  * added. If provided, the values will be assigned to the corresponding keys or nodes in the same
313
325
  * order. If not provided, undefined will be assigned as the value for each key or node.
314
- * @param [isBalanceAdd=true] - A boolean flag indicating whether the add operation should be
315
- * balanced or not. If set to true, the add operation will be balanced using a binary search tree
316
- * algorithm. If set to false, the add operation will not be balanced and the nodes will be added
317
- * in the order they appear in the input.
318
- * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
319
- * type of iteration to use when adding multiple keys or nodes. It has a default value of
320
- * `this.iterationType`, which suggests that it is a property of the current object.
321
- * @returns The function `addMany` returns an array of nodes (`NODE`) or `undefined` values.
326
+ * @param [isBalanceAdd=true] - A boolean flag indicating whether the tree should be balanced after
327
+ * adding the elements. If set to true, the tree will be balanced using a binary search tree
328
+ * algorithm. If set to false, the elements will be added without balancing the tree. The default
329
+ * value is true.
330
+ * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that
331
+ * specifies the type of iteration to use when adding multiple keys or nodes to the binary tree. It
332
+ * has a default value of `this.iterationType`, which means it will use the iteration type specified
333
+ * in the binary tree instance.
334
+ * @returns The function `addMany` returns an array of booleans indicating whether each key or node
335
+ * or entry was successfully inserted into the data structure.
322
336
  */
323
337
  override addMany(
324
338
  keysOrNodesOrEntries: Iterable<KeyOrNodeOrEntry<K, V, NODE>>,
@@ -357,16 +371,20 @@ export class BST<
357
371
  let sorted: BTNodePureExemplar<K, V, NODE>[] = [];
358
372
 
359
373
  sorted = realBTNExemplars.sort((a, b) => {
360
- let aR: number, bR: number;
361
- if (this.isEntry(a)) aR = this.extractor(a[0]);
362
- else if (this.isRealNode(a)) aR = this.extractor(a.key);
363
- else aR = this.extractor(a);
364
-
365
- if (this.isEntry(b)) bR = this.extractor(b[0]);
366
- else if (this.isRealNode(b)) bR = this.extractor(b.key);
367
- else bR = this.extractor(b);
368
-
369
- return aR - bR;
374
+ let keyA: K | undefined | null, keyB: K | undefined | null;
375
+ if (this.isEntry(a)) {
376
+ keyA = a[0];
377
+ } else if (this.isRealNode(a)) keyA = a.key;
378
+ else keyA = a;
379
+
380
+ if (this.isEntry(b)) keyB = b[0];
381
+ else if (this.isRealNode(b)) keyB = b.key;
382
+ else keyB = b;
383
+
384
+ if (keyA !== undefined && keyA !== null && keyB !== undefined && keyB !== null) {
385
+ return this.comparator(keyA, keyB);
386
+ }
387
+ return 0;
370
388
  });
371
389
 
372
390
  const _dfs = (arr: BTNodePureExemplar<K, V, NODE>[]) => {
@@ -406,51 +424,6 @@ export class BST<
406
424
  return inserted;
407
425
  }
408
426
 
409
- /**
410
- * Time Complexity: O(log n)
411
- * Space Complexity: O(1)
412
- */
413
-
414
- /**
415
- * Time Complexity: O(log n)
416
- * Space Complexity: O(1)
417
- *
418
- * The function `getNodeByKey` searches for a node in a binary tree based on a given key, using
419
- * either recursive or iterative methods.
420
- * @param {K} key - The `key` parameter is the key value that we are searching for in the tree.
421
- * It is used to identify the node that we want to retrieve.
422
- * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
423
- * type of iteration to use when searching for a node in the binary tree. It can have two possible
424
- * values:
425
- * @returns The function `getNodeByKey` returns a node (`NODE`) if a node with the specified key is
426
- * found in the binary tree. If no node is found, it returns `undefined`.
427
- */
428
- override getNodeByKey(key: K, iterationType: IterationType = 'ITERATIVE'): NODE | undefined {
429
- // return this.getNodes(key, this._DEFAULT_CALLBACK, true, this.root, iterationType)[0];
430
- if (!this.isRealNode(this.root)) return;
431
- if (iterationType === 'RECURSIVE') {
432
- const dfs = (cur: NODE): NODE | undefined => {
433
- if (cur.key === key) return cur;
434
- if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
435
-
436
- if (this.isRealNode(cur.left) && this._compare(cur.key, key) === 'GT') return dfs(cur.left);
437
- if (this.isRealNode(cur.right) && this._compare(cur.key, key) === 'LT') return dfs(cur.right);
438
- };
439
-
440
- return dfs(this.root);
441
- } else {
442
- const stack = [this.root];
443
- while (stack.length > 0) {
444
- const cur = stack.pop();
445
- if (this.isRealNode(cur)) {
446
- if (this._compare(cur.key, key) === 'EQ') return cur;
447
- if (this.isRealNode(cur.left) && this._compare(cur.key, key) === 'GT') stack.push(cur.left);
448
- if (this.isRealNode(cur.right) && this._compare(cur.key, key) === 'LT') stack.push(cur.right);
449
- }
450
- }
451
- }
452
- }
453
-
454
427
  /**
455
428
  * Time Complexity: O(log n)
456
429
  * Space Complexity: O(k + log n)
@@ -488,6 +461,7 @@ export class BST<
488
461
  ): NODE[] {
489
462
  beginRoot = this.ensureNode(beginRoot);
490
463
  if (!beginRoot) return [];
464
+ callback = this._ensureCallback(identifier, callback);
491
465
  const ans: NODE[] = [];
492
466
 
493
467
  if (iterationType === 'RECURSIVE') {
@@ -501,8 +475,8 @@ export class BST<
501
475
  if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
502
476
  // TODO potential bug
503
477
  if (callback === this._DEFAULT_CALLBACK) {
504
- if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') dfs(cur.left);
505
- if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') dfs(cur.right);
478
+ if (this.isRealNode(cur.left) && this.comparator(cur.key, identifier as K) > 0) dfs(cur.left);
479
+ if (this.isRealNode(cur.right) && this.comparator(cur.key, identifier as K) < 0) dfs(cur.right);
506
480
  } else {
507
481
  this.isRealNode(cur.left) && dfs(cur.left);
508
482
  this.isRealNode(cur.right) && dfs(cur.right);
@@ -513,29 +487,27 @@ export class BST<
513
487
  } else {
514
488
  const stack = [beginRoot];
515
489
  while (stack.length > 0) {
516
- const cur = stack.pop();
517
- if (this.isRealNode(cur)) {
518
- const callbackResult = callback(cur);
519
- if (callbackResult === identifier) {
520
- ans.push(cur);
521
- if (onlyOne) return ans;
522
- }
523
- // TODO potential bug
524
- if (callback === this._DEFAULT_CALLBACK) {
525
- if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') stack.push(cur.right);
526
- if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') stack.push(cur.left);
527
-
528
- // if (this.isRealNode(cur.right) && this._lt(cur.key, identifier as K)) stack.push(cur.right);
529
- // if (this.isRealNode(cur.left) && this._gt(cur.key, identifier as K)) stack.push(cur.left);
530
-
531
- // // @ts-ignore
532
- // if (this.isRealNode(cur.right) && cur.key > identifier) stack.push(cur.right);
533
- // // @ts-ignore
534
- // if (this.isRealNode(cur.left) && cur.key < identifier) stack.push(cur.left);
535
- } else {
536
- this.isRealNode(cur.right) && stack.push(cur.right);
537
- this.isRealNode(cur.left) && stack.push(cur.left);
538
- }
490
+ const cur = stack.pop()!;
491
+ const callbackResult = callback(cur);
492
+ if (callbackResult === identifier) {
493
+ ans.push(cur);
494
+ if (onlyOne) return ans;
495
+ }
496
+ // TODO potential bug
497
+ if (callback === this._DEFAULT_CALLBACK) {
498
+ if (this.isRealNode(cur.right) && this.comparator(cur.key, identifier as K) < 0) stack.push(cur.right);
499
+ if (this.isRealNode(cur.left) && this.comparator(cur.key, identifier as K) > 0) stack.push(cur.left);
500
+
501
+ // if (this.isRealNode(cur.right) && this._lt(cur.key, identifier as K)) stack.push(cur.right);
502
+ // if (this.isRealNode(cur.left) && this._gt(cur.key, identifier as K)) stack.push(cur.left);
503
+
504
+ // // @ts-ignore
505
+ // if (this.isRealNode(cur.right) && cur.key > identifier) stack.push(cur.right);
506
+ // // @ts-ignore
507
+ // if (this.isRealNode(cur.left) && cur.key < identifier) stack.push(cur.left);
508
+ } else {
509
+ this.isRealNode(cur.right) && stack.push(cur.right);
510
+ this.isRealNode(cur.left) && stack.push(cur.left);
539
511
  }
540
512
  }
541
513
  }
@@ -578,6 +550,29 @@ export class BST<
578
550
  return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined;
579
551
  }
580
552
 
553
+ /**
554
+ * Time Complexity: O(log n)
555
+ * Space Complexity: O(1)
556
+ */
557
+
558
+ /**
559
+ * Time Complexity: O(log n)
560
+ * Space Complexity: O(1)
561
+ *
562
+ * The function `getNodeByKey` searches for a node in a binary tree based on a given key, using
563
+ * either recursive or iterative methods.
564
+ * @param {K} key - The `key` parameter is the key value that we are searching for in the tree.
565
+ * It is used to identify the node that we want to retrieve.
566
+ * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
567
+ * type of iteration to use when searching for a node in the binary tree. It can have two possible
568
+ * values:
569
+ * @returns The function `getNodeByKey` returns a node (`NODE`) if a node with the specified key is
570
+ * found in the binary tree. If no node is found, it returns `undefined`.
571
+ */
572
+ override getNodeByKey(key: K, iterationType: IterationType = 'ITERATIVE'): NODE | undefined {
573
+ return this.getNode(key, this._DEFAULT_CALLBACK, this.root, iterationType);
574
+ }
575
+
581
576
  /**
582
577
  * Time complexity: O(n)
583
578
  * Space complexity: O(n)
@@ -672,42 +667,6 @@ export class BST<
672
667
  return super.listLevels(callback, beginRoot, iterationType, false);
673
668
  }
674
669
 
675
- /**
676
- * Time Complexity: O(log n)
677
- * Space Complexity: O(1)
678
- */
679
-
680
- /**
681
- * Time Complexity: O(log n)
682
- * Space Complexity: O(1)
683
- *
684
- * The `lastKey` function returns the key of the rightmost node in a binary tree, or the key of the
685
- * leftmost node if the comparison result is greater than.
686
- * @param {K | NODE | undefined} beginRoot - The `beginRoot` parameter is optional and can be of
687
- * type `K`, `NODE`, or `undefined`. It represents the starting point for finding the last key in
688
- * the binary tree. If not provided, it defaults to the root of the binary tree (`this.root`).
689
- * @returns the key of the rightmost node in the binary tree if the comparison result is less than,
690
- * the key of the leftmost node if the comparison result is greater than, and the key of the
691
- * rightmost node otherwise. If no node is found, it returns 0.
692
- */
693
- lastKey(beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root): K | undefined {
694
- let current = this.ensureNode(beginRoot);
695
- if (!current) return undefined;
696
-
697
- if (this._variant === 'STANDARD') {
698
- // For 'STANDARD', find the rightmost node
699
- while (current.right !== undefined) {
700
- current = current.right;
701
- }
702
- } else {
703
- // For BSTVariant.MAX, find the leftmost node
704
- while (current.left !== undefined) {
705
- current = current.left;
706
- }
707
- }
708
- return current.key;
709
- }
710
-
711
670
  /**
712
671
  * Time Complexity: O(log n)
713
672
  * Space Complexity: O(log n)
@@ -736,21 +695,21 @@ export class BST<
736
695
  */
737
696
  lesserOrGreaterTraverse<C extends BTNCallback<NODE>>(
738
697
  callback: C = this._DEFAULT_CALLBACK as C,
739
- lesserOrGreater: CP = 'LT',
698
+ lesserOrGreater: CP = -1,
740
699
  targetNode: KeyOrNodeOrEntry<K, V, NODE> = this.root,
741
700
  iterationType: IterationType = this.iterationType
742
701
  ): ReturnType<C>[] {
743
- targetNode = this.ensureNode(targetNode);
702
+ const targetNodeEnsured = this.ensureNode(targetNode);
744
703
  const ans: ReturnType<BTNCallback<NODE>>[] = [];
745
- if (!targetNode) return ans;
704
+ if (!targetNodeEnsured) return ans;
746
705
  if (!this.root) return ans;
747
706
 
748
- const targetKey = targetNode.key;
707
+ const targetKey = targetNodeEnsured.key;
749
708
 
750
709
  if (iterationType === 'RECURSIVE') {
751
710
  const dfs = (cur: NODE) => {
752
- const compared = this._compare(cur.key, targetKey);
753
- if (compared === lesserOrGreater) ans.push(callback(cur));
711
+ const compared = this.comparator(cur.key, targetKey);
712
+ if (Math.sign(compared) === lesserOrGreater) ans.push(callback(cur));
754
713
 
755
714
  if (this.isRealNode(cur.left)) dfs(cur.left);
756
715
  if (this.isRealNode(cur.right)) dfs(cur.right);
@@ -763,8 +722,8 @@ export class BST<
763
722
  while (queue.size > 0) {
764
723
  const cur = queue.shift();
765
724
  if (this.isRealNode(cur)) {
766
- const compared = this._compare(cur.key, targetKey);
767
- if (compared === lesserOrGreater) ans.push(callback(cur));
725
+ const compared = this.comparator(cur.key, targetKey);
726
+ if (Math.sign(compared) === lesserOrGreater) ans.push(callback(cur));
768
727
 
769
728
  if (this.isRealNode(cur.left)) queue.push(cur.left);
770
729
  if (this.isRealNode(cur.right)) queue.push(cur.right);
@@ -906,55 +865,4 @@ export class BST<
906
865
  }
907
866
  this._root = v;
908
867
  }
909
-
910
- /**
911
- * The function compares two values using a comparator function and returns whether the first value
912
- * is greater than, less than, or equal to the second value.
913
- * @param {K} a - The parameter "a" is of type K.
914
- * @param {K} b - The parameter "b" in the above code represents a K.
915
- * @returns a value of type CP (ComparisonResult). The possible return values are 'GT' (greater
916
- * than), 'LT' (less than), or 'EQ' (equal).
917
- */
918
- protected _compare(a: K, b: K): CP {
919
- const extractedA = this.extractor(a);
920
- const extractedB = this.extractor(b);
921
- const compared = this.variant === 'STANDARD' ? extractedA - extractedB : extractedB - extractedA;
922
-
923
- return compared > 0 ? 'GT' : compared < 0 ? 'LT' : 'EQ';
924
- }
925
-
926
- /**
927
- * The function `_lt` compares two values `a` and `b` using an extractor function and returns true if
928
- * `a` is less than `b` based on the specified variant.
929
- * @param {K} a - The parameter "a" is of type "K", which means it can be any type. It represents the
930
- * first value to be compared in the function.
931
- * @param {K} b - The parameter `b` is of type `K`, which means it can be any type. It is used as one
932
- * of the arguments for the comparison in the `_lt` function.
933
- * @returns a boolean value.
934
- */
935
- protected _lt(a: K, b: K): boolean {
936
- const extractedA = this.extractor(a);
937
- const extractedB = this.extractor(b);
938
- // return this.variant === BSTVariant.STANDARD ? extractedA < extractedB : extractedA > extractedB;
939
- return this.variant === 'STANDARD' ? extractedA < extractedB : extractedA > extractedB;
940
- // return extractedA < extractedB;
941
- // return a < b;
942
- }
943
-
944
- /**
945
- * The function compares two values using a custom extractor function and returns true if the first
946
- * value is greater than the second value.
947
- * @param {K} a - The parameter "a" is of type K, which means it can be any type.
948
- * @param {K} b - The parameter "b" is of type K, which means it can be any type. It is used as one
949
- * of the arguments for the comparison in the function.
950
- * @returns a boolean value.
951
- */
952
- protected _gt(a: K, b: K): boolean {
953
- const extractedA = this.extractor(a);
954
- const extractedB = this.extractor(b);
955
- // return this.variant === BSTVariant.STANDARD ? extractedA > extractedB : extractedA < extractedB;
956
- return this.variant === 'STANDARD' ? extractedA > extractedB : extractedA < extractedB;
957
- // return extractedA > extractedB;
958
- // return a > b;
959
- }
960
868
  }
@@ -1,17 +1,19 @@
1
1
  import type {
2
2
  BinaryTreeDeleteResult,
3
3
  BTNCallback,
4
+ Comparable,
5
+ CRUD,
4
6
  KeyOrNodeOrEntry,
7
+ RBTNColor,
5
8
  RBTreeOptions,
6
9
  RedBlackTreeNested,
7
10
  RedBlackTreeNodeNested
8
11
  } from '../../types';
9
- import { CRUD, RBTNColor } from '../../types';
10
12
  import { BST, BSTNode } from './bst';
11
13
  import { IBinaryTree } from '../../interfaces';
12
14
 
13
15
  export class RedBlackTreeNode<
14
- K = any,
16
+ K extends Comparable,
15
17
  V = any,
16
18
  NODE extends RedBlackTreeNode<K, V, NODE> = RedBlackTreeNodeNested<K, V>
17
19
  > extends BSTNode<K, V, NODE> {
@@ -51,7 +53,7 @@ export class RedBlackTreeNode<
51
53
  }
52
54
 
53
55
  export class RedBlackTree<
54
- K = any,
56
+ K extends Comparable,
55
57
  V = any,
56
58
  NODE extends RedBlackTreeNode<K, V, NODE> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>,
57
59
  TREE extends RedBlackTree<K, V, NODE, TREE> = RedBlackTree<K, V, NODE, RedBlackTreeNested<K, V, NODE>>
@@ -252,7 +254,7 @@ export class RedBlackTree<
252
254
  ): BinaryTreeDeleteResult<NODE>[] {
253
255
  if (identifier === null) return [];
254
256
  const results: BinaryTreeDeleteResult<NODE>[] = [];
255
-
257
+ callback = this._ensureCallback(identifier, callback);
256
258
  const nodeToDelete = this.isRealNode(identifier) ? identifier : this.getNode(identifier, callback);
257
259
 
258
260
  if (!nodeToDelete) {
@@ -363,9 +365,10 @@ export class RedBlackTree<
363
365
 
364
366
  while (this.isRealNode(current)) {
365
367
  parent = current;
366
- if (node.key < current.key) {
368
+ const compared = this.comparator(node.key, current.key);
369
+ if (compared < 0) {
367
370
  current = current.left ?? this.NIL;
368
- } else if (node.key > current.key) {
371
+ } else if (compared > 0) {
369
372
  current = current.right ?? this.NIL;
370
373
  } else {
371
374
  this._replaceNode(current, node);
@@ -9,18 +9,19 @@ import type {
9
9
  BinaryTreeDeleteResult,
10
10
  BSTNKeyOrNode,
11
11
  BTNCallback,
12
+ Comparable,
12
13
  IterationType,
13
14
  KeyOrNodeOrEntry,
15
+ RBTNColor,
14
16
  TreeMultiMapNested,
15
17
  TreeMultiMapNodeNested,
16
18
  TreeMultiMapOptions
17
19
  } from '../../types';
18
- import { RBTNColor } from '../../types';
19
20
  import { IBinaryTree } from '../../interfaces';
20
21
  import { RedBlackTree, RedBlackTreeNode } from './rb-tree';
21
22
 
22
23
  export class TreeMultiMapNode<
23
- K = any,
24
+ K extends Comparable,
24
25
  V = any,
25
26
  NODE extends TreeMultiMapNode<K, V, NODE> = TreeMultiMapNodeNested<K, V>
26
27
  > extends RedBlackTreeNode<K, V, NODE> {
@@ -62,7 +63,7 @@ export class TreeMultiMapNode<
62
63
  }
63
64
 
64
65
  export class TreeMultiMap<
65
- K = any,
66
+ K extends Comparable,
66
67
  V = any,
67
68
  NODE extends TreeMultiMapNode<K, V, NODE> = TreeMultiMapNode<K, V, TreeMultiMapNodeNested<K, V>>,
68
69
  TREE extends TreeMultiMap<K, V, NODE, TREE> = TreeMultiMap<K, V, NODE, TreeMultiMapNested<K, V, NODE>>
@@ -257,6 +258,7 @@ export class TreeMultiMap<
257
258
  ): BinaryTreeDeleteResult<NODE>[] {
258
259
  if (identifier === null) return [];
259
260
  const results: BinaryTreeDeleteResult<NODE>[] = [];
261
+ callback = this._ensureCallback(identifier, callback);
260
262
 
261
263
  const nodeToDelete = this.isRealNode(identifier) ? identifier : this.getNode(identifier, callback);
262
264
 
@@ -93,7 +93,7 @@ export class Heap<E = any> extends IterableElementBase<E> {
93
93
  * @param elements
94
94
  * @param options
95
95
  */
96
- static heapify<E>(elements: Iterable<E>, options: { comparator: Comparator<E> }): Heap<E> {
96
+ static heapify<E>(elements: Iterable<E>, options: HeapOptions<E>): Heap<E> {
97
97
  return new Heap<E>(elements, options);
98
98
  }
99
99
 
@@ -1,22 +1,23 @@
1
1
  import { BinaryTree, BinaryTreeNode } from '../data-structures';
2
- import {
2
+ import type {
3
3
  BinaryTreeDeleteResult,
4
4
  BinaryTreeNested,
5
5
  BinaryTreeNodeNested,
6
6
  BinaryTreeOptions,
7
7
  BTNCallback,
8
+ Comparable,
8
9
  KeyOrNodeOrEntry
9
10
  } from '../types';
10
11
 
11
12
  export interface IBinaryTree<
12
- K = number,
13
+ K extends Comparable,
13
14
  V = any,
14
15
  N extends BinaryTreeNode<K, V, N> = BinaryTreeNodeNested<K, V>,
15
16
  TREE extends BinaryTree<K, V, N, TREE> = BinaryTreeNested<K, V, N>
16
17
  > {
17
18
  createNode(key: K, value?: N['value']): N;
18
19
 
19
- createTree(options?: Partial<BinaryTreeOptions<K>>): TREE;
20
+ createTree(options?: Partial<BinaryTreeOptions>): TREE;
20
21
 
21
22
  add(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, N>, value?: V, count?: number): boolean;
22
23
 
@@ -1,5 +1,5 @@
1
1
  export type BSTVariant = 'STANDARD' | 'INVERSE';
2
- export type CP = 'LT' | 'EQ' | 'GT';
2
+ export type CP = 1 | -1 | 0;
3
3
 
4
4
  /**
5
5
  * Enum representing different loop types.