bst-typed 2.4.4 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +0 -30
  2. package/dist/cjs/index.cjs +1228 -544
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/cjs-legacy/index.cjs +1225 -541
  5. package/dist/cjs-legacy/index.cjs.map +1 -1
  6. package/dist/esm/index.mjs +1228 -545
  7. package/dist/esm/index.mjs.map +1 -1
  8. package/dist/esm-legacy/index.mjs +1225 -542
  9. package/dist/esm-legacy/index.mjs.map +1 -1
  10. package/dist/types/common/error.d.ts +23 -0
  11. package/dist/types/common/index.d.ts +1 -0
  12. package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
  13. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
  14. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
  15. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +439 -78
  16. package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
  17. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +217 -31
  18. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
  19. package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
  20. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
  21. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
  22. package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
  23. package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
  24. package/dist/types/data-structures/graph/directed-graph.d.ts +220 -47
  25. package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
  26. package/dist/types/data-structures/graph/undirected-graph.d.ts +218 -59
  27. package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
  28. package/dist/types/data-structures/heap/heap.d.ts +287 -99
  29. package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
  30. package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
  31. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
  32. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
  33. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
  34. package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
  35. package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
  36. package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
  37. package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
  38. package/dist/types/data-structures/queue/deque.d.ts +313 -66
  39. package/dist/types/data-structures/queue/queue.d.ts +211 -42
  40. package/dist/types/data-structures/stack/stack.d.ts +174 -32
  41. package/dist/types/data-structures/trie/trie.d.ts +213 -43
  42. package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
  43. package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
  44. package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
  45. package/dist/umd/bst-typed.js +1221 -537
  46. package/dist/umd/bst-typed.js.map +1 -1
  47. package/dist/umd/bst-typed.min.js +2 -2
  48. package/dist/umd/bst-typed.min.js.map +1 -1
  49. package/package.json +2 -2
  50. package/src/common/error.ts +60 -0
  51. package/src/common/index.ts +2 -0
  52. package/src/data-structures/base/iterable-element-base.ts +2 -2
  53. package/src/data-structures/binary-tree/avl-tree.ts +134 -51
  54. package/src/data-structures/binary-tree/binary-indexed-tree.ts +303 -247
  55. package/src/data-structures/binary-tree/binary-tree.ts +542 -121
  56. package/src/data-structures/binary-tree/bst.ts +346 -37
  57. package/src/data-structures/binary-tree/red-black-tree.ts +309 -96
  58. package/src/data-structures/binary-tree/segment-tree.ts +372 -248
  59. package/src/data-structures/binary-tree/tree-map.ts +1292 -13
  60. package/src/data-structures/binary-tree/tree-multi-map.ts +1098 -215
  61. package/src/data-structures/binary-tree/tree-multi-set.ts +863 -69
  62. package/src/data-structures/binary-tree/tree-set.ts +1143 -15
  63. package/src/data-structures/graph/abstract-graph.ts +106 -1
  64. package/src/data-structures/graph/directed-graph.ts +223 -47
  65. package/src/data-structures/graph/map-graph.ts +59 -1
  66. package/src/data-structures/graph/undirected-graph.ts +299 -59
  67. package/src/data-structures/hash/hash-map.ts +243 -79
  68. package/src/data-structures/heap/heap.ts +291 -102
  69. package/src/data-structures/heap/max-heap.ts +48 -3
  70. package/src/data-structures/heap/min-heap.ts +59 -0
  71. package/src/data-structures/linked-list/doubly-linked-list.ts +286 -44
  72. package/src/data-structures/linked-list/singly-linked-list.ts +278 -65
  73. package/src/data-structures/linked-list/skip-linked-list.ts +689 -90
  74. package/src/data-structures/matrix/matrix.ts +425 -22
  75. package/src/data-structures/priority-queue/max-priority-queue.ts +59 -3
  76. package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
  77. package/src/data-structures/priority-queue/priority-queue.ts +60 -0
  78. package/src/data-structures/queue/deque.ts +343 -68
  79. package/src/data-structures/queue/queue.ts +211 -42
  80. package/src/data-structures/stack/stack.ts +174 -32
  81. package/src/data-structures/trie/trie.ts +215 -44
  82. package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
  83. package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
  84. package/src/types/data-structures/queue/deque.ts +7 -0
  85. package/src/utils/utils.ts +4 -2
@@ -475,6 +475,237 @@ var LinearBase = class _LinearBase extends IterableElementBase {
475
475
  }
476
476
  };
477
477
 
478
+ // src/common/error.ts
479
+ var ERR = {
480
+ // Range / index
481
+ indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
482
+ invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
483
+ // Type / argument
484
+ invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
485
+ comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
486
+ invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
487
+ notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
488
+ invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
489
+ invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
490
+ invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
491
+ reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
492
+ callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
493
+ // State / operation
494
+ invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
495
+ // Matrix
496
+ matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
497
+ matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
498
+ matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
499
+ matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
500
+ matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
501
+ };
502
+
503
+ // src/common/index.ts
504
+ var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
505
+ DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
506
+ DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
507
+ return DFSOperation2;
508
+ })(DFSOperation || {});
509
+ var Range = class {
510
+ constructor(low, high, includeLow = true, includeHigh = true) {
511
+ this.low = low;
512
+ this.high = high;
513
+ this.includeLow = includeLow;
514
+ this.includeHigh = includeHigh;
515
+ }
516
+ static {
517
+ __name(this, "Range");
518
+ }
519
+ // Determine whether a key is within the range
520
+ isInRange(key, comparator) {
521
+ const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
522
+ const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
523
+ return lowCheck && highCheck;
524
+ }
525
+ };
526
+
527
+ // src/data-structures/base/iterable-entry-base.ts
528
+ var IterableEntryBase = class {
529
+ static {
530
+ __name(this, "IterableEntryBase");
531
+ }
532
+ /**
533
+ * Default iterator yielding `[key, value]` entries.
534
+ * @returns Iterator of `[K, V]`.
535
+ * @remarks Time O(n) to iterate, Space O(1)
536
+ */
537
+ *[Symbol.iterator](...args) {
538
+ yield* this._getIterator(...args);
539
+ }
540
+ /**
541
+ * Iterate over `[key, value]` pairs (may yield `undefined` values).
542
+ * @returns Iterator of `[K, V | undefined]`.
543
+ * @remarks Time O(n), Space O(1)
544
+ */
545
+ *entries() {
546
+ for (const item of this) {
547
+ yield item;
548
+ }
549
+ }
550
+ /**
551
+ * Iterate over keys only.
552
+ * @returns Iterator of keys.
553
+ * @remarks Time O(n), Space O(1)
554
+ */
555
+ *keys() {
556
+ for (const item of this) {
557
+ yield item[0];
558
+ }
559
+ }
560
+ /**
561
+ * Iterate over values only.
562
+ * @returns Iterator of values.
563
+ * @remarks Time O(n), Space O(1)
564
+ */
565
+ *values() {
566
+ for (const item of this) {
567
+ yield item[1];
568
+ }
569
+ }
570
+ /**
571
+ * Test whether all entries satisfy the predicate.
572
+ * @param predicate - `(key, value, index, self) => boolean`.
573
+ * @param thisArg - Optional `this` for callback.
574
+ * @returns `true` if all pass; otherwise `false`.
575
+ * @remarks Time O(n), Space O(1)
576
+ */
577
+ every(predicate, thisArg) {
578
+ let index = 0;
579
+ for (const item of this) {
580
+ if (!predicate.call(thisArg, item[1], item[0], index++, this)) {
581
+ return false;
582
+ }
583
+ }
584
+ return true;
585
+ }
586
+ /**
587
+ * Test whether any entry satisfies the predicate.
588
+ * @param predicate - `(key, value, index, self) => boolean`.
589
+ * @param thisArg - Optional `this` for callback.
590
+ * @returns `true` if any passes; otherwise `false`.
591
+ * @remarks Time O(n), Space O(1)
592
+ */
593
+ some(predicate, thisArg) {
594
+ let index = 0;
595
+ for (const item of this) {
596
+ if (predicate.call(thisArg, item[1], item[0], index++, this)) {
597
+ return true;
598
+ }
599
+ }
600
+ return false;
601
+ }
602
+ /**
603
+ * Visit each entry, left-to-right.
604
+ * @param callbackfn - `(key, value, index, self) => void`.
605
+ * @param thisArg - Optional `this` for callback.
606
+ * @remarks Time O(n), Space O(1)
607
+ */
608
+ forEach(callbackfn, thisArg) {
609
+ let index = 0;
610
+ for (const item of this) {
611
+ const [key, value] = item;
612
+ callbackfn.call(thisArg, value, key, index++, this);
613
+ }
614
+ }
615
+ /**
616
+ * Find the first entry that matches a predicate.
617
+ * @param callbackfn - `(key, value, index, self) => boolean`.
618
+ * @param thisArg - Optional `this` for callback.
619
+ * @returns Matching `[key, value]` or `undefined`.
620
+ * @remarks Time O(n), Space O(1)
621
+ */
622
+ find(callbackfn, thisArg) {
623
+ let index = 0;
624
+ for (const item of this) {
625
+ const [key, value] = item;
626
+ if (callbackfn.call(thisArg, value, key, index++, this)) return item;
627
+ }
628
+ return;
629
+ }
630
+ /**
631
+ * Whether the given key exists.
632
+ * @param key - Key to test.
633
+ * @returns `true` if found; otherwise `false`.
634
+ * @remarks Time O(n) generic, Space O(1)
635
+ */
636
+ has(key) {
637
+ for (const item of this) {
638
+ const [itemKey] = item;
639
+ if (itemKey === key) return true;
640
+ }
641
+ return false;
642
+ }
643
+ /**
644
+ * Whether there exists an entry with the given value.
645
+ * @param value - Value to test.
646
+ * @returns `true` if found; otherwise `false`.
647
+ * @remarks Time O(n), Space O(1)
648
+ */
649
+ hasValue(value) {
650
+ for (const [, elementValue] of this) {
651
+ if (elementValue === value) return true;
652
+ }
653
+ return false;
654
+ }
655
+ /**
656
+ * Get the value under a key.
657
+ * @param key - Key to look up.
658
+ * @returns Value or `undefined`.
659
+ * @remarks Time O(n) generic, Space O(1)
660
+ */
661
+ get(key) {
662
+ for (const item of this) {
663
+ const [itemKey, value] = item;
664
+ if (itemKey === key) return value;
665
+ }
666
+ return;
667
+ }
668
+ /**
669
+ * Reduce entries into a single accumulator.
670
+ * @param callbackfn - `(acc, value, key, index, self) => acc`.
671
+ * @param initialValue - Initial accumulator.
672
+ * @returns Final accumulator.
673
+ * @remarks Time O(n), Space O(1)
674
+ */
675
+ reduce(callbackfn, initialValue) {
676
+ let accumulator = initialValue;
677
+ let index = 0;
678
+ for (const item of this) {
679
+ const [key, value] = item;
680
+ accumulator = callbackfn(accumulator, value, key, index++, this);
681
+ }
682
+ return accumulator;
683
+ }
684
+ /**
685
+ * Converts data structure to `[key, value]` pairs.
686
+ * @returns Array of entries.
687
+ * @remarks Time O(n), Space O(n)
688
+ */
689
+ toArray() {
690
+ return [...this];
691
+ }
692
+ /**
693
+ * Visualize the iterable as an array of `[key, value]` pairs (or a custom string).
694
+ * @returns Array of entries (default) or a string.
695
+ * @remarks Time O(n), Space O(n)
696
+ */
697
+ toVisual() {
698
+ return [...this];
699
+ }
700
+ /**
701
+ * Print a human-friendly representation to the console.
702
+ * @remarks Time O(n), Space O(n)
703
+ */
704
+ print() {
705
+ console.log(this.toVisual());
706
+ }
707
+ };
708
+
478
709
  // src/data-structures/queue/queue.ts
