deque-typed 1.54.1 → 1.54.3

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 (46) hide show
  1. package/LICENSE +1 -1
  2. package/coverage/lcov-report/index.ts.html +2 -2
  3. package/dist/data-structures/binary-tree/avl-tree-counter.d.ts +21 -20
  4. package/dist/data-structures/binary-tree/avl-tree-counter.js +8 -7
  5. package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +12 -12
  6. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +2 -2
  7. package/dist/data-structures/binary-tree/avl-tree.d.ts +25 -21
  8. package/dist/data-structures/binary-tree/avl-tree.js +12 -8
  9. package/dist/data-structures/binary-tree/binary-tree.d.ts +173 -225
  10. package/dist/data-structures/binary-tree/binary-tree.js +239 -144
  11. package/dist/data-structures/binary-tree/bst.d.ts +62 -56
  12. package/dist/data-structures/binary-tree/bst.js +78 -122
  13. package/dist/data-structures/binary-tree/red-black-tree.d.ts +19 -25
  14. package/dist/data-structures/binary-tree/red-black-tree.js +7 -13
  15. package/dist/data-structures/binary-tree/tree-counter.d.ts +19 -19
  16. package/dist/data-structures/binary-tree/tree-counter.js +12 -12
  17. package/dist/data-structures/binary-tree/tree-multi-map.d.ts +14 -14
  18. package/dist/data-structures/binary-tree/tree-multi-map.js +4 -4
  19. package/dist/index.d.ts +2 -2
  20. package/dist/index.js +2 -3
  21. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -0
  22. package/dist/types/data-structures/binary-tree/bst.d.ts +1 -1
  23. package/dist/types/data-structures/binary-tree/index.d.ts +1 -1
  24. package/dist/types/data-structures/binary-tree/index.js +1 -1
  25. package/dist/types/data-structures/binary-tree/tree-counter.d.ts +1 -1
  26. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
  27. package/dist/utils/utils.d.ts +2 -2
  28. package/package.json +3 -3
  29. package/src/data-structures/binary-tree/avl-tree-counter.ts +30 -23
  30. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +25 -15
  31. package/src/data-structures/binary-tree/avl-tree.ts +35 -29
  32. package/src/data-structures/binary-tree/binary-tree.ts +469 -252
  33. package/src/data-structures/binary-tree/bst.ts +141 -143
  34. package/src/data-structures/binary-tree/red-black-tree.ts +27 -35
  35. package/src/data-structures/binary-tree/tree-counter.ts +33 -27
  36. package/src/data-structures/binary-tree/tree-multi-map.ts +25 -17
  37. package/src/index.ts +2 -3
  38. package/src/types/data-structures/binary-tree/binary-tree.ts +1 -0
  39. package/src/types/data-structures/binary-tree/bst.ts +1 -1
  40. package/src/types/data-structures/binary-tree/index.ts +1 -1
  41. package/src/types/data-structures/binary-tree/tree-counter.ts +1 -1
  42. package/src/types/data-structures/binary-tree/tree-multi-map.ts +1 -1
  43. package/src/utils/utils.ts +2 -2
  44. /package/dist/types/data-structures/binary-tree/{rb-tree.d.ts → red-black-tree.d.ts} +0 -0
  45. /package/dist/types/data-structures/binary-tree/{rb-tree.js → red-black-tree.js} +0 -0
  46. /package/src/types/data-structures/binary-tree/{rb-tree.ts → red-black-tree.ts} +0 -0
@@ -17,8 +17,7 @@ import type {
17
17
  IterationType,
18
18
  NodeCallback,
19
19
  NodePredicate,
20
- OptNode,
21
- OptNodeOrNull
20
+ OptNode
22
21
  } from '../../types';
23
22
  import { BinaryTree, BinaryTreeNode } from './binary-tree';
24
23
  import { IBinaryTree } from '../../interfaces';
@@ -27,6 +26,8 @@ import { isComparable } from '../../utils';
27
26
  import { Range } from '../../common';
28
27
 