479
710
  var Queue = class _Queue extends LinearBase {
480
711
  static {
@@ -532,18 +763,52 @@ var Queue = class _Queue extends LinearBase {
532
763
  this._autoCompactRatio = value;
533
764
  }
534
765
  /**
535
- * Get the number of elements currently in the queue.
536
- * @remarks Time O(1), Space O(1)
537
- * @returns Current length.
538
- */
766
+ * Get the number of elements currently in the queue.
767
+ * @remarks Time O(1), Space O(1)
768
+ * @returns Current length.
769
+
770
+
771
+
772
+
773
+
774
+
775
+
776
+
777
+
778
+
779
+
780
+ * @example
781
+ * // Track queue length
782
+ * const q = new Queue<number>();
783
+ * console.log(q.length); // 0;
784
+ * q.push(1);
785
+ * q.push(2);
786
+ * console.log(q.length); // 2;
787
+ */
539
788
  get length() {
540
789
  return this.elements.length - this._offset;
541
790
  }
542
791
  /**
543
- * Get the first element (front) without removing it.
544
- * @remarks Time O(1), Space O(1)
545
- * @returns Front element or undefined.
546
- */
792
+ * Get the first element (front) without removing it.
793
+ * @remarks Time O(1), Space O(1)
794
+ * @returns Front element or undefined.
795
+
796
+
797
+
798
+
799
+
800
+
801
+
802
+
803
+
804
+
805
+
806
+ * @example
807
+ * // View the front element
808
+ * const q = new Queue<string>(['first', 'second', 'third']);
809
+ * console.log(q.first); // 'first';
810
+ * console.log(q.length); // 3;
811
+ */
547
812
  get first() {
548
813
  return this.length > 0 ? this.elements[this._offset] : void 0;
549
814
  }
@@ -566,19 +831,69 @@ var Queue = class _Queue extends LinearBase {
566
831
  return new _Queue(elements);
567
832
  }
568
833
  /**
569
- * Check whether the queue is empty.
570
- * @remarks Time O(1), Space O(1)
571
- * @returns True if length is 0.
572
- */
834
+ * Check whether the queue is empty.
835
+ * @remarks Time O(1), Space O(1)
836
+ * @returns True if length is 0.
837
+
838
+
839
+
840
+
841
+
842
+
843
+
844
+
845
+
846
+
847
+
848
+ * @example
849
+ * // Queue for...of iteration and isEmpty check
850
+ * const queue = new Queue<string>(['A', 'B', 'C', 'D']);
851
+ *
852
+ * const elements: string[] = [];
853
+ * for (const item of queue) {
854
+ * elements.push(item);
855
+ * }
856
+ *
857
+ * // Verify all elements are iterated in order
858
+ * console.log(elements); // ['A', 'B', 'C', 'D'];
859
+ *
860
+ * // Process all elements
861
+ * while (queue.length > 0) {
862
+ * queue.shift();
863
+ * }
864
+ *
865
+ * console.log(queue.length); // 0;
866
+ */
573
867
  isEmpty() {
574
868
  return this.length === 0;
575
869
  }
576
870
  /**
577
- * Enqueue one element at the back.
578
- * @remarks Time O(1), Space O(1)
579
- * @param element - Element to enqueue.
580
- * @returns True on success.
581
- */
871
+ * Enqueue one element at the back.
872
+ * @remarks Time O(1), Space O(1)
873
+ * @param element - Element to enqueue.
874
+ * @returns True on success.
875
+
876
+
877
+
878
+
879
+
880
+
881
+
882
+
883
+
884
+
885
+
886
+ * @example
887
+ * // basic Queue creation and push operation
888
+ * // Create a simple Queue with initial values
889
+ * const queue = new Queue([1, 2, 3, 4, 5]);
890
+ *
891
+ * // Verify the queue maintains insertion order
892
+ * console.log([...queue]); // [1, 2, 3, 4, 5];
893
+ *
894
+ * // Check length
895
+ * console.log(queue.length); // 5;
896
+ */
582
897
  push(element) {
583
898
  this.elements.push(element);
584
899
  if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
@@ -599,10 +914,35 @@ var Queue = class _Queue extends LinearBase {
599
914
  return ans;
600
915
  }
601
916
  /**
602
- * Dequeue one element from the front (amortized via offset).
603
- * @remarks Time O(1) amortized, Space O(1)
604
- * @returns Removed element or undefined.
605
- */
917
+ * Dequeue one element from the front (amortized via offset).
918
+ * @remarks Time O(1) amortized, Space O(1)
919
+ * @returns Removed element or undefined.
920
+
921
+
922
+
923
+
924
+
925
+
926
+
927
+
928
+
929
+
930
+
931
+ * @example
932
+ * // Queue shift and peek operations
933
+ * const queue = new Queue<number>([10, 20, 30, 40]);
934
+ *
935
+ * // Peek at the front element without removing it
936
+ * console.log(queue.first); // 10;
937
+ *
938
+ * // Remove and get the first element (FIFO)
939
+ * const first = queue.shift();
940
+ * console.log(first); // 10;
941
+ *
942
+ * // Verify remaining elements and length decreased
943
+ * console.log([...queue]); // [20, 30, 40];
944
+ * console.log(queue.length); // 3;
945
+ */
606
946
  shift() {
607
947
  if (this.length === 0) return void 0;
608
948
  const first = this.first;
@@ -611,11 +951,24 @@ var Queue = class _Queue extends LinearBase {
611
951
  return first;
612
952
  }
613
953
  /**
614
- * Delete the first occurrence of a specific element.
615
- * @remarks Time O(N), Space O(1)
616
- * @param element - Element to remove (strict equality via Object.is).
617
- * @returns True if an element was removed.
618
- */
954
+ * Delete the first occurrence of a specific element.
955
+ * @remarks Time O(N), Space O(1)
956
+ * @param element - Element to remove (strict equality via Object.is).
957
+ * @returns True if an element was removed.
958
+
959
+
960
+
961
+
962
+
963
+
964
+
965
+
966
+ * @example
967
+ * // Remove specific element
968
+ * const q = new Queue<number>([1, 2, 3, 2]);
969
+ * q.delete(2);
970
+ * console.log(q.length); // 3;
971
+ */
619
972
  delete(element) {
620
973
  for (let i = this._offset; i < this.elements.length; i++) {
621
974
  if (Object.is(this.elements[i], element)) {
@@ -626,11 +979,24 @@ var Queue = class _Queue extends LinearBase {
626
979
  return false;
627
980
  }
628
981
  /**
629
- * Get the element at a given logical index.
630
- * @remarks Time O(1), Space O(1)
631
- * @param index - Zero-based index from the front.
632
- * @returns Element or undefined.
633
- */
982
+ * Get the element at a given logical index.
983
+ * @remarks Time O(1), Space O(1)
984
+ * @param index - Zero-based index from the front.
985
+ * @returns Element or undefined.
986
+
987
+
988
+
989
+
990
+
991
+
992
+
993
+
994
+ * @example
995
+ * // Access element by index
996
+ * const q = new Queue<string>(['a', 'b', 'c']);
997
+ * console.log(q.at(0)); // 'a';
998
+ * console.log(q.at(2)); // 'c';
999
+ */
634
1000
  at(index) {
635
1001
  if (index < 0 || index >= this.length) return void 0;
636
1002
  return this._elements[this._offset + index];
@@ -682,19 +1048,48 @@ var Queue = class _Queue extends LinearBase {
682
1048
  return this;
683
1049
  }
684
1050
  /**
685
- * Remove all elements and reset offset.
686
- * @remarks Time O(1), Space O(1)
687
- * @returns void
688
- */
1051
+ * Remove all elements and reset offset.
1052
+ * @remarks Time O(1), Space O(1)
1053
+ * @returns void
1054
+
1055
+
1056
+
1057
+
1058
+
1059
+
1060
+
1061
+
1062
+
1063
+ * @example
1064
+ * // Remove all elements
1065
+ * const q = new Queue<number>([1, 2, 3]);
1066
+ * q.clear();
1067
+ * console.log(q.length); // 0;
1068
+ */
689
1069
  clear() {
690
1070
  this._elements = [];
691
1071
  this._offset = 0;
692
1072
  }
693
1073
  /**
694
- * Compact storage by discarding consumed head elements.
695
- * @remarks Time O(N), Space O(N)
696
- * @returns True when compaction performed.
697
- */
1074
+ * Compact storage by discarding consumed head elements.
1075
+ * @remarks Time O(N), Space O(N)
1076
+ * @returns True when compaction performed.
1077
+
1078
+
1079
+
1080
+
1081
+
1082
+
1083
+
1084
+
1085
+ * @example
1086
+ * // Reclaim unused memory
1087
+ * const q = new Queue<number>([1, 2, 3, 4, 5]);
1088
+ * q.shift();
1089
+ * q.shift();
1090
+ * q.compact();
1091
+ * console.log(q.length); // 3;
1092
+ */
698
1093
  compact() {
699
1094
  this._elements = this.elements.slice(this._offset);
700
1095
  this._offset = 0;
@@ -720,332 +1115,169 @@ var Queue = class _Queue extends LinearBase {
720
1115
  return removed;
721
1116
  }
722
1117
  /**
723
- * Deep clone this queue and its parameters.
724
- * @remarks Time O(N), Space O(N)
725
- * @returns A new queue with the same content and options.
726
- */
1118
+ * Deep clone this queue and its parameters.
1119
+ * @remarks Time O(N), Space O(N)
1120
+ * @returns A new queue with the same content and options.
1121
+
1122
+
1123
+
1124
+
1125
+
1126
+
1127
+
1128
+
1129
+
1130
+ * @example
1131
+ * // Create independent copy
1132
+ * const q = new Queue<number>([1, 2, 3]);
1133
+ * const copy = q.clone();
1134
+ * copy.shift();
1135
+ * console.log(q.length); // 3;
1136
+ * console.log(copy.length); // 2;
1137
+ */
727
1138
  clone() {
728
1139
  const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
729
1140
  out._setAutoCompactRatio(this._autoCompactRatio);
730
1141
  for (let i = this._offset; i < this.elements.length; i++) out.push(this.elements[i]);
731
- return out;
732
- }
733
- /**
734
- * Filter elements into a new queue of the same class.
735
- * @remarks Time O(N), Space O(N)
736
- * @param predicate - Predicate (element, index, queue) → boolean to keep element.
737
- * @param [thisArg] - Value for `this` inside the predicate.
738
- * @returns A new queue with kept elements.
739
- */
740
- filter(predicate, thisArg) {
741
- const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
742
- out._setAutoCompactRatio(this._autoCompactRatio);
743
- let index = 0;
744
- for (const v of this) {
745
- if (predicate.call(thisArg, v, index, this)) out.push(v);
746
- index++;
747
- }
748
- return out;
749
- }
750
- /**
751
- * Map each element to a new element in a possibly different-typed queue.
752
- * @remarks Time O(N), Space O(N)
753
- * @template EM
754
- * @template RM
755
- * @param callback - Mapping function (element, index, queue) → newElement.
756
- * @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
757
- * @param [thisArg] - Value for `this` inside the callback.
758
- * @returns A new Queue with mapped elements.
759
- */
760
- map(callback, options, thisArg) {
761
- const out = new this.constructor([], {
762
- toElementFn: options?.toElementFn,
763
- maxLen: options?.maxLen ?? this._maxLen,
764
- autoCompactRatio: options?.autoCompactRatio ?? this._autoCompactRatio
765
- });
766
- let index = 0;
767
- for (const v of this)
768
- out.push(thisArg === void 0 ? callback(v, index++, this) : callback.call(thisArg, v, index++, this));
769
- return out;
770
- }
771
- /**
772
- * Map each element to a new value of the same type.
773
- * @remarks Time O(N), Space O(N)
774
- * @param callback - Mapping function (element, index, queue) → element.
775
- * @param [thisArg] - Value for `this` inside the callback.
776
- * @returns A new queue with mapped elements (same element type).
777
- */
778
- mapSame(callback, thisArg) {
779
- const Ctor = this.constructor;
780
- const out = new Ctor([], {
781
- toElementFn: this.toElementFn,
782
- maxLen: this._maxLen,
783
- autoCompactRatio: this._autoCompactRatio
784
- });
785
- out._setAutoCompactRatio?.(this._autoCompactRatio);
786
- let index = 0;
787
- for (const v of this) {
788
- const mv = thisArg === void 0 ? callback(v, index++, this) : callback.call(thisArg, v, index++, this);
789
- out.push(mv);
790
- }
791
- return out;
792
- }
793
- /**
794
- * (Protected) Set the internal auto-compaction ratio.
795
- * @remarks Time O(1), Space O(1)
796
- * @param value - New ratio to assign.
797
- * @returns void
798
- */
799
- _setAutoCompactRatio(value) {
800
- this._autoCompactRatio = value;
801
- }
802
- /**
803
- * (Protected) Iterate elements from front to back.
804
- * @remarks Time O(N), Space O(1)
805
- * @returns Iterator of E.
806
- */
807
- *_getIterator() {
808
- for (let i = this._offset; i < this.elements.length; i++) yield this.elements[i];
809
- }
810
- /**
811
- * (Protected) Iterate elements from back to front.
812
- * @remarks Time O(N), Space O(1)
813
- * @returns Iterator of E.
814
- */
815
- *_getReverseIterator() {
816
- for (let i = this.length - 1; i >= 0; i--) {
817
- const cur = this.at(i);
818
- if (cur !== void 0) yield cur;
819
- }
820
- }
821
- /**
822
- * (Protected) Create an empty instance of the same concrete class.
823
- * @remarks Time O(1), Space O(1)
824
- * @param [options] - Options forwarded to the constructor.
825
- * @returns An empty like-kind queue instance.
826
- */
827
- _createInstance(options) {
828
- const Ctor = this.constructor;
829
- return new Ctor([], options);
830
- }
831
- /**
832
- * (Protected) Create a like-kind queue and seed it from an iterable.
833
- * @remarks Time O(N), Space O(N)
834
- * @template EM
835
- * @template RM
836
- * @param [elements] - Iterable used to seed the new queue.
837
- * @param [options] - Options forwarded to the constructor.
838
- * @returns A like-kind Queue instance.
839
- */
840
- _createLike(elements = [], options) {
841
- const Ctor = this.constructor;
842
- return new Ctor(elements, options);
843
- }
844
- };
845
-
846
- // src/data-structures/base/iterable-entry-base.ts
847
- var IterableEntryBase = class {
848
- static {
849
- __name(this, "IterableEntryBase");
850
- }
851
- /**
852
- * Default iterator yielding `[key, value]` entries.
853
- * @returns Iterator of `[K, V]`.
854
- * @remarks Time O(n) to iterate, Space O(1)
855
- */
856
- *[Symbol.iterator](...args) {
857
- yield* this._getIterator(...args);
858
- }
859
- /**
860
- * Iterate over `[key, value]` pairs (may yield `undefined` values).
861
- * @returns Iterator of `[K, V | undefined]`.
862
- * @remarks Time O(n), Space O(1)
863
- */
864
- *entries() {
865
- for (const item of this) {
866
- yield item;
867
- }
868
- }
869
- /**
870
- * Iterate over keys only.
871
- * @returns Iterator of keys.
872
- * @remarks Time O(n), Space O(1)
873
- */
874
- *keys() {
875
- for (const item of this) {
876
- yield item[0];
877
- }
878
- }
879
- /**
880
- * Iterate over values only.
881
- * @returns Iterator of values.
882
- * @remarks Time O(n), Space O(1)
883
- */
884
- *values() {
885
- for (const item of this) {
886
- yield item[1];
887
- }
888
- }
889
- /**
890
- * Test whether all entries satisfy the predicate.
891
- * @param predicate - `(key, value, index, self) => boolean`.
892
- * @param thisArg - Optional `this` for callback.
893
- * @returns `true` if all pass; otherwise `false`.
894
- * @remarks Time O(n), Space O(1)
895
- */
896
- every(predicate, thisArg) {
897
- let index = 0;
898
- for (const item of this) {
899
- if (!predicate.call(thisArg, item[1], item[0], index++, this)) {
900
- return false;
901
- }
902
- }
903
- return true;
904
- }
905
- /**
906
- * Test whether any entry satisfies the predicate.
907
- * @param predicate - `(key, value, index, self) => boolean`.
908
- * @param thisArg - Optional `this` for callback.
909
- * @returns `true` if any passes; otherwise `false`.
910
- * @remarks Time O(n), Space O(1)
911
- */
912
- some(predicate, thisArg) {
913
- let index = 0;
914
- for (const item of this) {
915
- if (predicate.call(thisArg, item[1], item[0], index++, this)) {
916
- return true;
917
- }
918
- }
919
- return false;
920
- }
921
- /**
922
- * Visit each entry, left-to-right.
923
- * @param callbackfn - `(key, value, index, self) => void`.
924
- * @param thisArg - Optional `this` for callback.
925
- * @remarks Time O(n), Space O(1)
926
- */
927
- forEach(callbackfn, thisArg) {
928
- let index = 0;
929
- for (const item of this) {
930
- const [key, value] = item;
931
- callbackfn.call(thisArg, value, key, index++, this);
932
- }
1142
+ return out;
933
1143
  }
934
1144
  /**
935
- * Find the first entry that matches a predicate.
936
- * @param callbackfn - `(key, value, index, self) => boolean`.
937
- * @param thisArg - Optional `this` for callback.
938
- * @returns Matching `[key, value]` or `undefined`.
939
- * @remarks Time O(n), Space O(1)
940
- */
941
- find(callbackfn, thisArg) {
1145
+ * Filter elements into a new queue of the same class.
1146
+ * @remarks Time O(N), Space O(N)
1147
+ * @param predicate - Predicate (element, index, queue) → boolean to keep element.
1148
+ * @param [thisArg] - Value for `this` inside the predicate.
1149
+ * @returns A new queue with kept elements.
1150
+
1151
+
1152
+
1153
+
1154
+
1155
+
1156
+
1157
+
1158
+
1159
+ * @example
1160
+ * // Filter elements
1161
+ * const q = new Queue<number>([1, 2, 3, 4, 5]);
1162
+ * const evens = q.filter(x => x % 2 === 0);
1163
+ * console.log(evens.length); // 2;
1164
+ */
1165
+ filter(predicate, thisArg) {
1166
+ const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
1167
+ out._setAutoCompactRatio(this._autoCompactRatio);
942
1168
  let index = 0;
943
- for (const item of this) {
944
- const [key, value] = item;
945
- if (callbackfn.call(thisArg, value, key, index++, this)) return item;
1169
+ for (const v of this) {
1170
+ if (predicate.call(thisArg, v, index, this)) out.push(v);
1171
+ index++;
946
1172
  }
947
- return;
1173
+ return out;
948
1174
  }
949
1175
  /**
950
- * Whether the given key exists.
951
- * @param key - Key to test.
952
- * @returns `true` if found; otherwise `false`.
953
- * @remarks Time O(n) generic, Space O(1)
954
- */
955
- has(key) {
956
- for (const item of this) {
957
- const [itemKey] = item;
958
- if (itemKey === key) return true;
959
- }
960
- return false;
1176
+ * Map each element to a new element in a possibly different-typed queue.
1177
+ * @remarks Time O(N), Space O(N)
1178
+ * @template EM
1179
+ * @template RM
1180
+ * @param callback - Mapping function (element, index, queue) → newElement.
1181
+ * @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
1182
+ * @param [thisArg] - Value for `this` inside the callback.
1183
+ * @returns A new Queue with mapped elements.
1184
+
1185
+
1186
+
1187
+
1188
+
1189
+
1190
+
1191
+
1192
+ * @example
1193
+ * // Transform elements
1194
+ * const q = new Queue<number>([1, 2, 3]);
1195
+ * const doubled = q.map(x => x * 2);
1196
+ * console.log(doubled.toArray()); // [2, 4, 6];
1197
+ */
1198
+ map(callback, options, thisArg) {
1199
+ const out = new this.constructor([], {
1200
+ toElementFn: options?.toElementFn,
1201
+ maxLen: options?.maxLen ?? this._maxLen,
1202
+ autoCompactRatio: options?.autoCompactRatio ?? this._autoCompactRatio
1203
+ });
1204
+ let index = 0;
1205
+ for (const v of this)
1206
+ out.push(thisArg === void 0 ? callback(v, index++, this) : callback.call(thisArg, v, index++, this));
1207
+ return out;
961
1208
  }
962
1209
  /**
963
- * Whether there exists an entry with the given value.
964
- * @param value - Value to test.
965
- * @returns `true` if found; otherwise `false`.
966
- * @remarks Time O(n), Space O(1)
1210
+ * Map each element to a new value of the same type.
1211
+ * @remarks Time O(N), Space O(N)
1212
+ * @param callback - Mapping function (element, index, queue) → element.
1213
+ * @param [thisArg] - Value for `this` inside the callback.
1214
+ * @returns A new queue with mapped elements (same element type).
967
1215
  */
968
- hasValue(value) {
969
- for (const [, elementValue] of this) {
970
- if (elementValue === value) return true;
1216
+ mapSame(callback, thisArg) {
1217
+ const Ctor = this.constructor;
1218
+ const out = new Ctor([], {
1219
+ toElementFn: this.toElementFn,
1220
+ maxLen: this._maxLen,
1221
+ autoCompactRatio: this._autoCompactRatio
1222
+ });
1223
+ out._setAutoCompactRatio?.(this._autoCompactRatio);
1224
+ let index = 0;
1225
+ for (const v of this) {
1226
+ const mv = thisArg === void 0 ? callback(v, index++, this) : callback.call(thisArg, v, index++, this);
1227
+ out.push(mv);
971
1228
  }
972
- return false;
1229
+ return out;
973
1230
  }
974
1231
  /**
975
- * Get the value under a key.
976
- * @param key - Key to look up.
977
- * @returns Value or `undefined`.
978
- * @remarks Time O(n) generic, Space O(1)
1232
+ * (Protected) Set the internal auto-compaction ratio.
1233
+ * @remarks Time O(1), Space O(1)
1234
+ * @param value - New ratio to assign.
1235
+ * @returns void
979
1236
  */
980
- get(key) {
981
- for (const item of this) {
982
- const [itemKey, value] = item;
983
- if (itemKey === key) return value;
984
- }
985
- return;
1237
+ _setAutoCompactRatio(value) {
1238
+ this._autoCompactRatio = value;
986
1239
  }
987
1240
  /**
988
- * Reduce entries into a single accumulator.
989
- * @param callbackfn - `(acc, value, key, index, self) => acc`.
990
- * @param initialValue - Initial accumulator.
991
- * @returns Final accumulator.
992
- * @remarks Time O(n), Space O(1)
1241
+ * (Protected) Iterate elements from front to back.
1242
+ * @remarks Time O(N), Space O(1)
1243
+ * @returns Iterator of E.
993
1244
  */
994
- reduce(callbackfn, initialValue) {
995
- let accumulator = initialValue;
996
- let index = 0;
997
- for (const item of this) {
998
- const [key, value] = item;
999
- accumulator = callbackfn(accumulator, value, key, index++, this);
1000
- }
1001
- return accumulator;
1245
+ *_getIterator() {
1246
+ for (let i = this._offset; i < this.elements.length; i++) yield this.elements[i];
1002
1247
  }
1003
1248
  /**
1004
- * Converts data structure to `[key, value]` pairs.
1005
- * @returns Array of entries.
1006
- * @remarks Time O(n), Space O(n)
1249
+ * (Protected) Iterate elements from back to front.
1250
+ * @remarks Time O(N), Space O(1)
1251
+ * @returns Iterator of E.
1007
1252
  */
1008
- toArray() {
1009
- return [...this];
1253
+ *_getReverseIterator() {
1254
+ for (let i = this.length - 1; i >= 0; i--) {
1255
+ const cur = this.at(i);
1256
+ if (cur !== void 0) yield cur;
1257
+ }
1010
1258
  }
1011
1259
  /**
1012
- * Visualize the iterable as an array of `[key, value]` pairs (or a custom string).
1013
- * @returns Array of entries (default) or a string.
1014
- * @remarks Time O(n), Space O(n)
1260
+ * (Protected) Create an empty instance of the same concrete class.
1261
+ * @remarks Time O(1), Space O(1)
1262
+ * @param [options] - Options forwarded to the constructor.
1263
+ * @returns An empty like-kind queue instance.
1015
1264
  */
1016
- toVisual() {
1017
- return [...this];
1265
+ _createInstance(options) {
1266
+ const Ctor = this.constructor;
1267
+ return new Ctor([], options);
1018
1268
  }
1019
1269
  /**
1020
- * Print a human-friendly representation to the console.
1021
- * @remarks Time O(n), Space O(n)
1270
+ * (Protected) Create a like-kind queue and seed it from an iterable.
1271
+ * @remarks Time O(N), Space O(N)
1272
+ * @template EM
1273
+ * @template RM
1274
+ * @param [elements] - Iterable used to seed the new queue.
1275
+ * @param [options] - Options forwarded to the constructor.
1276
+ * @returns A like-kind Queue instance.
1022
1277
  */
1023
- print() {
1024
- console.log(this.toVisual());
1025
- }
1026
- };
1027
-
1028
- // src/common/index.ts
1029
- var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
1030
- DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
1031
- DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
1032
- return DFSOperation2;
1033
- })(DFSOperation || {});
1034
- var Range = class {
1035
- constructor(low, high, includeLow = true, includeHigh = true) {
1036
- this.low = low;
1037
- this.high = high;
1038
- this.includeLow = includeLow;
1039
- this.includeHigh = includeHigh;
1040
- }
1041
- static {
1042
- __name(this, "Range");
1043
- }
1044
- // Determine whether a key is within the range
1045
- isInRange(key, comparator) {
1046
- const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
1047
- const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
1048
- return lowCheck && highCheck;
1278
+ _createLike(elements = [], options) {
1279
+ const Ctor = this.constructor;
1280
+ return new Ctor(elements, options);
1049
1281
  }
1050
1282
  };
1051
1283
 
@@ -1187,7 +1419,7 @@ var BinaryTreeNode = class {
1187
1419
  return "MAL_NODE";
1188
1420
  }
1189
1421
  };
1190
- var BinaryTree = class extends IterableEntryBase {
1422
+ var BinaryTree = class _BinaryTree extends IterableEntryBase {
1191
1423
  static {
1192
1424
  __name(this, "BinaryTree");
1193
1425
  }
@@ -1207,7 +1439,7 @@ var BinaryTree = class extends IterableEntryBase {
1207
1439
  if (isMapMode !== void 0) this._isMapMode = isMapMode;
1208
1440
  if (isDuplicate !== void 0) this._isDuplicate = isDuplicate;
1209
1441
  if (typeof toEntryFn === "function") this._toEntryFn = toEntryFn;
1210
- else if (toEntryFn) throw TypeError("toEntryFn must be a function type");
1442
+ else if (toEntryFn) throw new TypeError(ERR.notAFunction("toEntryFn", "BinaryTree"));
1211
1443
  }
1212
1444
  if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
1213
1445
  }
@@ -1422,30 +1654,78 @@ var BinaryTree = class extends IterableEntryBase {
1422
1654
  return isComparable(key);
1423
1655
  }
1424
1656
  /**
1425
- * Adds a new node to the tree.
1426
- * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation adds the node at the first available position in a level-order (BFS) traversal. This is NOT a Binary Search Tree insertion. Time O(N), where N is the number of nodes. It must traverse level-by-level to find an empty slot. Space O(N) in the worst case for the BFS queue (e.g., a full last level).
1427
- *
1428
- * @param keyNodeOrEntry - The key, node, or entry to add.
1429
- * @returns True if the addition was successful, false otherwise.
1430
- */
1657
+ * Adds a new node to the tree.
1658
+ * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation adds the node at the first available position in a level-order (BFS) traversal. This is NOT a Binary Search Tree insertion. Time O(N), where N is the number of nodes. It must traverse level-by-level to find an empty slot. Space O(N) in the worst case for the BFS queue (e.g., a full last level).
1659
+ *
1660
+ * @param keyNodeOrEntry - The key, node, or entry to add.
1661
+ * @returns True if the addition was successful, false otherwise.
1662
+
1663
+
1664
+
1665
+
1666
+
1667
+
1668
+ * @example
1669
+ * // Add a single node
1670
+ * const tree = new BinaryTree<number>();
1671
+ * tree.add(1);
1672
+ * tree.add(2);
1673
+ * tree.add(3);
1674
+ * console.log(tree.size); // 3;
1675
+ * console.log(tree.has(1)); // true;
1676
+ */
1431
1677
  add(keyNodeOrEntry) {
1432
1678
  return this.set(keyNodeOrEntry);
1433
1679
  }
1434
1680
  /**
1435
- * Adds or updates a new node to the tree.
1436
- * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation sets the node at the first available position in a level-order (BFS) traversal. This is NOT a Binary Search Tree insertion. Time O(N), where N is the number of nodes. It must traverse level-by-level to find an empty slot. Space O(N) in the worst case for the BFS queue (e.g., a full last level).
1437
- *
1438
- * @param keyNodeOrEntry - The key, node, or entry to set or update.
1439
- * @param [value] - The value, if providing just a key.
1440
- * @returns True if the addition was successful, false otherwise.
1441
- */
1681
+ * Adds or updates a new node to the tree.
1682
+ * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation sets the node at the first available position in a level-order (BFS) traversal. This is NOT a Binary Search Tree insertion. Time O(N), where N is the number of nodes. It must traverse level-by-level to find an empty slot. Space O(N) in the worst case for the BFS queue (e.g., a full last level).
1683
+ *
1684
+ * @param keyNodeOrEntry - The key, node, or entry to set or update.
1685
+ * @param [value] - The value, if providing just a key.
1686
+ * @returns True if the addition was successful, false otherwise.
1687
+
1688
+
1689
+
1690
+
1691
+
1692
+
1693
+
1694
+
1695
+
1696
+
1697
+
1698
+ * @example
1699
+ * // basic BinaryTree creation and insertion
1700
+ * // Create a BinaryTree with entries
1701
+ * const entries: [number, string][] = [
1702
+ * [6, 'six'],
1703
+ * [1, 'one'],
1704
+ * [2, 'two'],
1705
+ * [7, 'seven'],
1706
+ * [5, 'five'],
1707
+ * [3, 'three'],
1708
+ * [4, 'four'],
1709
+ * [9, 'nine'],
1710
+ * [8, 'eight']
1711
+ * ];
1712
+ *
1713
+ * const tree = new BinaryTree(entries);
1714
+ *
1715
+ * // Verify size
1716
+ * console.log(tree.size); // 9;
1717
+ *
1718
+ * // Add new element
1719
+ * tree.set(10, 'ten');
1720
+ * console.log(tree.size); // 10;
1721
+ */
1442
1722
  set(keyNodeOrEntry, value) {
1443
1723
  const [newNode] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
1444
1724
  if (newNode === void 0) return false;
1445
1725
  if (!this._root) {
1446
1726
  this._setRoot(newNode);
1447
1727
  if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
1448
- this._size = 1;
1728
+ if (newNode !== null) this._size = 1;
1449
1729
  return true;
1450
1730
  }
1451
1731
  const queue = new Queue([this._root]);
@@ -1477,29 +1757,50 @@ var BinaryTree = class extends IterableEntryBase {
1477
1757
  potentialParent.right = newNode;
1478
1758
  }
1479
1759
  if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
1480
- this._size++;
1760
+ if (newNode !== null) this._size++;
1481
1761
  return true;
1482
1762
  }
1483
1763
  return false;
1484
1764
  }
1485
1765
  /**
1486
- * Adds multiple items to the tree.
1487
- * @remarks Time O(N * M), where N is the number of items to set and M is the size of the tree at insertion (due to O(M) `set` operation). Space O(M) (from `set`) + O(N) (for the `inserted` array).
1488
- *
1489
- * @param keysNodesEntriesOrRaws - An iterable of items to set.
1490
- * @returns An array of booleans indicating the success of each individual `set` operation.
1491
- */
1766
+ * Adds multiple items to the tree.
1767
+ * @remarks Time O(N * M), where N is the number of items to set and M is the size of the tree at insertion (due to O(M) `set` operation). Space O(M) (from `set`) + O(N) (for the `inserted` array).
1768
+ *
1769
+ * @param keysNodesEntriesOrRaws - An iterable of items to set.
1770
+ * @returns An array of booleans indicating the success of each individual `set` operation.
1771
+
1772
+
1773
+
1774
+
1775
+
1776
+
1777
+
1778
+
1779
+
1780
+ * @example
1781
+ * // Bulk add
1782
+ * const tree = new BinaryTree<number>();
1783
+ * tree.addMany([1, 2, 3, 4, 5]);
1784
+ * console.log(tree.size); // 5;
1785
+ */
1492
1786
  addMany(keysNodesEntriesOrRaws) {
1493
1787
  return this.setMany(keysNodesEntriesOrRaws);
1494
1788
  }
1495
1789
  /**
1496
- * Adds or updates multiple items to the tree.
1497
- * @remarks Time O(N * M), where N is the number of items to set and M is the size of the tree at insertion (due to O(M) `set` operation). Space O(M) (from `set`) + O(N) (for the `inserted` array).
1498
- *
1499
- * @param keysNodesEntriesOrRaws - An iterable of items to set or update.
1500
- * @param [values] - An optional parallel iterable of values.
1501
- * @returns An array of booleans indicating the success of each individual `set` operation.
1502
- */
1790
+ * Adds or updates multiple items to the tree.
1791
+ * @remarks Time O(N * M), where N is the number of items to set and M is the size of the tree at insertion (due to O(M) `set` operation). Space O(M) (from `set`) + O(N) (for the `inserted` array).
1792
+ *
1793
+ * @param keysNodesEntriesOrRaws - An iterable of items to set or update.
1794
+ * @param [values] - An optional parallel iterable of values.
1795
+ * @returns An array of booleans indicating the success of each individual `set` operation.
1796
+
1797
+
1798
+ * @example
1799
+ * // Set multiple entries
1800
+ * const tree = new BinaryTree<number, string>();
1801
+ * tree.setMany([[1, 'a'], [2, 'b'], [3, 'c']]);
1802
+ * console.log(tree.size); // 3;
1803
+ */
1503
1804
  setMany(keysNodesEntriesOrRaws, values) {
1504
1805
  const inserted = [];
1505
1806
  let valuesIterator;
@@ -1520,11 +1821,26 @@ var BinaryTree = class extends IterableEntryBase {
1520
1821
  return inserted;
1521
1822
  }
1522
1823
  /**
1523
- * Merges another tree into this one by seting all its nodes.
1524
- * @remarks Time O(N * M), same as `setMany`, where N is the size of `anotherTree` and M is the size of this tree. Space O(M) (from `set`).
1525
- *
1526
- * @param anotherTree - The tree to merge.
1527
- */
1824
+ * Merges another tree into this one by seting all its nodes.
1825
+ * @remarks Time O(N * M), same as `setMany`, where N is the size of `anotherTree` and M is the size of this tree. Space O(M) (from `set`).
1826
+ *
1827
+ * @param anotherTree - The tree to merge.
1828
+
1829
+
1830
+
1831
+
1832
+
1833
+
1834
+
1835
+
1836
+
1837
+ * @example
1838
+ * // Combine trees
1839
+ * const t1 = new BinaryTree<number>([1, 2]);
1840
+ * const t2 = new BinaryTree<number>([3, 4]);
1841
+ * t1.merge(t2);
1842
+ * console.log(t1.size); // 4;
1843
+ */
1528
1844
  merge(anotherTree) {
1529
1845
  this.setMany(anotherTree, []);
1530
1846
  }
@@ -1540,12 +1856,29 @@ var BinaryTree = class extends IterableEntryBase {
1540
1856
  this.setMany(keysNodesEntriesOrRaws, values);
1541
1857
  }
1542
1858
  /**
1543
- * Deletes a node from the tree.
1544
- * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation finds the node, and if it has two children, swaps it with the rightmost node of its left subtree (in-order predecessor) before deleting. Time O(N) in the worst case. O(N) to find the node (`getNode`) and O(H) (which is O(N) worst-case) to find the rightmost node. Space O(1) (if `getNode` is iterative, which it is).
1545
- *
1546
- * @param keyNodeEntryRawOrPredicate - The node to delete.
1547
- * @returns An array containing deletion results (for compatibility with self-balancing trees).
1548
- */
1859
+ * Deletes a node from the tree.
1860
+ * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation finds the node, and if it has two children, swaps it with the rightmost node of its left subtree (in-order predecessor) before deleting. Time O(N) in the worst case. O(N) to find the node (`getNode`) and O(H) (which is O(N) worst-case) to find the rightmost node. Space O(1) (if `getNode` is iterative, which it is).
1861
+ *
1862
+ * @param keyNodeEntryRawOrPredicate - The node to delete.
1863
+ * @returns An array containing deletion results (for compatibility with self-balancing trees).
1864
+
1865
+
1866
+
1867
+
1868
+
1869
+
1870
+
1871
+
1872
+
1873
+
1874
+
1875
+ * @example
1876
+ * // Remove a node
1877
+ * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
1878
+ * tree.delete(3);
1879
+ * console.log(tree.has(3)); // false;
1880
+ * console.log(tree.size); // 4;
1881
+ */
1549
1882
  delete(keyNodeEntryRawOrPredicate) {
1550
1883
  const deletedResult = [];
1551
1884
  if (!this._root) return deletedResult;
@@ -1639,14 +1972,27 @@ var BinaryTree = class extends IterableEntryBase {
1639
1972
  return this.search(keyNodeEntryOrPredicate, onlyOne, (node) => node, startNode, iterationType);
1640
1973
  }
1641
1974
  /**
1642
- * Gets the first node matching a predicate.
1643
- * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). Time O(N) in the worst case (via `search`). Space O(H) or O(N) (via `search`).
1644
- *
1645
- * @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
1646
- * @param [startNode=this._root] - The node to start the search from.
1647
- * @param [iterationType=this.iterationType] - The traversal method.
1648
- * @returns The first matching node, or undefined if not found.
1649
- */
1975
+ * Gets the first node matching a predicate.
1976
+ * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). Time O(N) in the worst case (via `search`). Space O(H) or O(N) (via `search`).
1977
+ *
1978
+ * @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
1979
+ * @param [startNode=this._root] - The node to start the search from.
1980
+ * @param [iterationType=this.iterationType] - The traversal method.
1981
+ * @returns The first matching node, or undefined if not found.
1982
+
1983
+
1984
+
1985
+
1986
+
1987
+
1988
+
1989
+
1990
+
1991
+ * @example
1992
+ * // Get node by key
1993
+ * const tree = new BinaryTree<number, string>([[1, 'root'], [2, 'child']]);
1994
+ * console.log(tree.getNode(2)?.value); // 'child';
1995
+ */
1650
1996
  getNode(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
1651
1997
  if (this._isMapMode && keyNodeEntryOrPredicate !== null && keyNodeEntryOrPredicate !== void 0) {
1652
1998
  if (!this._isPredicate(keyNodeEntryOrPredicate)) {
@@ -1658,14 +2004,30 @@ var BinaryTree = class extends IterableEntryBase {
1658
2004
  return this.search(keyNodeEntryOrPredicate, true, (node) => node, startNode, iterationType)[0];
1659
2005
  }
1660
2006
  /**
1661
- * Gets the value associated with a key.
1662
- * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). Time O(1) if in Map mode. O(N) if not in Map mode (uses `getNode`). Space O(1) if in Map mode. O(H) or O(N) otherwise.
1663
- *
1664
- * @param keyNodeEntryOrPredicate - The key, node, or entry to get the value for.
1665
- * @param [startNode=this._root] - The node to start searching from (if not in Map mode).
1666
- * @param [iterationType=this.iterationType] - The traversal method (if not in Map mode).
1667
- * @returns The associated value, or undefined.
1668
- */
2007
+ * Gets the value associated with a key.
2008
+ * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). Time O(1) if in Map mode. O(N) if not in Map mode (uses `getNode`). Space O(1) if in Map mode. O(H) or O(N) otherwise.
2009
+ *
2010
+ * @param keyNodeEntryOrPredicate - The key, node, or entry to get the value for.
2011
+ * @param [startNode=this._root] - The node to start searching from (if not in Map mode).
2012
+ * @param [iterationType=this.iterationType] - The traversal method (if not in Map mode).
2013
+ * @returns The associated value, or undefined.
2014
+
2015
+
2016
+
2017
+
2018
+
2019
+
2020
+
2021
+
2022
+
2023
+
2024
+
2025
+ * @example
2026
+ * // Retrieve value by key
2027
+ * const tree = new BinaryTree<number, string>([[1, 'root'], [2, 'left'], [3, 'right']]);
2028
+ * console.log(tree.get(2)); // 'left';
2029
+ * console.log(tree.get(99)); // undefined;
2030
+ */
1669
2031
  get(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
1670
2032
  if (this._isMapMode) {
1671
2033
  const key = this._extractKey(keyNodeEntryOrPredicate);
@@ -1685,19 +2047,45 @@ var BinaryTree = class extends IterableEntryBase {
1685
2047
  return this.search(keyNodeEntryOrPredicate, true, (node) => node, startNode, iterationType).length > 0;
1686
2048
  }
1687
2049
  /**
1688
- * Clears the tree of all nodes and values.
1689
- * @remarks Time O(N) if in Map mode (due to `_store.clear()`), O(1) otherwise. Space O(1)
1690
- */
2050
+ * Clears the tree of all nodes and values.
2051
+ * @remarks Time O(N) if in Map mode (due to `_store.clear()`), O(1) otherwise. Space O(1)
2052
+
2053
+
2054
+
2055
+
2056
+
2057
+
2058
+
2059
+
2060
+
2061
+ * @example
2062
+ * // Remove all nodes
2063
+ * const tree = new BinaryTree<number>([1, 2, 3]);
2064
+ * tree.clear();
2065
+ * console.log(tree.isEmpty()); // true;
2066
+ */
1691
2067
  clear() {
1692
2068
  this._clearNodes();
1693
2069
  if (this._isMapMode) this._clearValues();
1694
2070
  }
1695
2071
  /**
1696
- * Checks if the tree is empty.
1697
- * @remarks Time O(1), Space O(1)
1698
- *
1699
- * @returns True if the tree has no nodes, false otherwise.
1700
- */
2072
+ * Checks if the tree is empty.
2073
+ * @remarks Time O(1), Space O(1)
2074
+ *
2075
+ * @returns True if the tree has no nodes, false otherwise.
2076
+
2077
+
2078
+
2079
+
2080
+
2081
+
2082
+
2083
+
2084
+
2085
+ * @example
2086
+ * // Check empty
2087
+ * console.log(new BinaryTree().isEmpty()); // true;
2088
+ */
1701
2089
  isEmpty() {
1702
2090
  return this._size === 0;
1703
2091
  }
@@ -1712,13 +2100,27 @@ var BinaryTree = class extends IterableEntryBase {
1712
2100
  return this.getMinHeight(startNode) + 1 >= this.getHeight(startNode);
1713
2101
  }
1714
2102
  /**
1715
- * Checks if the tree is a valid Binary Search Tree (BST).
1716
- * @remarks Time O(N), as it must visit every node. Space O(H) for the call stack (recursive) or explicit stack (iterative), where H is the tree height (O(N) worst-case).
1717
- *
1718
- * @param [startNode=this._root] - The node to start checking from.
1719
- * @param [iterationType=this.iterationType] - The traversal method.
1720
- * @returns True if it's a valid BST, false otherwise.
1721
- */
2103
+ * Checks if the tree is a valid Binary Search Tree (BST).
2104
+ * @remarks Time O(N), as it must visit every node. Space O(H) for the call stack (recursive) or explicit stack (iterative), where H is the tree height (O(N) worst-case).
2105
+ *
2106
+ * @param [startNode=this._root] - The node to start checking from.
2107
+ * @param [iterationType=this.iterationType] - The traversal method.
2108
+ * @returns True if it's a valid BST, false otherwise.
2109
+
2110
+
2111
+
2112
+
2113
+
2114
+
2115
+
2116
+
2117
+
2118
+ * @example
2119
+ * // Check BST property
2120
+ * const tree = new BinaryTree<number>([1, 2, 3]);
2121
+ * // BinaryTree doesn't guarantee BST order
2122
+ * console.log(typeof tree.isBST()); // 'boolean';
2123
+ */
1722
2124
  isBST(startNode = this._root, iterationType = this.iterationType) {
1723
2125
  const startNodeSired = this.ensureNode(startNode);
1724
2126
  if (!startNodeSired) return true;
@@ -1756,13 +2158,29 @@ var BinaryTree = class extends IterableEntryBase {
1756
2158
  }
1757
2159
  }
1758
2160
  /**
1759
- * Gets the depth of a node (distance from `startNode`).
1760
- * @remarks Time O(H), where H is the depth of the `dist` node relative to `startNode`. O(N) worst-case. Space O(1).
1761
- *
1762
- * @param dist - The node to find the depth of.
1763
- * @param [startNode=this._root] - The node to measure depth from (defaults to root).
1764
- * @returns The depth (0 if `dist` is `startNode`).
1765
- */
2161
+ * Gets the depth of a node (distance from `startNode`).
2162
+ * @remarks Time O(H), where H is the depth of the `dist` node relative to `startNode`. O(N) worst-case. Space O(1).
2163
+ *
2164
+ * @param dist - The node to find the depth of.
2165
+ * @param [startNode=this._root] - The node to measure depth from (defaults to root).
2166
+ * @returns The depth (0 if `dist` is `startNode`).
2167
+
2168
+
2169
+
2170
+
2171
+
2172
+
2173
+
2174
+
2175
+
2176
+
2177
+
2178
+ * @example
2179
+ * // Get depth of a node
2180
+ * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
2181
+ * const node = tree.getNode(4);
2182
+ * console.log(tree.getDepth(node!)); // 2;
2183
+ */
1766
2184
  getDepth(dist, startNode = this._root) {
1767
2185
  let distEnsured = this.ensureNode(dist);
1768
2186
  const beginRootEnsured = this.ensureNode(startNode);
@@ -1777,13 +2195,28 @@ var BinaryTree = class extends IterableEntryBase {
1777
2195
  return depth;
1778
2196
  }
1779
2197
  /**
1780
- * Gets the maximum height of the tree (longest path from startNode to a leaf).
1781
- * @remarks Time O(N), as it must visit every node. Space O(H) for recursive stack (O(N) worst-case) or O(N) for iterative stack (storing node + depth).
1782
- *
1783
- * @param [startNode=this._root] - The node to start measuring from.
1784
- * @param [iterationType=this.iterationType] - The traversal method.
1785
- * @returns The height ( -1 for an empty tree, 0 for a single-node tree).
1786
- */
2198
+ * Gets the maximum height of the tree (longest path from startNode to a leaf).
2199
+ * @remarks Time O(N), as it must visit every node. Space O(H) for recursive stack (O(N) worst-case) or O(N) for iterative stack (storing node + depth).
2200
+ *
2201
+ * @param [startNode=this._root] - The node to start measuring from.
2202
+ * @param [iterationType=this.iterationType] - The traversal method.
2203
+ * @returns The height ( -1 for an empty tree, 0 for a single-node tree).
2204
+
2205
+
2206
+
2207
+
2208
+
2209
+
2210
+
2211
+
2212
+
2213
+
2214
+
2215
+ * @example
2216
+ * // Get tree height
2217
+ * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
2218
+ * console.log(tree.getHeight()); // 2;
2219
+ */
1787
2220
  getHeight(startNode = this._root, iterationType = this.iterationType) {
1788
2221
  startNode = this.ensureNode(startNode);
1789
2222
  if (!this.isRealNode(startNode)) return -1;
@@ -2045,7 +2478,7 @@ var BinaryTree = class extends IterableEntryBase {
2045
2478
  }
2046
2479
  /**
2047
2480
  * Finds all leaf nodes in the tree.
2048
- * @remarks Time O(N), visits every node. Space O(H) for recursive stack or O(N) for iterative queue.
2481
+ * @remarks Time O(N), visits every node. Space O(H) for recursive or iterative stack.
2049
2482
  *
2050
2483
  * @template C - The type of the callback function.
2051
2484
  * @param [callback=this._DEFAULT_NODE_CALLBACK] - Function to call on each leaf node.
@@ -2068,15 +2501,15 @@ var BinaryTree = class extends IterableEntryBase {
2068
2501
  }, "dfs");
2069
2502
  dfs(startNode);
2070
2503
  } else {
2071
- const queue = new Queue([startNode]);
2072
- while (queue.length > 0) {
2073
- const cur = queue.shift();
2504
+ const stack = [startNode];
2505
+ while (stack.length > 0) {
2506
+ const cur = stack.pop();
2074
2507
  if (this.isRealNode(cur)) {
2075
2508
  if (this.isLeaf(cur)) {
2076
2509
  leaves.push(callback(cur));
2077
2510
  }
2078
- if (this.isRealNode(cur.left)) queue.push(cur.left);
2079
- if (this.isRealNode(cur.right)) queue.push(cur.right);
2511
+ if (this.isRealNode(cur.right)) stack.push(cur.right);
2512
+ if (this.isRealNode(cur.left)) stack.push(cur.left);
2080
2513
  }
2081
2514
  }
2082
2515
  }
@@ -2219,24 +2652,53 @@ var BinaryTree = class extends IterableEntryBase {
2219
2652
  return ans;
2220
2653
  }
2221
2654
  /**
2222
- * Clones the tree.
2223
- * @remarks Time O(N * M), where N is the number of nodes and M is the tree size during insertion (due to `bfs` + `set`, and `set` is O(M)). Space O(N) for the new tree and the BFS queue.
2224
- *
2225
- * @returns A new, cloned instance of the tree.
2226
- */
2655
+ * Clones the tree.
2656
+ * @remarks Time O(N * M), where N is the number of nodes and M is the tree size during insertion (due to `bfs` + `set`, and `set` is O(M)). Space O(N) for the new tree and the BFS queue.
2657
+ *
2658
+ * @returns A new, cloned instance of the tree.
2659
+
2660
+
2661
+
2662
+
2663
+
2664
+
2665
+
2666
+
2667
+
2668
+ * @example
2669
+ * // Deep copy
2670
+ * const tree = new BinaryTree<number>([1, 2, 3]);
2671
+ * const copy = tree.clone();
2672
+ * copy.delete(1);
2673
+ * console.log(tree.has(1)); // true;
2674
+ */
2227
2675
  clone() {
2228
2676
  const out = this._createInstance();
2229
2677
  this._clone(out);
2230
2678
  return out;
2231
2679
  }
2232
2680
  /**
2233
- * Creates a new tree containing only the entries that satisfy the predicate.
2234
- * @remarks Time O(N * M), where N is nodes in this tree, and M is size of the new tree during insertion (O(N) iteration + O(M) `set` for each item). Space O(N) for the new tree.
2235
- *
2236
- * @param predicate - A function to test each [key, value] pair.
2237
- * @param [thisArg] - `this` context for the predicate.
2238
- * @returns A new, filtered tree.
2239
- */
2681
+ * Creates a new tree containing only the entries that satisfy the predicate.
2682
+ * @remarks Time O(N * M), where N is nodes in this tree, and M is size of the new tree during insertion (O(N) iteration + O(M) `set` for each item). Space O(N) for the new tree.
2683
+ *
2684
+ * @param predicate - A function to test each [key, value] pair.
2685
+ * @param [thisArg] - `this` context for the predicate.
2686
+ * @returns A new, filtered tree.
2687
+
2688
+
2689
+
2690
+
2691
+
2692
+
2693
+
2694
+
2695
+
2696
+ * @example
2697
+ * // Filter nodes by condition
2698
+ * const tree = new BinaryTree<number>([1, 2, 3, 4]);
2699
+ * const result = tree.filter((_, key) => key > 2);
2700
+ * console.log(result.size); // 2;
2701
+ */
2240
2702
  filter(predicate, thisArg) {
2241
2703
  const out = this._createInstance();
2242
2704
  let i = 0;
@@ -2244,17 +2706,31 @@ var BinaryTree = class extends IterableEntryBase {
2244
2706
  return out;
2245
2707
  }
2246
2708
  /**
2247
- * Creates a new tree by mapping each [key, value] pair to a new entry.
2248
- * @remarks Time O(N * M), where N is nodes in this tree, and M is size of the new tree during insertion. Space O(N) for the new tree.
2249
- *
2250
- * @template MK - New key type.
2251
- * @template MV - New value type.
2252
- * @template MR - New raw type.
2253
- * @param cb - A function to map each [key, value] pair.
2254
- * @param [options] - Options for the new tree.
2255
- * @param [thisArg] - `this` context for the callback.
2256
- * @returns A new, mapped tree.
2257
- */
2709
+ * Creates a new tree by mapping each [key, value] pair to a new entry.
2710
+ * @remarks Time O(N * M), where N is nodes in this tree, and M is size of the new tree during insertion. Space O(N) for the new tree.
2711
+ *
2712
+ * @template MK - New key type.
2713
+ * @template MV - New value type.
2714
+ * @template MR - New raw type.
2715
+ * @param cb - A function to map each [key, value] pair.
2716
+ * @param [options] - Options for the new tree.
2717
+ * @param [thisArg] - `this` context for the callback.
2718
+ * @returns A new, mapped tree.
2719
+
2720
+
2721
+
2722
+
2723
+
2724
+
2725
+
2726
+
2727
+
2728
+ * @example
2729
+ * // Transform to new tree
2730
+ * const tree = new BinaryTree<number, number>([[1, 10], [2, 20]]);
2731
+ * const mapped = tree.map((v, key) => [key, (v ?? 0) + 1] as [number, number]);
2732
+ * console.log([...mapped.values()]); // contains 11;
2733
+ */
2258
2734
  map(cb, options, thisArg) {
2259
2735
  const out = this._createLike([], options);
2260
2736
  let i = 0;
@@ -2292,12 +2768,25 @@ var BinaryTree = class extends IterableEntryBase {
2292
2768
  return output;
2293
2769
  }
2294
2770
  /**
2295
- * Prints a visual representation of the tree to the console.
2296
- * @remarks Time O(N) (via `toVisual`). Space O(N*H) or O(N^2) (via `toVisual`).
2297
- *
2298
- * @param [options] - Options to control the output.
2299
- * @param [startNode=this._root] - The node to start printing from.
2300
- */
2771
+ * Prints a visual representation of the tree to the console.
2772
+ * @remarks Time O(N) (via `toVisual`). Space O(N*H) or O(N^2) (via `toVisual`).
2773
+ *
2774
+ * @param [options] - Options to control the output.
2775
+ * @param [startNode=this._root] - The node to start printing from.
2776
+
2777
+
2778
+
2779
+
2780
+
2781
+
2782
+
2783
+
2784
+
2785
+ * @example
2786
+ * // Display tree
2787
+ * const tree = new BinaryTree<number>([1, 2, 3]);
2788
+ * expect(() => tree.print()).not.toThrow();
2789
+ */
2301
2790
  print(options, startNode = this._root) {
2302
2791
  console.log(this.toVisual(startNode, options));
2303
2792
  }
@@ -2536,44 +3025,99 @@ var BinaryTree = class extends IterableEntryBase {
2536
3025
  * @returns Layout information for this subtree.
2537
3026
  */
2538
3027
  _displayAux(node, options) {
2539
- const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
2540
3028
  const emptyDisplayLayout = [["\u2500"], 1, 0, 0];
2541
- if (node === null && !isShowNull) {
2542
- return emptyDisplayLayout;
2543
- } else if (node === void 0 && !isShowUndefined) {
2544
- return emptyDisplayLayout;
2545
- } else if (this.isNIL(node) && !isShowRedBlackNIL) {
2546
- return emptyDisplayLayout;
2547
- } else if (node !== null && node !== void 0) {
2548
- const key = node.key, line = this.isNIL(node) ? "S" : String(key), width = line.length;
2549
- return _buildNodeDisplay(
2550
- line,
2551
- width,
2552
- this._displayAux(node.left, options),
2553
- this._displayAux(node.right, options)
2554
- );
2555
- } else {
2556
- const line = node === void 0 ? "U" : "N", width = line.length;
2557
- return _buildNodeDisplay(line, width, [[""], 1, 0, 0], [[""], 1, 0, 0]);
2558
- }
2559
- function _buildNodeDisplay(line, width, left, right) {
2560
- const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
2561
- const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
2562
- const firstLine = " ".repeat(Math.max(0, leftMiddle + 1)) + "_".repeat(Math.max(0, leftWidth - leftMiddle - 1)) + line + "_".repeat(Math.max(0, rightMiddle)) + " ".repeat(Math.max(0, rightWidth - rightMiddle));
2563
- const secondLine = (leftHeight > 0 ? " ".repeat(leftMiddle) + "/" + " ".repeat(leftWidth - leftMiddle - 1) : " ".repeat(leftWidth)) + " ".repeat(width) + (rightHeight > 0 ? " ".repeat(rightMiddle) + "\\" + " ".repeat(rightWidth - rightMiddle - 1) : " ".repeat(rightWidth));
2564
- const mergedLines = [firstLine, secondLine];
2565
- for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
2566
- const leftLine = i < leftHeight ? leftLines[i] : " ".repeat(leftWidth);
2567
- const rightLine = i < rightHeight ? rightLines[i] : " ".repeat(rightWidth);
2568
- mergedLines.push(leftLine + " ".repeat(width) + rightLine);
3029
+ const newFrame = /* @__PURE__ */ __name((n) => ({
3030
+ node: n,
3031
+ stage: 0,
3032
+ leftLayout: emptyDisplayLayout,
3033
+ rightLayout: emptyDisplayLayout
3034
+ }), "newFrame");
3035
+ const stack = [newFrame(node)];
3036
+ let result = emptyDisplayLayout;
3037
+ const setChildResult = /* @__PURE__ */ __name((layout) => {
3038
+ if (stack.length === 0) {
3039
+ result = layout;
3040
+ return;
3041
+ }
3042
+ const parent = stack[stack.length - 1];
3043
+ if (parent.stage === 1) parent.leftLayout = layout;
3044
+ else parent.rightLayout = layout;
3045
+ }, "setChildResult");
3046
+ while (stack.length > 0) {
3047
+ const frame = stack[stack.length - 1];
3048
+ const cur = frame.node;
3049
+ if (frame.stage === 0) {
3050
+ if (this._isDisplayLeaf(cur, options)) {
3051
+ stack.pop();
3052
+ const layout = this._resolveDisplayLeaf(cur, options, emptyDisplayLayout);
3053
+ setChildResult(layout);
3054
+ continue;
3055
+ }
3056
+ frame.stage = 1;
3057
+ stack.push(newFrame(cur.left));
3058
+ } else if (frame.stage === 1) {
3059
+ frame.stage = 2;
3060
+ stack.push(newFrame(cur.right));
3061
+ } else {
3062
+ stack.pop();
3063
+ const line = this.isNIL(cur) ? "S" : String(cur.key);
3064
+ const layout = _BinaryTree._buildNodeDisplay(line, line.length, frame.leftLayout, frame.rightLayout);
3065
+ setChildResult(layout);
2569
3066
  }
2570
- return [
2571
- mergedLines,
2572
- leftWidth + width + rightWidth,
2573
- Math.max(leftHeight, rightHeight) + 2,
2574
- leftWidth + Math.floor(width / 2)
2575
- ];
2576
3067
  }
3068
+ return result;
3069
+ }
3070
+ static _buildNodeDisplay(line, width, left, right) {
3071
+ const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
3072
+ const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
3073
+ const firstLine = " ".repeat(Math.max(0, leftMiddle + 1)) + "_".repeat(Math.max(0, leftWidth - leftMiddle - 1)) + line + "_".repeat(Math.max(0, rightMiddle)) + " ".repeat(Math.max(0, rightWidth - rightMiddle));
3074
+ const secondLine = (leftHeight > 0 ? " ".repeat(leftMiddle) + "/" + " ".repeat(leftWidth - leftMiddle - 1) : " ".repeat(leftWidth)) + " ".repeat(width) + (rightHeight > 0 ? " ".repeat(rightMiddle) + "\\" + " ".repeat(rightWidth - rightMiddle - 1) : " ".repeat(rightWidth));
3075
+ const mergedLines = [firstLine, secondLine];
3076
+ for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
3077
+ const leftLine = i < leftHeight ? leftLines[i] : " ".repeat(leftWidth);
3078
+ const rightLine = i < rightHeight ? rightLines[i] : " ".repeat(rightWidth);
3079
+ mergedLines.push(leftLine + " ".repeat(width) + rightLine);
3080
+ }
3081
+ return [
3082
+ mergedLines,
3083
+ leftWidth + width + rightWidth,
3084
+ Math.max(leftHeight, rightHeight) + 2,
3085
+ leftWidth + Math.floor(width / 2)
3086
+ ];
3087
+ }
3088
+ /**
3089
+ * Check if a node is a display leaf (empty, null, undefined, NIL, or real leaf).
3090
+ */
3091
+ _isDisplayLeaf(node, options) {
3092
+ const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
3093
+ if (node === null && !isShowNull) return true;
3094
+ if (node === void 0 && !isShowUndefined) return true;
3095
+ if (this.isNIL(node) && !isShowRedBlackNIL) return true;
3096
+ if (node === null || node === void 0) return true;
3097
+ const hasDisplayableLeft = this._hasDisplayableChild(node.left, options);
3098
+ const hasDisplayableRight = this._hasDisplayableChild(node.right, options);
3099
+ return !hasDisplayableLeft && !hasDisplayableRight;
3100
+ }
3101
+ _hasDisplayableChild(child, options) {
3102
+ if (child === null) return !!options.isShowNull;
3103
+ if (child === void 0) return !!options.isShowUndefined;
3104
+ if (this.isNIL(child)) return !!options.isShowRedBlackNIL;
3105
+ return true;
3106
+ }
3107
+ /**
3108
+ * Resolve a display leaf node to its layout.
3109
+ */
3110
+ _resolveDisplayLeaf(node, options, emptyDisplayLayout) {
3111
+ const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
3112
+ if (node === null && !isShowNull) return emptyDisplayLayout;
3113
+ if (node === void 0 && !isShowUndefined) return emptyDisplayLayout;
3114
+ if (this.isNIL(node) && !isShowRedBlackNIL) return emptyDisplayLayout;
3115
+ if (node !== null && node !== void 0) {
3116
+ const line2 = this.isNIL(node) ? "S" : String(node.key);
3117
+ return _BinaryTree._buildNodeDisplay(line2, line2.length, emptyDisplayLayout, emptyDisplayLayout);
3118
+ }
3119
+ const line = node === void 0 ? "U" : "N";
3120
+ return _BinaryTree._buildNodeDisplay(line, line.length, [[""], 1, 0, 0], [[""], 1, 0, 0]);
2577
3121
  }
2578
3122
  /**
2579
3123
  * (Protected) Swaps the key/value properties of two nodes.
@@ -2776,6 +3320,7 @@ var BSTNode = class {
2776
3320
  *
2777
3321
  * @returns The height.
2778
3322
  */
3323
+ /* istanbul ignore next -- covered by AVLTree/RedBlackTree tests (subclass uses height) */
2779
3324
  get height() {
2780
3325
  return this._height;
2781
3326
  }
@@ -2785,6 +3330,7 @@ var BSTNode = class {
2785
3330
  *
2786
3331
  * @param value - The new height.
2787
3332
  */
3333
+ /* istanbul ignore next -- covered by AVLTree/RedBlackTree tests (subclass uses height) */
2788
3334
  set height(value) {
2789
3335
  this._height = value;
2790
3336
  }
@@ -2795,6 +3341,7 @@ var BSTNode = class {
2795
3341
  *
2796
3342
  * @returns The node's color.
2797
3343
  */
3344
+ /* istanbul ignore next -- covered by RedBlackTree tests (subclass uses color) */
2798
3345
  get color() {
2799
3346
  return this._color;
2800
3347
  }
@@ -2804,6 +3351,7 @@ var BSTNode = class {
2804
3351
  *
2805
3352
  * @param value - The new color.
2806
3353
  */
3354
+ /* istanbul ignore next -- covered by RedBlackTree tests (subclass uses color) */
2807
3355
  set color(value) {
2808
3356
  this._color = value;
2809
3357
  }
@@ -2814,6 +3362,7 @@ var BSTNode = class {
2814
3362
  *
2815
3363
  * @returns The subtree node count.
2816
3364
  */
3365
+ /* istanbul ignore next -- internal field used by subclasses */
2817
3366
  get count() {
2818
3367
  return this._count;
2819
3368
  }
@@ -2823,6 +3372,7 @@ var BSTNode = class {
2823
3372
  *
2824
3373
  * @param value - The new count.
2825
3374
  */
3375
+ /* istanbul ignore next -- internal field used by subclasses */
2826
3376
  set count(value) {
2827
3377
  this._count = value;
2828
3378
  }
@@ -2977,14 +3527,39 @@ var BST = class extends BinaryTree {
2977
3527
  return super.listLevels(callback, startNode, iterationType, false);
2978
3528
  }
2979
3529
  /**
2980
- * Gets the first node matching a predicate.
2981
- * @remarks Time O(log N) if searching by key, O(N) if searching by predicate. Space O(log N) or O(N).
2982
- *
2983
- * @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
2984
- * @param [startNode=this._root] - The node to start the search from.
2985
- * @param [iterationType=this.iterationType] - The traversal method.
2986
- * @returns The first matching node, or undefined if not found.
2987
- */
3530
+ * Gets the first node matching a predicate.
3531
+ * @remarks Time O(log N) if searching by key, O(N) if searching by predicate. Space O(log N) or O(N).
3532
+ *
3533
+ * @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
3534
+ * @param [startNode=this._root] - The node to start the search from.
3535
+ * @param [iterationType=this.iterationType] - The traversal method.
3536
+ * @returns The first matching node, or undefined if not found.
3537
+
3538
+
3539
+
3540
+
3541
+
3542
+
3543
+
3544
+
3545
+
3546
+
3547
+
3548
+
3549
+
3550
+
3551
+
3552
+
3553
+
3554
+
3555
+
3556
+ * @example
3557
+ * // Get node object by key
3558
+ * const bst = new BST<number, string>([[5, 'root'], [3, 'left'], [7, 'right']]);
3559
+ * const node = bst.getNode(3);
3560
+ * console.log(node?.key); // 3;
3561
+ * console.log(node?.value); // 'left';
3562
+ */
2988
3563
  getNode(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
2989
3564
  if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === void 0) return void 0;
2990
3565
  if (this._isPredicate(keyNodeEntryOrPredicate)) {
@@ -3133,13 +3708,44 @@ var BST = class extends BinaryTree {
3133
3708
  return this.search(searchRange, false, callback, startNode, iterationType);
3134
3709
  }
3135
3710
  /**
3136
- * Adds a new node to the BST based on key comparison.
3137
- * @remarks Time O(log N), where H is tree height. O(N) worst-case (unbalanced tree), O(log N) average. Space O(1).
3138
- *
3139
- * @param keyNodeOrEntry - The key, node, or entry to set.
3140
- * @param [value] - The value, if providing just a key.
3141
- * @returns True if the addition was successful, false otherwise.
3142
- */
3711
+ * Adds a new node to the BST based on key comparison.
3712
+ * @remarks Time O(log N), where H is tree height. O(N) worst-case (unbalanced tree), O(log N) average. Space O(1).
3713
+ *
3714
+ * @param keyNodeOrEntry - The key, node, or entry to set.
3715
+ * @param [value] - The value, if providing just a key.
3716
+ * @returns True if the addition was successful, false otherwise.
3717
+
3718
+
3719
+
3720
+
3721
+
3722
+
3723
+
3724
+
3725
+
3726
+
3727
+
3728
+
3729
+
3730
+
3731
+
3732
+
3733
+
3734
+
3735
+
3736
+
3737
+
3738
+
3739
+
3740
+
3741
+
3742
+ * @example
3743
+ * // Set a key-value pair
3744
+ * const bst = new BST<number, string>();
3745
+ * bst.set(1, 'one');
3746
+ * bst.set(2, 'two');
3747
+ * console.log(bst.get(1)); // 'one';
3748
+ */
3143
3749
  set(keyNodeOrEntry, value) {
3144
3750
  const [newNode] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
3145
3751
  if (newNode === void 0) return false;
@@ -3176,17 +3782,34 @@ var BST = class extends BinaryTree {
3176
3782
  return false;
3177
3783
  }
3178
3784
  /**
3179
- * Adds multiple items to the tree.
3180
- * @remarks If `isBalanceAdd` is true, sorts the input and builds a balanced tree. Time O(N log N) (due to sort and balanced set).
3181
- * If false, adds items one by one. Time O(N * H), which is O(N^2) worst-case.
3182
- * Space O(N) for sorting and recursion/iteration stack.
3183
- *
3184
- * @param keysNodesEntriesOrRaws - An iterable of items to set.
3185
- * @param [values] - An optional parallel iterable of values.
3186
- * @param [isBalanceAdd=true] - If true, builds a balanced tree from the items.
3187
- * @param [iterationType=this.iterationType] - The traversal method for balanced set (recursive or iterative).
3188
- * @returns An array of booleans indicating the success of each individual `set` operation.
3189
- */
3785
+ * Adds multiple items to the tree.
3786
+ * @remarks If `isBalanceAdd` is true, sorts the input and builds a balanced tree. Time O(N log N) (due to sort and balanced set).
3787
+ * If false, adds items one by one. Time O(N * H), which is O(N^2) worst-case.
3788
+ * Space O(N) for sorting and recursion/iteration stack.
3789
+ *
3790
+ * @param keysNodesEntriesOrRaws - An iterable of items to set.
3791
+ * @param [values] - An optional parallel iterable of values.
3792
+ * @param [isBalanceAdd=true] - If true, builds a balanced tree from the items.
3793
+ * @param [iterationType=this.iterationType] - The traversal method for balanced set (recursive or iterative).
3794
+ * @returns An array of booleans indicating the success of each individual `set` operation.
3795
+
3796
+
3797
+
3798
+
3799
+
3800
+
3801
+
3802
+
3803
+
3804
+
3805
+
3806
+ * @example
3807
+ * // Set multiple key-value pairs
3808
+ * const bst = new BST<number, string>();
3809
+ * bst.setMany([[1, 'a'], [2, 'b'], [3, 'c']]);
3810
+ * console.log(bst.size); // 3;
3811
+ * console.log(bst.get(2)); // 'b';
3812
+ */
3190
3813
  setMany(keysNodesEntriesOrRaws, values, isBalanceAdd = true, iterationType = this.iterationType) {
3191
3814
  const inserted = [];
3192
3815
  const valuesIterator = values?.[Symbol.iterator]();
@@ -3429,12 +4052,29 @@ var BST = class extends BinaryTree {
3429
4052
  }
3430
4053
  }
3431
4054
  /**
3432
- * Rebuilds the tree to be perfectly balanced.
3433
- * @remarks Time O(N) (O(N) for DFS, O(N) for sorted build). Space O(N) for node array and recursion stack.
3434
- *
3435
- * @param [iterationType=this.iterationType] - The traversal method for the initial node export.
3436
- * @returns True if successful, false if the tree was empty.
3437
- */
4055
+ * Rebuilds the tree to be perfectly balanced.
4056
+ * @remarks Time O(N) (O(N) for DFS, O(N) for sorted build). Space O(N) for node array and recursion stack.
4057
+ *
4058
+ * @param [iterationType=this.iterationType] - The traversal method for the initial node export.
4059
+ * @returns True if successful, false if the tree was empty.
4060
+
4061
+
4062
+
4063
+
4064
+
4065
+
4066
+
4067
+
4068
+
4069
+ * @example
4070
+ * // Rebalance the tree
4071
+ * const bst = new BST<number>();
4072
+ * // Insert in sorted order (worst case for BST)
4073
+ * for (let i = 1; i <= 7; i++) bst.add(i);
4074
+ * console.log(bst.isAVLBalanced()); // false;
4075
+ * bst.perfectlyBalance();
4076
+ * console.log(bst.isAVLBalanced()); // true;
4077
+ */
3438
4078
  perfectlyBalance(iterationType = this.iterationType) {
3439
4079
  const nodes = this.dfs((node) => node, "IN", false, this._root, iterationType);
3440
4080
  const n = nodes.length;
@@ -3457,12 +4097,25 @@ var BST = class extends BinaryTree {
3457
4097
  return true;
3458
4098
  }
3459
4099
  /**
3460
- * Checks if the tree meets the AVL balance condition (height difference <= 1).
3461
- * @remarks Time O(N), as it must visit every node to compute height. Space O(log N) for recursion or O(N) for iterative map.
3462
- *
3463
- * @param [iterationType=this.iterationType] - The traversal method.
3464
- * @returns True if the tree is AVL balanced, false otherwise.
3465
- */
4100
+ * Checks if the tree meets the AVL balance condition (height difference <= 1).
4101
+ * @remarks Time O(N), as it must visit every node to compute height. Space O(log N) for recursion or O(N) for iterative map.
4102
+ *
4103
+ * @param [iterationType=this.iterationType] - The traversal method.
4104
+ * @returns True if the tree is AVL balanced, false otherwise.
4105
+
4106
+
4107
+
4108
+
4109
+
4110
+
4111
+
4112
+
4113
+
4114
+ * @example
4115
+ * // Check if tree is height-balanced
4116
+ * const bst = new BST<number>([3, 1, 5, 2, 4]);
4117
+ * console.log(bst.isAVLBalanced()); // true;
4118
+ */
3466
4119
  isAVLBalanced(iterationType = this.iterationType) {
3467
4120
  if (!this._root) return true;
3468
4121
  let balanced = true;
@@ -3502,18 +4155,42 @@ var BST = class extends BinaryTree {
3502
4155
  return balanced;
3503
4156
  }
3504
4157
  /**
3505
- * Creates a new BST by mapping each [key, value] pair to a new entry.
3506
- * @remarks Time O(N * H), where N is nodes in this tree, and H is height of the new tree during insertion.
3507
- * Space O(N) for the new tree.
3508
- *
3509
- * @template MK - New key type.
3510
- * @template MV - New value type.
3511
- * @template MR - New raw type.
3512
- * @param callback - A function to map each [key, value] pair.
3513
- * @param [options] - Options for the new BST.
3514
- * @param [thisArg] - `this` context for the callback.
3515
- * @returns A new, mapped BST.
3516
- */
4158
+ * Creates a new BST by mapping each [key, value] pair to a new entry.
4159
+ * @remarks Time O(N * H), where N is nodes in this tree, and H is height of the new tree during insertion.
4160
+ * Space O(N) for the new tree.
4161
+ *
4162
+ * @template MK - New key type.
4163
+ * @template MV - New value type.
4164
+ * @template MR - New raw type.
4165
+ * @param callback - A function to map each [key, value] pair.
4166
+ * @param [options] - Options for the new BST.
4167
+ * @param [thisArg] - `this` context for the callback.
4168
+ * @returns A new, mapped BST.
4169
+
4170
+
4171
+
4172
+
4173
+
4174
+
4175
+
4176
+
4177
+
4178
+
4179
+
4180
+
4181
+
4182
+
4183
+
4184
+
4185
+
4186
+
4187
+
4188
+ * @example
4189
+ * // Transform to new tree
4190
+ * const bst = new BST<number, number>([[1, 10], [2, 20], [3, 30]]);
4191
+ * const doubled = bst.map((value, key) => [key, (value ?? 0) * 2] as [number, number]);
4192
+ * console.log([...doubled.values()]); // [20, 40, 60];
4193
+ */
3517
4194
  map(callback, options, thisArg) {
3518
4195
  const out = this._createLike([], options);
3519
4196
  let index = 0;
@@ -3579,9 +4256,15 @@ var BST = class extends BinaryTree {
3579
4256
  if (a < b) return -1;
3580
4257
  return 0;
3581
4258
  }
4259
+ if (a instanceof Date && b instanceof Date) {
4260
+ const ta = a.getTime();
4261
+ const tb = b.getTime();
4262
+ if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate("BST"));
4263
+ return ta > tb ? 1 : ta < tb ? -1 : 0;
4264
+ }
3582
4265
  if (typeof a === "object" || typeof b === "object") {
3583
- throw TypeError(
3584
- `When comparing object type keys, a custom comparator must be provided in the constructor's options!`
4266
+ throw new TypeError(
4267
+ ERR.comparatorRequired("BST")
3585
4268
  );
3586
4269
  }
3587
4270
  return 0;
@@ -4001,6 +4684,7 @@ exports.BSTNode = BSTNode;
4001
4684
  exports.BinaryTree = BinaryTree;
4002
4685
  exports.BinaryTreeNode = BinaryTreeNode;
4003
4686
  exports.DFSOperation = DFSOperation;
4687
+ exports.ERR = ERR;
4004
4688
  exports.Range = Range;
4005
4689
  //# sourceMappingURL=index.cjs.map
4006
4690
  //# sourceMappingURL=index.cjs.map