29
28
  export class BSTNode<K = any, V = any> extends BinaryTreeNode<K, V> {
29
+ override parent?: BSTNode<K, V> = undefined;
30
+
30
31
  /**
31
32
  * This TypeScript constructor function initializes an instance with a key and an optional value.
32
33
  * @param {K} key - The `key` parameter is typically used to uniquely identify an object or element
@@ -40,28 +41,26 @@ export class BSTNode<K = any, V = any> extends BinaryTreeNode<K, V> {
40
41
  super(key, value);
41
42
  }
42
43
 
43
- override parent?: BSTNode<K, V> = undefined;
44
-
45
- override _left?: OptNodeOrNull<BSTNode<K, V>> = undefined;
44
+ override _left?: BSTNode<K, V> | null | undefined = undefined;
46
45
 
47
- override get left(): OptNodeOrNull<BSTNode<K, V>> {
46
+ override get left(): BSTNode<K, V> | null | undefined {
48
47
  return this._left;
49
48
  }
50
49
 
51
- override set left(v: OptNodeOrNull<BSTNode<K, V>>) {
50
+ override set left(v: BSTNode<K, V> | null | undefined) {
52
51
  if (v) {
53
52
  v.parent = this;
54
53
  }
55
54
  this._left = v;
56
55
  }
57
56
 
58
- override _right?: OptNodeOrNull<BSTNode<K, V>> = undefined;
57
+ override _right?: BSTNode<K, V> | null | undefined = undefined;
59
58
 
60
- override get right(): OptNodeOrNull<BSTNode<K, V>> {
59
+ override get right(): BSTNode<K, V> | null | undefined {
61
60
  return this._right;
62
61
  }
63
62
 
64
- override set right(v: OptNodeOrNull<BSTNode<K, V>>) {
63
+ override set right(v: BSTNode<K, V> | null | undefined) {
65
64
  if (v) {
66
65
  v.parent = this;
67
66
  }
@@ -103,9 +102,9 @@ export class BSTNode<K = any, V = any> extends BinaryTreeNode<K, V> {
103
102
  * @example
104
103
  * // Find elements in a range
105
104
  * const bst = new BST<number>([10, 5, 15, 3, 7, 12, 18]);
106
- * console.log(bst.search(new Range(5, 10))); // [10, 5, 7]
107
- * console.log(bst.rangeSearch([4, 12], node => node.key.toString())); // ['10', '12', '5', '7']
108
- * console.log(bst.search(new Range(4, 12, true, false))); // [10, 5, 7]
105
+ * console.log(bst.search(new Range(5, 10))); // [5, 7, 10]
106
+ * console.log(bst.rangeSearch([4, 12], node => node.key.toString())); // ['5', '7', '10', '12']
107
+ * console.log(bst.search(new Range(4, 12, true, false))); // [5, 7, 10]
109
108
  * console.log(bst.rangeSearch([15, 20])); // [15, 18]
110
109
  * console.log(bst.search(new Range(15, 20, false))); // [18]
111
110
  * @example
@@ -142,12 +141,17 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
142
141
  * This TypeScript constructor initializes a binary search tree with optional options and adds
143
142
  * elements if provided.
144
143
  * @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the constructor is an
145
- * iterable that can contain elements of type `BTNRep<K, V, BSTNode<K, V>>` or `R`. It is used to
144
+ * iterable that can contain elements of type `K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined ` or `R`. It is used to
146
145
  * initialize the binary search tree with keys, nodes, entries, or raw data.
147
146
  * @param [options] - The `options` parameter is an optional object that can contain the following
148
147
  * properties:
149
148
  */
150
- constructor(keysNodesEntriesOrRaws: Iterable<BTNRep<K, V, BSTNode<K, V>> | R> = [], options?: BSTOptions<K, V, R>) {
149
+ constructor(
150
+ keysNodesEntriesOrRaws: Iterable<
151
+ K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | R
152
+ > = [],
153
+ options?: BSTOptions<K, V, R>
154
+ ) {
151
155
  super([], options);
152
156
 
153
157
  if (options) {
@@ -243,7 +247,7 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
243
247
  *
244
248
  * The function ensures the existence of a node in a data structure and returns it, or undefined if
245
249
  * it doesn't exist.
246
- * @param {BTNRep<K, V, BSTNode<K, V>>} keyNodeOrEntry - The parameter
250
+ * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The parameter
247
251
  * `keyNodeOrEntry` can accept a value of type `R`, which represents the key, node,
248
252
  * entry, or raw element that needs to be ensured in the tree.
249
253
  * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional
@@ -253,7 +257,7 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
253
257
  * not be ensured.
254
258
  */
255
259
  override ensureNode(
256
- keyNodeOrEntry: BTNRep<K, V, BSTNode<K, V>>,
260
+ keyNodeOrEntry: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
257
261
  iterationType: IterationType = this.iterationType
258
262
  ): OptNode<BSTNode<K, V>> {
259
263
  return super.ensureNode(keyNodeOrEntry, iterationType) ?? undefined;
@@ -264,12 +268,14 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
264
268
  * Space Complexity: O(1)
265
269
  *
266
270
  * The function checks if the input is an instance of the BSTNode class.
267
- * @param {BTNRep<K, V, BSTNode<K, V>>} keyNodeOrEntry - The parameter
268
- * `keyNodeOrEntry` can be of type `R` or `BTNRep<K, V, BSTNode<K, V>>`.
271
+ * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The parameter
272
+ * `keyNodeOrEntry` can be of type `R` or `K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined `.
269
273
  * @returns a boolean value indicating whether the input parameter `keyNodeOrEntry` is
270
274
  * an instance of the `BSTNode` class.
271
275
  */
272
- override isNode(keyNodeOrEntry: BTNRep<K, V, BSTNode<K, V>>): keyNodeOrEntry is BSTNode<K, V> {
276
+ override isNode(
277
+ keyNodeOrEntry: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined
278
+ ): keyNodeOrEntry is BSTNode<K, V> {
273
279
  return keyNodeOrEntry instanceof BSTNode;
274
280
  }
275
281
 
@@ -293,13 +299,16 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
293
299
  * Space Complexity: O(log n)
294
300
  *
295
301
  * The `add` function in TypeScript adds a new node to a binary search tree based on the key value.
296
- * @param {BTNRep<K, V, BSTNode<K, V>>} keyNodeOrEntry - The parameter
297
- * `keyNodeOrEntry` can accept a value of type `R` or `BTNRep<K, V, BSTNode<K, V>>`.
302
+ * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The parameter
303
+ * `keyNodeOrEntry` can accept a value of type `R` or `K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined `.
298
304
  * @param {V} [value] - The `value` parameter is an optional value that can be associated with the
299
305
  * key in the binary search tree. If provided, it will be stored in the node along with the key.
300
306
  * @returns a boolean value.
301
307
  */
302
- override add(keyNodeOrEntry: BTNRep<K, V, BSTNode<K, V>>, value?: V): boolean {
308
+ override add(
309
+ keyNodeOrEntry: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
310
+ value?: V
311
+ ): boolean {
303
312
  const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
304
313
  if (newNode === undefined) return false;
305
314
 
@@ -383,7 +392,7 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
383
392
  }
384
393
 
385
394
  const realBTNExemplars: {
386
- key: R | BTNRep<K, V, BSTNode<K, V>>;
395
+ key: R | K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined;
387
396
  value: V | undefined;
388
397
  orgIndex: number;
389
398
  }[] = [];
@@ -394,7 +403,11 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
394
403
  i++;
395
404
  }
396
405
 
397
- let sorted: { key: R | BTNRep<K, V, BSTNode<K, V>>; value: V | undefined; orgIndex: number }[] = [];
406
+ let sorted: {
407
+ key: R | K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined;
408
+ value: V | undefined;
409
+ orgIndex: number;
410
+ }[] = [];
398
411
 
399
412
  sorted = realBTNExemplars.sort(({ key: a }, { key: b }) => {
400
413
  let keyA: K | undefined | null, keyB: K | undefined | null;
@@ -418,7 +431,13 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
418
431
  return 0;
419
432
  });
420
433
 
421
- const _dfs = (arr: { key: R | BTNRep<K, V, BSTNode<K, V>>; value: V | undefined; orgIndex: number }[]) => {
434
+ const _dfs = (
435
+ arr: {
436
+ key: R | K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined;
437
+ value: V | undefined;
438
+ orgIndex: number;
439
+ }[]
440
+ ) => {
422
441
  if (arr.length === 0) return;
423
442
 
424
443
  const mid = Math.floor((arr.length - 1) / 2);
@@ -473,7 +492,7 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
473
492
  *
474
493
  * The function `search` in TypeScript overrides the search behavior in a binary tree structure based
475
494
  * on specified criteria.
476
- * @param {BTNRep<K, V, BSTNode<K, V>> | NodePredicate<BSTNode<K, V>>} keyNodeEntryOrPredicate - The
495
+ * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BSTNode<K, V>>} keyNodeEntryOrPredicate - The
477
496
  * `keyNodeEntryOrPredicate` parameter in the `override search` method can accept one of the
478
497
  * following types:
479
498
  * @param [onlyOne=false] - The `onlyOne` parameter is a boolean flag that determines whether the
@@ -481,9 +500,9 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
481
500
  * search will return as soon as a matching node is found. If `onlyOne` is set to `false`, the
482
501
  * @param {C} callback - The `callback` parameter in the `override search` function is a function
483
502
  * that will be called on each node that matches the search criteria. It is of type `C`, which
484
- * extends `NodeCallback<BSTNode<K, V>>`. The callback function should accept a node of type `BSTNode<K, V>` as its
503
+ * extends `NodeCallback<BSTNode<K, V> | null>`. The callback function should accept a node of type `BSTNode<K, V>` as its
485
504
  * argument and
486
- * @param {BTNRep<K, V, BSTNode<K, V>>} startNode - The `startNode` parameter in the `override search`
505
+ * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the `override search`
487
506
  * method represents the node from which the search operation will begin. It is the starting point
488
507
  * for searching within the tree data structure. The method ensures that the `startNode` is a valid
489
508
  * node before proceeding with the search operation. If the `
@@ -496,10 +515,17 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
496
515
  * collected in an array and returned as the output of the method.
497
516
  */
498
517
  override search<C extends NodeCallback<BSTNode<K, V>>>(
499
- keyNodeEntryOrPredicate: BTNRep<K, V, BSTNode<K, V>> | NodePredicate<BSTNode<K, V>> | Range<K>,
518
+ keyNodeEntryOrPredicate:
519
+ | K
520
+ | BSTNode<K, V>
521
+ | [K | null | undefined, V | undefined]
522
+ | null
523
+ | undefined
524
+ | NodePredicate<BSTNode<K, V>>
525
+ | Range<K>,
500
526
  onlyOne = false,
501
527
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
502
- startNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
528
+ startNode: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined = this._root,
503
529
  iterationType: IterationType = this.iterationType
504
530
  ): ReturnType<C>[] {
505
531
  if (keyNodeEntryOrPredicate === undefined) return [];
@@ -511,21 +537,32 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
511
537
  const isRange = this.isRange(keyNodeEntryOrPredicate);
512
538
  // Set predicate based on parameter type
513
539
  if (isRange) {
514
- predicate = node => keyNodeEntryOrPredicate.isInRange(node.key, this._comparator);
540
+ predicate = node => {
541
+ if (!node) return false;
542
+ return keyNodeEntryOrPredicate.isInRange(node.key, this._comparator);
543
+ };
515
544
  } else {
516
545
  predicate = this._ensurePredicate(keyNodeEntryOrPredicate);
517
546
  }
518
- const isToLeftByRange = (cur: BSTNode<K, V>) => {
547
+ const shouldVisitLeft = (cur: BSTNode<K, V> | null | undefined) => {
548
+ if (!cur) return false;
549
+ if (!this.isRealNode(cur.left)) return false;
519
550
  if (isRange) {
520
551
  const range = keyNodeEntryOrPredicate;
521
552
  const leftS = this.isReverse ? range.high : range.low;
522
553
  const leftI = this.isReverse ? range.includeHigh : range.includeLow;
523
554
  return (leftI && this._compare(cur.key, leftS) >= 0) || (!leftI && this._compare(cur.key, leftS) > 0);
524
555
  }
525
- return false;
556
+ if (!isRange && !this._isPredicate(keyNodeEntryOrPredicate)) {
557
+ const benchmarkKey = this._extractKey(keyNodeEntryOrPredicate);
558
+ return benchmarkKey !== null && benchmarkKey !== undefined && this._compare(cur.key, benchmarkKey) > 0;
559
+ }
560
+ return true;
526
561
  };
527
562
 
528
- const isToRightByRange = (cur: BSTNode<K, V>) => {
563
+ const shouldVisitRight = (cur: BSTNode<K, V> | null | undefined) => {
564
+ if (!cur) return false;
565
+ if (!this.isRealNode(cur.right)) return false;
529
566
  if (isRange) {
530
567
  const range = keyNodeEntryOrPredicate;
531
568
  const rightS = this.isReverse ? range.low : range.high;
@@ -533,79 +570,27 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
533
570
 
534
571
  return (rightI && this._compare(cur.key, rightS) <= 0) || (!rightI && this._compare(cur.key, rightS) < 0);
535
572
  }
536
- return false;
573
+ if (!isRange && !this._isPredicate(keyNodeEntryOrPredicate)) {
574
+ const benchmarkKey = this._extractKey(keyNodeEntryOrPredicate);
575
+ return benchmarkKey !== null && benchmarkKey !== undefined && this._compare(cur.key, benchmarkKey) < 0;
576
+ }
577
+ return true;
537
578
  };
538
- const ans: ReturnType<C>[] = [];
539
- if (iterationType === 'RECURSIVE') {
540
- const dfs = (cur: BSTNode<K, V>) => {
541
- if (predicate(cur)) {
542
- ans.push(callback(cur));
543
- if (onlyOne) return;
544
- }
545
-
546
- if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
547
-
548
- if (isRange) {
549
- if (this.isRealNode(cur.left) && isToLeftByRange(cur)) dfs(cur.left);
550
- if (this.isRealNode(cur.right) && isToRightByRange(cur)) dfs(cur.right);
551
- } else if (!this._isPredicate(keyNodeEntryOrPredicate)) {
552
- const benchmarkKey = this._extractKey(keyNodeEntryOrPredicate);
553
- if (
554
- this.isRealNode(cur.left) &&
555
- benchmarkKey !== null &&
556
- benchmarkKey !== undefined &&
557
- this._compare(cur.key, benchmarkKey) > 0
558
- )
559
- dfs(cur.left);
560
- if (
561
- this.isRealNode(cur.right) &&
562
- benchmarkKey !== null &&
563
- benchmarkKey !== undefined &&
564
- this._compare(cur.key, benchmarkKey) < 0
565
- )
566
- dfs(cur.right);
567
- } else {
568
- if (this.isRealNode(cur.left)) dfs(cur.left);
569
- if (this.isRealNode(cur.right)) dfs(cur.right);
570
- }
571
- };
572
-
573
- dfs(startNode);
574
- } else {
575
- const stack = [startNode];
576
- while (stack.length > 0) {
577
- const cur = stack.pop()!;
578
- if (predicate(cur)) {
579
- ans.push(callback(cur));
580
- if (onlyOne) return ans;
581
- }
582
- if (isRange) {
583
- if (this.isRealNode(cur.left) && isToLeftByRange(cur)) stack.push(cur.left);
584
- if (this.isRealNode(cur.right) && isToRightByRange(cur)) stack.push(cur.right);
585
- } else if (!this._isPredicate(keyNodeEntryOrPredicate)) {
586
- const benchmarkKey = this._extractKey(keyNodeEntryOrPredicate);
587
- if (
588
- this.isRealNode(cur.right) &&
589
- benchmarkKey !== null &&
590
- benchmarkKey !== undefined &&
591
- this._compare(cur.key, benchmarkKey) < 0
592
- )
593
- stack.push(cur.right);
594
- if (
595
- this.isRealNode(cur.left) &&
596
- benchmarkKey !== null &&
597
- benchmarkKey !== undefined &&
598
- this._compare(cur.key, benchmarkKey) > 0
599
- )
600
- stack.push(cur.left);
601
- } else {
602
- if (this.isRealNode(cur.right)) stack.push(cur.right);
603
- if (this.isRealNode(cur.left)) stack.push(cur.left);
604
- }
579
+ return super._dfs(
580
+ callback,
581
+ 'IN',
582
+ onlyOne,
583
+ startNode,
584
+ iterationType,
585
+ false,
586
+ shouldVisitLeft,
587
+ shouldVisitRight,
588
+ () => true,
589
+ cur => {
590
+ if (cur) return predicate(cur);
591
+ return false;
605
592
  }
606
- }
607
-
608
- return ans;
593
+ );
609
594
  }
610
595
 
611
596
  /**
@@ -617,9 +602,9 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
617
602
  * either a `Range` object or an array of two elements representing the range boundaries.
618
603
  * @param {C} callback - The `callback` parameter in the `rangeSearch` function is a callback
619
604
  * function that is used to process each node that is found within the specified range during the
620
- * search operation. It is of type `NodeCallback<BSTNode<K, V>>`, where `BSTNode<K, V>` is the type of nodes in the
605
+ * search operation. It is of type `NodeCallback<BSTNode<K, V> | null>`, where `BSTNode<K, V>` is the type of nodes in the
621
606
  * data structure.
622
- * @param {BTNRep<K, V, BSTNode<K, V>>} startNode - The `startNode` parameter in the `rangeSearch`
607
+ * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the `rangeSearch`
623
608
  * function represents the node from which the search for nodes within the specified range will
624
609
  * begin. It is the starting point for the range search operation.
625
610
  * @param {IterationType} iterationType - The `iterationType` parameter in the `rangeSearch` function
@@ -632,7 +617,7 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
632
617
  rangeSearch<C extends NodeCallback<BSTNode<K, V>>>(
633
618
  range: Range<K> | [K, K],
634
619
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
635
- startNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
620
+ startNode: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined = this._root,
636
621
  iterationType: IterationType = this.iterationType
637
622
  ) {
638
623
  const searchRange: Range<K> = range instanceof Range ? range : new Range(range[0], range[1]);
@@ -644,8 +629,8 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
644
629
  * Space Complexity: O(log n)
645
630
  *
646
631
  * This function retrieves a node based on a given keyNodeEntryOrPredicate within a binary search tree structure.
647
- * @param {BTNRep<K, V, BSTNode<K, V>> | NodePredicate<BSTNode<K, V>>} keyNodeEntryOrPredicate - The `keyNodeEntryOrPredicate`
648
- * parameter can be of type `BTNRep<K, V, BSTNode<K, V>>`, `R`, or `NodePredicate<BSTNode<K, V>>`.
632
+ * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BSTNode<K, V>>} keyNodeEntryOrPredicate - The `keyNodeEntryOrPredicate`
633
+ * parameter can be of type `K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined `, `R`, or `NodePredicate<BSTNode<K, V>>`.
649
634
  * @param {BSTNOptKeyOrNode<K, BSTNode<K, V>>} startNode - The `startNode` parameter in the `getNode` method
650
635
  * is used to specify the starting point for searching nodes in the binary search tree. If no
651
636
  * specific starting point is provided, the default value is set to `this._root`, which is the root
@@ -660,7 +645,13 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
660
645
  * returns the first node found or `undefined` if no node is found.
661
646
  */
662
647
  override getNode(
663
- keyNodeEntryOrPredicate: BTNRep<K, V, BSTNode<K, V>> | NodePredicate<BSTNode<K, V>>,
648
+ keyNodeEntryOrPredicate:
649
+ | K
650
+ | BSTNode<K, V>
651
+ | [K | null | undefined, V | undefined]
652
+ | null
653
+ | undefined
654
+ | NodePredicate<BSTNode<K, V>>,
664
655
  startNode: BSTNOptKeyOrNode<K, BSTNode<K, V>> = this._root,
665
656
  iterationType: IterationType = this.iterationType
666
657
  ): OptNode<BSTNode<K, V>> {
@@ -671,29 +662,36 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
671
662
  * Time complexity: O(n)
672
663
  * Space complexity: O(n)
673
664
  *
674
- * The function overrides the depth-first search method and returns an array of the return types of
675
- * the callback function.
665
+ * The function `dfs` in TypeScript overrides the base class method with default parameters and
666
+ * returns the result of the super class `dfs` method.
676
667
  * @param {C} callback - The `callback` parameter is a function that will be called for each node
677
- * during the depth-first search traversal. It is an optional parameter and defaults to
678
- * `this._DEFAULT_NODE_CALLBACK`. The type `C` represents the type of the callback function.
679
- * @param {DFSOrderPattern} [pattern=IN] - The "pattern" parameter in the code snippet refers to the
680
- * order in which the Depth-First Search (DFS) algorithm visits the nodes in a tree or graph. It can
681
- * take one of the following values:
682
- * @param {BTNRep<K, V, BSTNode<K, V>>} startNode - The `startNode` parameter is the starting
683
- * point for the depth-first search traversal. It can be either a root node, a key-value pair, or a
684
- * node entry. If not specified, the default value is the root of the tree.
685
- * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter specifies the
686
- * type of iteration to be used during the Depth-First Search (DFS) traversal. It can have one of the
687
- * following values:
688
- * @returns The method is returning an array of the return type of the callback function.
668
+ * visited during the Depth-First Search traversal. It is a generic type `C` that extends the
669
+ * `NodeCallback` interface for `BSTNode<K, V>`. The default value for `callback` is `this._
670
+ * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `override dfs` method
671
+ * specifies the order in which the Depth-First Search (DFS) traversal should be performed on the
672
+ * Binary Search Tree (BST). The possible values for the `pattern` parameter are:
673
+ * @param {boolean} [onlyOne=false] - The `onlyOne` parameter in the `override dfs` method is a
674
+ * boolean flag that indicates whether you want to stop the depth-first search traversal after
675
+ * finding the first matching node or continue searching for all matching nodes. If `onlyOne` is set
676
+ * to `true`, the traversal will stop after finding
677
+ * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined} startNode -
678
+ * The `startNode` parameter in the `override dfs` method can be one of the following types:
679
+ * @param {IterationType} iterationType - The `iterationType` parameter in the `override dfs` method
680
+ * specifies the type of iteration to be performed during the Depth-First Search (DFS) traversal of a
681
+ * Binary Search Tree (BST). It is used to determine the order in which nodes are visited during the
682
+ * traversal. The possible values for `
683
+ * @returns The `override` function is returning the result of calling the `dfs` method from the
684
+ * superclass, with the provided arguments `callback`, `pattern`, `onlyOne`, `startNode`, and
685
+ * `iterationType`. The return type is an array of the return type of the callback function `C`.
689
686
  */
690
687
  override dfs<C extends NodeCallback<BSTNode<K, V>>>(
691
688
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
692
689
  pattern: DFSOrderPattern = 'IN',
693
- startNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
690
+ onlyOne: boolean = false,
691
+ startNode: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined = this._root,
694
692
  iterationType: IterationType = this.iterationType
695
693
  ): ReturnType<C>[] {
696
- return super.dfs(callback, pattern, startNode, iterationType);
694
+ return super.dfs(callback, pattern, onlyOne, startNode, iterationType);
697
695
  }
698
696
 
699
697
  /**
@@ -705,7 +703,7 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
705
703
  * @param {C} callback - The `callback` parameter is a function that will be called for each node
706
704
  * visited during the breadth-first search. It should take a single argument, which is the current
707
705
  * node being visited, and it can return a value of any type.
708
- * @param {BTNRep<K, V, BSTNode<K, V>>} startNode - The `startNode` parameter is the starting
706
+ * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter is the starting
709
707
  * point for the breadth-first search. It can be either a root node, a key-value pair, or an entry
710
708
  * object. If no value is provided, the default value is the root of the tree.
711
709
  * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type
@@ -715,7 +713,7 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
715
713
  */
716
714
  override bfs<C extends NodeCallback<BSTNode<K, V>>>(
717
715
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
718
- startNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
716
+ startNode: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined = this._root,
719
717
  iterationType: IterationType = this.iterationType
720
718
  ): ReturnType<C>[] {
721
719
  return super.bfs(callback, startNode, iterationType, false);
@@ -728,9 +726,9 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
728
726
  * The function overrides the listLevels method from the superclass and returns an array of arrays
729
727
  * containing the results of the callback function applied to each level of the tree.
730
728
  * @param {C} callback - The `callback` parameter is a generic type `C` that extends
731
- * `NodeCallback<BSTNode<K, V>>`. It represents a callback function that will be called for each node in the
729
+ * `NodeCallback<BSTNode<K, V> | null>`. It represents a callback function that will be called for each node in the
732
730
  * tree during the iteration process.
733
- * @param {BTNRep<K, V, BSTNode<K, V>>} startNode - The `startNode` parameter is the starting
731
+ * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter is the starting
734
732
  * point for listing the levels of the binary tree. It can be either a root node of the tree, a
735
733
  * key-value pair representing a node in the tree, or a key representing a node in the tree. If no
736
734
  * value is provided, the root of
@@ -741,7 +739,7 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
741
739
  */
742
740
  override listLevels<C extends NodeCallback<BSTNode<K, V>>>(
743
741
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
744
- startNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
742
+ startNode: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined = this._root,
745
743
  iterationType: IterationType = this.iterationType
746
744
  ): ReturnType<C>[][] {
747
745
  return super.listLevels(callback, startNode, iterationType, false);
@@ -759,7 +757,7 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
759
757
  * @param {CP} lesserOrGreater - The `lesserOrGreater` parameter is used to determine whether to
760
758
  * traverse nodes that are lesser, greater, or both than the `targetNode`. It accepts the values -1,
761
759
  * 0, or 1, where:
762
- * @param {BTNRep<K, V, BSTNode<K, V>>} targetNode - The `targetNode` parameter is the node in
760
+ * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } targetNode - The `targetNode` parameter is the node in
763
761
  * the binary tree that you want to start traversing from. It can be specified either by providing
764
762
  * the key of the node, the node itself, or an entry containing the key and value of the node. If no
765
763
  * `targetNode` is provided,
@@ -771,7 +769,7 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
771
769
  lesserOrGreaterTraverse<C extends NodeCallback<BSTNode<K, V>>>(
772
770
  callback: C = this._DEFAULT_NODE_CALLBACK as C,
773
771
  lesserOrGreater: CP = -1,
774
- targetNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
772
+ targetNode: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined = this._root,
775
773
  iterationType: IterationType = this.iterationType
776
774
  ): ReturnType<C>[] {
777
775
  const targetNodeEnsured = this.ensureNode(targetNode);
@@ -831,8 +829,8 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
831
829
  if (l > r) return;
832
830
  const m = l + Math.floor((r - l) / 2);
833
831
  const midNode = sorted[m];
834
- if (this._isMapMode) this.add(midNode.key);
835
- else this.add([midNode.key, midNode.value]);
832
+ if (this._isMapMode && midNode !== null) this.add(midNode.key);
833
+ else if (midNode !== null) this.add([midNode.key, midNode.value]);
836
834
  buildBalanceBST(l, m - 1);
837
835
  buildBalanceBST(m + 1, r);
838
836
  };
@@ -848,8 +846,8 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
848
846
  if (l <= r) {
849
847
  const m = l + Math.floor((r - l) / 2);
850
848
  const midNode = sorted[m];
851
- if (this._isMapMode) this.add(midNode.key);
852
- else this.add([midNode.key, midNode.value]);
849
+ if (this._isMapMode && midNode !== null) this.add(midNode.key);
850
+ else if (midNode !== null) this.add([midNode.key, midNode.value]);
853
851
  stack.push([m + 1, r]);
854
852
  stack.push([l, m - 1]);
855
853
  }
@@ -877,7 +875,7 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
877
875
  let balanced = true;
878
876
 
879
877
  if (iterationType === 'RECURSIVE') {
880
- const _height = (cur: OptNodeOrNull<BSTNode<K, V>>): number => {
878
+ const _height = (cur: BSTNode<K, V> | null | undefined): number => {
881
879
  if (!cur) return 0;
882
880
  const leftHeight = _height(cur.left),
883
881
  rightHeight = _height(cur.right);
@@ -966,15 +964,15 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
966
964
  * Space Complexity: O(1)
967
965
  *
968
966
  * The function overrides a method and converts a key, value pair or entry or raw element to a node.
969
- * @param {BTNRep<K, V, BSTNode<K, V>>} keyNodeOrEntry - A variable that can be of
970
- * type R or BTNRep<K, V, BSTNode<K, V>>. It represents either a key, a node, an entry, or a raw
967
+ * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - A variable that can be of
968
+ * type R or K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined . It represents either a key, a node, an entry, or a raw
971
969
  * element.
972
970
  * @param {V} [value] - The `value` parameter is an optional value of type `V`. It represents the
973
971
  * value associated with a key in a key-value pair.
974
972
  * @returns either a BSTNode<K, V> object or undefined.
975
973
  */
976
974
  protected override _keyValueNodeOrEntryToNodeAndValue(
977
- keyNodeOrEntry: BTNRep<K, V, BSTNode<K, V>>,
975
+ keyNodeOrEntry: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
978
976
  value?: V
979
977
  ): [OptNode<BSTNode<K, V>>, V | undefined] {
980
978
  const [node, entryValue] = super._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);