binary-tree-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 -84
  2. package/dist/cjs/index.cjs +965 -420
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/cjs-legacy/index.cjs +962 -417
  5. package/dist/cjs-legacy/index.cjs.map +1 -1
  6. package/dist/esm/index.mjs +965 -421
  7. package/dist/esm/index.mjs.map +1 -1
  8. package/dist/esm-legacy/index.mjs +962 -418
  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/binary-tree-typed.js +959 -414
  46. package/dist/umd/binary-tree-typed.js.map +1 -1
  47. package/dist/umd/binary-tree-typed.min.js +3 -3
  48. package/dist/umd/binary-tree-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
@@ -473,6 +473,237 @@ var LinearBase = class _LinearBase extends IterableElementBase {
473
473
  }
474
474
  };
475
475
 
476
+ // src/common/error.ts
477
+ var ERR = {
478
+ // Range / index
479
+ indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
480
+ invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
481
+ // Type / argument
482
+ invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
483
+ comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
484
+ invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
485
+ notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
486
+ invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
487
+ invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
488
+ invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
489
+ reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
490
+ callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
491
+ // State / operation
492
+ invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
493
+ // Matrix
494
+ matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
495
+ matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
496
+ matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
497
+ matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
498
+ matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
499
+ };
500
+
501
+ // src/common/index.ts
502
+ var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
503
+ DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
504
+ DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
505
+ return DFSOperation2;
506
+ })(DFSOperation || {});
507
+ var Range = class {
508
+ constructor(low, high, includeLow = true, includeHigh = true) {
509
+ this.low = low;
510
+ this.high = high;
511
+ this.includeLow = includeLow;
512
+ this.includeHigh = includeHigh;
513
+ }
514
+ static {
515
+ __name(this, "Range");
516
+ }
517
+ // Determine whether a key is within the range
518
+ isInRange(key, comparator) {
519
+ const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
520
+ const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
521
+ return lowCheck && highCheck;
522
+ }
523
+ };
524
+
525
+ // src/data-structures/base/iterable-entry-base.ts
526
+ var IterableEntryBase = class {
527
+ static {
528
+ __name(this, "IterableEntryBase");
529
+ }
530
+ /**
531
+ * Default iterator yielding `[key, value]` entries.
532
+ * @returns Iterator of `[K, V]`.
533
+ * @remarks Time O(n) to iterate, Space O(1)
534
+ */
535
+ *[Symbol.iterator](...args) {
536
+ yield* this._getIterator(...args);
537
+ }
538
+ /**
539
+ * Iterate over `[key, value]` pairs (may yield `undefined` values).
540
+ * @returns Iterator of `[K, V | undefined]`.
541
+ * @remarks Time O(n), Space O(1)
542
+ */
543
+ *entries() {
544
+ for (const item of this) {
545
+ yield item;
546
+ }
547
+ }
548
+ /**
549
+ * Iterate over keys only.
550
+ * @returns Iterator of keys.
551
+ * @remarks Time O(n), Space O(1)
552
+ */
553
+ *keys() {
554
+ for (const item of this) {
555
+ yield item[0];
556
+ }
557
+ }
558
+ /**
559
+ * Iterate over values only.
560
+ * @returns Iterator of values.
561
+ * @remarks Time O(n), Space O(1)
562
+ */
563
+ *values() {
564
+ for (const item of this) {
565
+ yield item[1];
566
+ }
567
+ }
568
+ /**
569
+ * Test whether all entries satisfy the predicate.
570
+ * @param predicate - `(key, value, index, self) => boolean`.
571
+ * @param thisArg - Optional `this` for callback.
572
+ * @returns `true` if all pass; otherwise `false`.
573
+ * @remarks Time O(n), Space O(1)
574
+ */
575
+ every(predicate, thisArg) {
576
+ let index = 0;
577
+ for (const item of this) {
578
+ if (!predicate.call(thisArg, item[1], item[0], index++, this)) {
579
+ return false;
580
+ }
581
+ }
582
+ return true;
583
+ }
584
+ /**
585
+ * Test whether any entry satisfies the predicate.
586
+ * @param predicate - `(key, value, index, self) => boolean`.
587
+ * @param thisArg - Optional `this` for callback.
588
+ * @returns `true` if any passes; otherwise `false`.
589
+ * @remarks Time O(n), Space O(1)
590
+ */
591
+ some(predicate, thisArg) {
592
+ let index = 0;
593
+ for (const item of this) {
594
+ if (predicate.call(thisArg, item[1], item[0], index++, this)) {
595
+ return true;
596
+ }
597
+ }
598
+ return false;
599
+ }
600
+ /**
601
+ * Visit each entry, left-to-right.
602
+ * @param callbackfn - `(key, value, index, self) => void`.
603
+ * @param thisArg - Optional `this` for callback.
604
+ * @remarks Time O(n), Space O(1)
605
+ */
606
+ forEach(callbackfn, thisArg) {
607
+ let index = 0;
608
+ for (const item of this) {
609
+ const [key, value] = item;
610
+ callbackfn.call(thisArg, value, key, index++, this);
611
+ }
612
+ }
613
+ /**
614
+ * Find the first entry that matches a predicate.
615
+ * @param callbackfn - `(key, value, index, self) => boolean`.
616
+ * @param thisArg - Optional `this` for callback.
617
+ * @returns Matching `[key, value]` or `undefined`.
618
+ * @remarks Time O(n), Space O(1)
619
+ */
620
+ find(callbackfn, thisArg) {
621
+ let index = 0;
622
+ for (const item of this) {
623
+ const [key, value] = item;
624
+ if (callbackfn.call(thisArg, value, key, index++, this)) return item;
625
+ }
626
+ return;
627
+ }
628
+ /**
629
+ * Whether the given key exists.
630
+ * @param key - Key to test.
631
+ * @returns `true` if found; otherwise `false`.
632
+ * @remarks Time O(n) generic, Space O(1)
633
+ */
634
+ has(key) {
635
+ for (const item of this) {
636
+ const [itemKey] = item;
637
+ if (itemKey === key) return true;
638
+ }
639
+ return false;
640
+ }
641
+ /**
642
+ * Whether there exists an entry with the given value.
643
+ * @param value - Value to test.
644
+ * @returns `true` if found; otherwise `false`.
645
+ * @remarks Time O(n), Space O(1)
646
+ */
647
+ hasValue(value) {
648
+ for (const [, elementValue] of this) {
649
+ if (elementValue === value) return true;
650
+ }
651
+ return false;
652
+ }
653
+ /**
654
+ * Get the value under a key.
655
+ * @param key - Key to look up.
656
+ * @returns Value or `undefined`.
657
+ * @remarks Time O(n) generic, Space O(1)
658
+ */
659
+ get(key) {
660
+ for (const item of this) {
661
+ const [itemKey, value] = item;
662
+ if (itemKey === key) return value;
663
+ }
664
+ return;
665
+ }
666
+ /**
667
+ * Reduce entries into a single accumulator.
668
+ * @param callbackfn - `(acc, value, key, index, self) => acc`.
669
+ * @param initialValue - Initial accumulator.
670
+ * @returns Final accumulator.
671
+ * @remarks Time O(n), Space O(1)
672
+ */
673
+ reduce(callbackfn, initialValue) {
674
+ let accumulator = initialValue;
675
+ let index = 0;
676
+ for (const item of this) {
677
+ const [key, value] = item;
678
+ accumulator = callbackfn(accumulator, value, key, index++, this);
679
+ }
680
+ return accumulator;
681
+ }
682
+ /**
683
+ * Converts data structure to `[key, value]` pairs.
684
+ * @returns Array of entries.
685
+ * @remarks Time O(n), Space O(n)
686
+ */
687
+ toArray() {
688
+ return [...this];
689
+ }
690
+ /**
691
+ * Visualize the iterable as an array of `[key, value]` pairs (or a custom string).
692
+ * @returns Array of entries (default) or a string.
693
+ * @remarks Time O(n), Space O(n)
694
+ */
695
+ toVisual() {
696
+ return [...this];
697
+ }
698
+ /**
699
+ * Print a human-friendly representation to the console.
700
+ * @remarks Time O(n), Space O(n)
701
+ */
702
+ print() {
703
+ console.log(this.toVisual());
704
+ }
705
+ };
706
+
476
707
  // src/data-structures/queue/queue.ts
477
708
  var Queue = class _Queue extends LinearBase {
478
709
  static {
@@ -530,18 +761,52 @@ var Queue = class _Queue extends LinearBase {
530
761
  this._autoCompactRatio = value;
531
762
  }
532
763
  /**
533
- * Get the number of elements currently in the queue.
534
- * @remarks Time O(1), Space O(1)
535
- * @returns Current length.
536
- */
764
+ * Get the number of elements currently in the queue.
765
+ * @remarks Time O(1), Space O(1)
766
+ * @returns Current length.
767
+
768
+
769
+
770
+
771
+
772
+
773
+
774
+
775
+
776
+
777
+
778
+ * @example
779
+ * // Track queue length
780
+ * const q = new Queue<number>();
781
+ * console.log(q.length); // 0;
782
+ * q.push(1);
783
+ * q.push(2);
784
+ * console.log(q.length); // 2;
785
+ */
537
786
  get length() {
538
787
  return this.elements.length - this._offset;
539
788
  }
540
789
  /**
541
- * Get the first element (front) without removing it.
542
- * @remarks Time O(1), Space O(1)
543
- * @returns Front element or undefined.
544
- */
790
+ * Get the first element (front) without removing it.
791
+ * @remarks Time O(1), Space O(1)
792
+ * @returns Front element or undefined.
793
+
794
+
795
+
796
+
797
+
798
+
799
+
800
+
801
+
802
+
803
+
804
+ * @example
805
+ * // View the front element
806
+ * const q = new Queue<string>(['first', 'second', 'third']);
807
+ * console.log(q.first); // 'first';
808
+ * console.log(q.length); // 3;
809
+ */
545
810
  get first() {
546
811
  return this.length > 0 ? this.elements[this._offset] : void 0;
547
812
  }
@@ -564,19 +829,69 @@ var Queue = class _Queue extends LinearBase {
564
829
  return new _Queue(elements);
565
830
  }
566
831
  /**
567
- * Check whether the queue is empty.
568
- * @remarks Time O(1), Space O(1)
569
- * @returns True if length is 0.
570
- */
832
+ * Check whether the queue is empty.
833
+ * @remarks Time O(1), Space O(1)
834
+ * @returns True if length is 0.
835
+
836
+
837
+
838
+
839
+
840
+
841
+
842
+
843
+
844
+
845
+
846
+ * @example
847
+ * // Queue for...of iteration and isEmpty check
848
+ * const queue = new Queue<string>(['A', 'B', 'C', 'D']);
849
+ *
850
+ * const elements: string[] = [];
851
+ * for (const item of queue) {
852
+ * elements.push(item);
853
+ * }
854
+ *
855
+ * // Verify all elements are iterated in order
856
+ * console.log(elements); // ['A', 'B', 'C', 'D'];
857
+ *
858
+ * // Process all elements
859
+ * while (queue.length > 0) {
860
+ * queue.shift();
861
+ * }
862
+ *
863
+ * console.log(queue.length); // 0;
864
+ */
571
865
  isEmpty() {
572
866
  return this.length === 0;
573
867
  }
574
868
  /**
575
- * Enqueue one element at the back.
576
- * @remarks Time O(1), Space O(1)
577
- * @param element - Element to enqueue.
578
- * @returns True on success.
579
- */
869
+ * Enqueue one element at the back.
870
+ * @remarks Time O(1), Space O(1)
871
+ * @param element - Element to enqueue.
872
+ * @returns True on success.
873
+
874
+
875
+
876
+
877
+
878
+
879
+
880
+
881
+
882
+
883
+
884
+ * @example
885
+ * // basic Queue creation and push operation
886
+ * // Create a simple Queue with initial values
887
+ * const queue = new Queue([1, 2, 3, 4, 5]);
888
+ *
889
+ * // Verify the queue maintains insertion order
890
+ * console.log([...queue]); // [1, 2, 3, 4, 5];
891
+ *
892
+ * // Check length
893
+ * console.log(queue.length); // 5;
894
+ */
580
895
  push(element) {
581
896
  this.elements.push(element);
582
897
  if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
@@ -597,10 +912,35 @@ var Queue = class _Queue extends LinearBase {
597
912
  return ans;
598
913
  }
599
914
  /**
600
- * Dequeue one element from the front (amortized via offset).
601
- * @remarks Time O(1) amortized, Space O(1)
602
- * @returns Removed element or undefined.
603
- */
915
+ * Dequeue one element from the front (amortized via offset).
916
+ * @remarks Time O(1) amortized, Space O(1)
917
+ * @returns Removed element or undefined.
918
+
919
+
920
+
921
+
922
+
923
+
924
+
925
+
926
+
927
+
928
+
929
+ * @example
930
+ * // Queue shift and peek operations
931
+ * const queue = new Queue<number>([10, 20, 30, 40]);
932
+ *
933
+ * // Peek at the front element without removing it
934
+ * console.log(queue.first); // 10;
935
+ *
936
+ * // Remove and get the first element (FIFO)
937
+ * const first = queue.shift();
938
+ * console.log(first); // 10;
939
+ *
940
+ * // Verify remaining elements and length decreased
941
+ * console.log([...queue]); // [20, 30, 40];
942
+ * console.log(queue.length); // 3;
943
+ */
604
944
  shift() {
605
945
  if (this.length === 0) return void 0;
606
946
  const first = this.first;
@@ -609,11 +949,24 @@ var Queue = class _Queue extends LinearBase {
609
949
  return first;
610
950
  }
611
951
  /**
612
- * Delete the first occurrence of a specific element.
613
- * @remarks Time O(N), Space O(1)
614
- * @param element - Element to remove (strict equality via Object.is).
615
- * @returns True if an element was removed.
616
- */
952
+ * Delete the first occurrence of a specific element.
953
+ * @remarks Time O(N), Space O(1)
954
+ * @param element - Element to remove (strict equality via Object.is).
955
+ * @returns True if an element was removed.
956
+
957
+
958
+
959
+
960
+
961
+
962
+
963
+
964
+ * @example
965
+ * // Remove specific element
966
+ * const q = new Queue<number>([1, 2, 3, 2]);
967
+ * q.delete(2);
968
+ * console.log(q.length); // 3;
969
+ */
617
970
  delete(element) {
618
971
  for (let i = this._offset; i < this.elements.length; i++) {
619
972
  if (Object.is(this.elements[i], element)) {
@@ -624,11 +977,24 @@ var Queue = class _Queue extends LinearBase {
624
977
  return false;
625
978
  }
626
979
  /**
627
- * Get the element at a given logical index.
628
- * @remarks Time O(1), Space O(1)
629
- * @param index - Zero-based index from the front.
630
- * @returns Element or undefined.
631
- */
980
+ * Get the element at a given logical index.
981
+ * @remarks Time O(1), Space O(1)
982
+ * @param index - Zero-based index from the front.
983
+ * @returns Element or undefined.
984
+
985
+
986
+
987
+
988
+
989
+
990
+
991
+
992
+ * @example
993
+ * // Access element by index
994
+ * const q = new Queue<string>(['a', 'b', 'c']);
995
+ * console.log(q.at(0)); // 'a';
996
+ * console.log(q.at(2)); // 'c';
997
+ */
632
998
  at(index) {
633
999
  if (index < 0 || index >= this.length) return void 0;
634
1000
  return this._elements[this._offset + index];
@@ -680,19 +1046,48 @@ var Queue = class _Queue extends LinearBase {
680
1046
  return this;
681
1047
  }
682
1048
  /**
683
- * Remove all elements and reset offset.
684
- * @remarks Time O(1), Space O(1)
685
- * @returns void
686
- */
1049
+ * Remove all elements and reset offset.
1050
+ * @remarks Time O(1), Space O(1)
1051
+ * @returns void
1052
+
1053
+
1054
+
1055
+
1056
+
1057
+
1058
+
1059
+
1060
+
1061
+ * @example
1062
+ * // Remove all elements
1063
+ * const q = new Queue<number>([1, 2, 3]);
1064
+ * q.clear();
1065
+ * console.log(q.length); // 0;
1066
+ */
687
1067
  clear() {
688
1068
  this._elements = [];
689
1069
  this._offset = 0;
690
1070
  }
691
1071
  /**
692
- * Compact storage by discarding consumed head elements.
693
- * @remarks Time O(N), Space O(N)
694
- * @returns True when compaction performed.
695
- */
1072
+ * Compact storage by discarding consumed head elements.
1073
+ * @remarks Time O(N), Space O(N)
1074
+ * @returns True when compaction performed.
1075
+
1076
+
1077
+
1078
+
1079
+
1080
+
1081
+
1082
+
1083
+ * @example
1084
+ * // Reclaim unused memory
1085
+ * const q = new Queue<number>([1, 2, 3, 4, 5]);
1086
+ * q.shift();
1087
+ * q.shift();
1088
+ * q.compact();
1089
+ * console.log(q.length); // 3;
1090
+ */
696
1091
  compact() {
697
1092
  this._elements = this.elements.slice(this._offset);
698
1093
  this._offset = 0;
@@ -718,10 +1113,26 @@ var Queue = class _Queue extends LinearBase {
718
1113
  return removed;
719
1114
  }
720
1115
  /**
721
- * Deep clone this queue and its parameters.
722
- * @remarks Time O(N), Space O(N)
723
- * @returns A new queue with the same content and options.
724
- */
1116
+ * Deep clone this queue and its parameters.
1117
+ * @remarks Time O(N), Space O(N)
1118
+ * @returns A new queue with the same content and options.
1119
+
1120
+
1121
+
1122
+
1123
+
1124
+
1125
+
1126
+
1127
+
1128
+ * @example
1129
+ * // Create independent copy
1130
+ * const q = new Queue<number>([1, 2, 3]);
1131
+ * const copy = q.clone();
1132
+ * copy.shift();
1133
+ * console.log(q.length); // 3;
1134
+ * console.log(copy.length); // 2;
1135
+ */
725
1136
  clone() {
726
1137
  const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
727
1138
  out._setAutoCompactRatio(this._autoCompactRatio);
@@ -729,12 +1140,26 @@ var Queue = class _Queue extends LinearBase {
729
1140
  return out;
730
1141
  }
731
1142
  /**
732
- * Filter elements into a new queue of the same class.
733
- * @remarks Time O(N), Space O(N)
734
- * @param predicate - Predicate (element, index, queue) → boolean to keep element.
735
- * @param [thisArg] - Value for `this` inside the predicate.
736
- * @returns A new queue with kept elements.
737
- */
1143
+ * Filter elements into a new queue of the same class.
1144
+ * @remarks Time O(N), Space O(N)
1145
+ * @param predicate - Predicate (element, index, queue) → boolean to keep element.
1146
+ * @param [thisArg] - Value for `this` inside the predicate.
1147
+ * @returns A new queue with kept elements.
1148
+
1149
+
1150
+
1151
+
1152
+
1153
+
1154
+
1155
+
1156
+
1157
+ * @example
1158
+ * // Filter elements
1159
+ * const q = new Queue<number>([1, 2, 3, 4, 5]);
1160
+ * const evens = q.filter(x => x % 2 === 0);
1161
+ * console.log(evens.length); // 2;
1162
+ */
738
1163
  filter(predicate, thisArg) {
739
1164
  const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
740
1165
  out._setAutoCompactRatio(this._autoCompactRatio);
@@ -746,15 +1171,28 @@ var Queue = class _Queue extends LinearBase {
746
1171
  return out;
747
1172
  }
748
1173
  /**
749
- * Map each element to a new element in a possibly different-typed queue.
750
- * @remarks Time O(N), Space O(N)
751
- * @template EM
752
- * @template RM
753
- * @param callback - Mapping function (element, index, queue) → newElement.
754
- * @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
755
- * @param [thisArg] - Value for `this` inside the callback.
756
- * @returns A new Queue with mapped elements.
757
- */
1174
+ * Map each element to a new element in a possibly different-typed queue.
1175
+ * @remarks Time O(N), Space O(N)
1176
+ * @template EM
1177
+ * @template RM
1178
+ * @param callback - Mapping function (element, index, queue) → newElement.
1179
+ * @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
1180
+ * @param [thisArg] - Value for `this` inside the callback.
1181
+ * @returns A new Queue with mapped elements.
1182
+
1183
+
1184
+
1185
+
1186
+
1187
+
1188
+
1189
+
1190
+ * @example
1191
+ * // Transform elements
1192
+ * const q = new Queue<number>([1, 2, 3]);
1193
+ * const doubled = q.map(x => x * 2);
1194
+ * console.log(doubled.toArray()); // [2, 4, 6];
1195
+ */
758
1196
  map(callback, options, thisArg) {
759
1197
  const out = new this.constructor([], {
760
1198
  toElementFn: options?.toElementFn,
@@ -841,212 +1279,6 @@ var Queue = class _Queue extends LinearBase {
841
1279
  }
842
1280
  };
843
1281
 
844
- // src/data-structures/base/iterable-entry-base.ts
845
- var IterableEntryBase = class {
846
- static {
847
- __name(this, "IterableEntryBase");
848
- }
849
- /**
850
- * Default iterator yielding `[key, value]` entries.
851
- * @returns Iterator of `[K, V]`.
852
- * @remarks Time O(n) to iterate, Space O(1)
853
- */
854
- *[Symbol.iterator](...args) {
855
- yield* this._getIterator(...args);
856
- }
857
- /**
858
- * Iterate over `[key, value]` pairs (may yield `undefined` values).
859
- * @returns Iterator of `[K, V | undefined]`.
860
- * @remarks Time O(n), Space O(1)
861
- */
862
- *entries() {
863
- for (const item of this) {
864
- yield item;
865
- }
866
- }
867
- /**
868
- * Iterate over keys only.
869
- * @returns Iterator of keys.
870
- * @remarks Time O(n), Space O(1)
871
- */
872
- *keys() {
873
- for (const item of this) {
874
- yield item[0];
875
- }
876
- }
877
- /**
878
- * Iterate over values only.
879
- * @returns Iterator of values.
880
- * @remarks Time O(n), Space O(1)
881
- */
882
- *values() {
883
- for (const item of this) {
884
- yield item[1];
885
- }
886
- }
887
- /**
888
- * Test whether all entries satisfy the predicate.
889
- * @param predicate - `(key, value, index, self) => boolean`.
890
- * @param thisArg - Optional `this` for callback.
891
- * @returns `true` if all pass; otherwise `false`.
892
- * @remarks Time O(n), Space O(1)
893
- */
894
- every(predicate, thisArg) {
895
- let index = 0;
896
- for (const item of this) {
897
- if (!predicate.call(thisArg, item[1], item[0], index++, this)) {
898
- return false;
899
- }
900
- }
901
- return true;
902
- }
903
- /**
904
- * Test whether any entry satisfies the predicate.
905
- * @param predicate - `(key, value, index, self) => boolean`.
906
- * @param thisArg - Optional `this` for callback.
907
- * @returns `true` if any passes; otherwise `false`.
908
- * @remarks Time O(n), Space O(1)
909
- */
910
- some(predicate, thisArg) {
911
- let index = 0;
912
- for (const item of this) {
913
- if (predicate.call(thisArg, item[1], item[0], index++, this)) {
914
- return true;
915
- }
916
- }
917
- return false;
918
- }
919
- /**
920
- * Visit each entry, left-to-right.
921
- * @param callbackfn - `(key, value, index, self) => void`.
922
- * @param thisArg - Optional `this` for callback.
923
- * @remarks Time O(n), Space O(1)
924
- */
925
- forEach(callbackfn, thisArg) {
926
- let index = 0;
927
- for (const item of this) {
928
- const [key, value] = item;
929
- callbackfn.call(thisArg, value, key, index++, this);
930
- }
931
- }
932
- /**
933
- * Find the first entry that matches a predicate.
934
- * @param callbackfn - `(key, value, index, self) => boolean`.
935
- * @param thisArg - Optional `this` for callback.
936
- * @returns Matching `[key, value]` or `undefined`.
937
- * @remarks Time O(n), Space O(1)
938
- */
939
- find(callbackfn, thisArg) {
940
- let index = 0;
941
- for (const item of this) {
942
- const [key, value] = item;
943
- if (callbackfn.call(thisArg, value, key, index++, this)) return item;
944
- }
945
- return;
946
- }
947
- /**
948
- * Whether the given key exists.
949
- * @param key - Key to test.
950
- * @returns `true` if found; otherwise `false`.
951
- * @remarks Time O(n) generic, Space O(1)
952
- */
953
- has(key) {
954
- for (const item of this) {
955
- const [itemKey] = item;
956
- if (itemKey === key) return true;
957
- }
958
- return false;
959
- }
960
- /**
961
- * Whether there exists an entry with the given value.
962
- * @param value - Value to test.
963
- * @returns `true` if found; otherwise `false`.
964
- * @remarks Time O(n), Space O(1)
965
- */
966
- hasValue(value) {
967
- for (const [, elementValue] of this) {
968
- if (elementValue === value) return true;
969
- }
970
- return false;
971
- }
972
- /**
973
- * Get the value under a key.
974
- * @param key - Key to look up.
975
- * @returns Value or `undefined`.
976
- * @remarks Time O(n) generic, Space O(1)
977
- */
978
- get(key) {
979
- for (const item of this) {
980
- const [itemKey, value] = item;
981
- if (itemKey === key) return value;
982
- }
983
- return;
984
- }
985
- /**
986
- * Reduce entries into a single accumulator.
987
- * @param callbackfn - `(acc, value, key, index, self) => acc`.
988
- * @param initialValue - Initial accumulator.
989
- * @returns Final accumulator.
990
- * @remarks Time O(n), Space O(1)
991
- */
992
- reduce(callbackfn, initialValue) {
993
- let accumulator = initialValue;
994
- let index = 0;
995
- for (const item of this) {
996
- const [key, value] = item;
997
- accumulator = callbackfn(accumulator, value, key, index++, this);
998
- }
999
- return accumulator;
1000
- }
1001
- /**
1002
- * Converts data structure to `[key, value]` pairs.
1003
- * @returns Array of entries.
1004
- * @remarks Time O(n), Space O(n)
1005
- */
1006
- toArray() {
1007
- return [...this];
1008
- }
1009
- /**
1010
- * Visualize the iterable as an array of `[key, value]` pairs (or a custom string).
1011
- * @returns Array of entries (default) or a string.
1012
- * @remarks Time O(n), Space O(n)
1013
- */
1014
- toVisual() {
1015
- return [...this];
1016
- }
1017
- /**
1018
- * Print a human-friendly representation to the console.
1019
- * @remarks Time O(n), Space O(n)
1020
- */
1021
- print() {
1022
- console.log(this.toVisual());
1023
- }
1024
- };
1025
-
1026
- // src/common/index.ts
1027
- var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
1028
- DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
1029
- DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
1030
- return DFSOperation2;
1031
- })(DFSOperation || {});
1032
- var Range = class {
1033
- constructor(low, high, includeLow = true, includeHigh = true) {
1034
- this.low = low;
1035
- this.high = high;
1036
- this.includeLow = includeLow;
1037
- this.includeHigh = includeHigh;
1038
- }
1039
- static {
1040
- __name(this, "Range");
1041
- }
1042
- // Determine whether a key is within the range
1043
- isInRange(key, comparator) {
1044
- const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
1045
- const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
1046
- return lowCheck && highCheck;
1047
- }
1048
- };
1049
-
1050
1282
  // src/data-structures/binary-tree/binary-tree.ts
1051
1283
  var BinaryTreeNode = class {
1052
1284
  static {
@@ -1185,7 +1417,7 @@ var BinaryTreeNode = class {
1185
1417
  return "MAL_NODE";
1186
1418
  }
1187
1419
  };
1188
- var BinaryTree = class extends IterableEntryBase {
1420
+ var BinaryTree = class _BinaryTree extends IterableEntryBase {
1189
1421
  static {
1190
1422
  __name(this, "BinaryTree");
1191
1423
  }
@@ -1205,7 +1437,7 @@ var BinaryTree = class extends IterableEntryBase {
1205
1437
  if (isMapMode !== void 0) this._isMapMode = isMapMode;
1206
1438
  if (isDuplicate !== void 0) this._isDuplicate = isDuplicate;
1207
1439
  if (typeof toEntryFn === "function") this._toEntryFn = toEntryFn;
1208
- else if (toEntryFn) throw TypeError("toEntryFn must be a function type");
1440
+ else if (toEntryFn) throw new TypeError(ERR.notAFunction("toEntryFn", "BinaryTree"));
1209
1441
  }
1210
1442
  if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
1211
1443
  }
@@ -1420,30 +1652,78 @@ var BinaryTree = class extends IterableEntryBase {
1420
1652
  return isComparable(key);
1421
1653
  }
1422
1654
  /**
1423
- * Adds a new node to the tree.
1424
- * @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).
1425
- *
1426
- * @param keyNodeOrEntry - The key, node, or entry to add.
1427
- * @returns True if the addition was successful, false otherwise.
1428
- */
1655
+ * Adds a new node to the tree.
1656
+ * @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).
1657
+ *
1658
+ * @param keyNodeOrEntry - The key, node, or entry to add.
1659
+ * @returns True if the addition was successful, false otherwise.
1660
+
1661
+
1662
+
1663
+
1664
+
1665
+
1666
+ * @example
1667
+ * // Add a single node
1668
+ * const tree = new BinaryTree<number>();
1669
+ * tree.add(1);
1670
+ * tree.add(2);
1671
+ * tree.add(3);
1672
+ * console.log(tree.size); // 3;
1673
+ * console.log(tree.has(1)); // true;
1674
+ */
1429
1675
  add(keyNodeOrEntry) {
1430
1676
  return this.set(keyNodeOrEntry);
1431
1677
  }
1432
1678
  /**
1433
- * Adds or updates a new node to the tree.
1434
- * @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).
1435
- *
1436
- * @param keyNodeOrEntry - The key, node, or entry to set or update.
1437
- * @param [value] - The value, if providing just a key.
1438
- * @returns True if the addition was successful, false otherwise.
1439
- */
1679
+ * Adds or updates a new node to the tree.
1680
+ * @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).
1681
+ *
1682
+ * @param keyNodeOrEntry - The key, node, or entry to set or update.
1683
+ * @param [value] - The value, if providing just a key.
1684
+ * @returns True if the addition was successful, false otherwise.
1685
+
1686
+
1687
+
1688
+
1689
+
1690
+
1691
+
1692
+
1693
+
1694
+
1695
+
1696
+ * @example
1697
+ * // basic BinaryTree creation and insertion
1698
+ * // Create a BinaryTree with entries
1699
+ * const entries: [number, string][] = [
1700
+ * [6, 'six'],
1701
+ * [1, 'one'],
1702
+ * [2, 'two'],
1703
+ * [7, 'seven'],
1704
+ * [5, 'five'],
1705
+ * [3, 'three'],
1706
+ * [4, 'four'],
1707
+ * [9, 'nine'],
1708
+ * [8, 'eight']
1709
+ * ];
1710
+ *
1711
+ * const tree = new BinaryTree(entries);
1712
+ *
1713
+ * // Verify size
1714
+ * console.log(tree.size); // 9;
1715
+ *
1716
+ * // Add new element
1717
+ * tree.set(10, 'ten');
1718
+ * console.log(tree.size); // 10;
1719
+ */
1440
1720
  set(keyNodeOrEntry, value) {
1441
1721
  const [newNode] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
1442
1722
  if (newNode === void 0) return false;
1443
1723
  if (!this._root) {
1444
1724
  this._setRoot(newNode);
1445
1725
  if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
1446
- this._size = 1;
1726
+ if (newNode !== null) this._size = 1;
1447
1727
  return true;
1448
1728
  }
1449
1729
  const queue = new Queue([this._root]);
@@ -1475,29 +1755,50 @@ var BinaryTree = class extends IterableEntryBase {
1475
1755
  potentialParent.right = newNode;
1476
1756
  }
1477
1757
  if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
1478
- this._size++;
1758
+ if (newNode !== null) this._size++;
1479
1759
  return true;
1480
1760
  }
1481
1761
  return false;
1482
1762
  }
1483
1763
  /**
1484
- * Adds multiple items to the tree.
1485
- * @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).
1486
- *
1487
- * @param keysNodesEntriesOrRaws - An iterable of items to set.
1488
- * @returns An array of booleans indicating the success of each individual `set` operation.
1489
- */
1764
+ * Adds multiple items to the tree.
1765
+ * @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).
1766
+ *
1767
+ * @param keysNodesEntriesOrRaws - An iterable of items to set.
1768
+ * @returns An array of booleans indicating the success of each individual `set` operation.
1769
+
1770
+
1771
+
1772
+
1773
+
1774
+
1775
+
1776
+
1777
+
1778
+ * @example
1779
+ * // Bulk add
1780
+ * const tree = new BinaryTree<number>();
1781
+ * tree.addMany([1, 2, 3, 4, 5]);
1782
+ * console.log(tree.size); // 5;
1783
+ */
1490
1784
  addMany(keysNodesEntriesOrRaws) {
1491
1785
  return this.setMany(keysNodesEntriesOrRaws);
1492
1786
  }
1493
1787
  /**
1494
- * Adds or updates multiple items to the tree.
1495
- * @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).
1496
- *
1497
- * @param keysNodesEntriesOrRaws - An iterable of items to set or update.
1498
- * @param [values] - An optional parallel iterable of values.
1499
- * @returns An array of booleans indicating the success of each individual `set` operation.
1500
- */
1788
+ * Adds or updates multiple items to the tree.
1789
+ * @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).
1790
+ *
1791
+ * @param keysNodesEntriesOrRaws - An iterable of items to set or update.
1792
+ * @param [values] - An optional parallel iterable of values.
1793
+ * @returns An array of booleans indicating the success of each individual `set` operation.
1794
+
1795
+
1796
+ * @example
1797
+ * // Set multiple entries
1798
+ * const tree = new BinaryTree<number, string>();
1799
+ * tree.setMany([[1, 'a'], [2, 'b'], [3, 'c']]);
1800
+ * console.log(tree.size); // 3;
1801
+ */
1501
1802
  setMany(keysNodesEntriesOrRaws, values) {
1502
1803
  const inserted = [];
1503
1804
  let valuesIterator;
@@ -1518,11 +1819,26 @@ var BinaryTree = class extends IterableEntryBase {
1518
1819
  return inserted;
1519
1820
  }
1520
1821
  /**
1521
- * Merges another tree into this one by seting all its nodes.
1522
- * @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`).
1523
- *
1524
- * @param anotherTree - The tree to merge.
1525
- */
1822
+ * Merges another tree into this one by seting all its nodes.
1823
+ * @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`).
1824
+ *
1825
+ * @param anotherTree - The tree to merge.
1826
+
1827
+
1828
+
1829
+
1830
+
1831
+
1832
+
1833
+
1834
+
1835
+ * @example
1836
+ * // Combine trees
1837
+ * const t1 = new BinaryTree<number>([1, 2]);
1838
+ * const t2 = new BinaryTree<number>([3, 4]);
1839
+ * t1.merge(t2);
1840
+ * console.log(t1.size); // 4;
1841
+ */
1526
1842
  merge(anotherTree) {
1527
1843
  this.setMany(anotherTree, []);
1528
1844
  }
@@ -1538,12 +1854,29 @@ var BinaryTree = class extends IterableEntryBase {
1538
1854
  this.setMany(keysNodesEntriesOrRaws, values);
1539
1855
  }
1540
1856
  /**
1541
- * Deletes a node from the tree.
1542
- * @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).
1543
- *
1544
- * @param keyNodeEntryRawOrPredicate - The node to delete.
1545
- * @returns An array containing deletion results (for compatibility with self-balancing trees).
1546
- */
1857
+ * Deletes a node from the tree.
1858
+ * @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).
1859
+ *
1860
+ * @param keyNodeEntryRawOrPredicate - The node to delete.
1861
+ * @returns An array containing deletion results (for compatibility with self-balancing trees).
1862
+
1863
+
1864
+
1865
+
1866
+
1867
+
1868
+
1869
+
1870
+
1871
+
1872
+
1873
+ * @example
1874
+ * // Remove a node
1875
+ * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
1876
+ * tree.delete(3);
1877
+ * console.log(tree.has(3)); // false;
1878
+ * console.log(tree.size); // 4;
1879
+ */
1547
1880
  delete(keyNodeEntryRawOrPredicate) {
1548
1881
  const deletedResult = [];
1549
1882
  if (!this._root) return deletedResult;
@@ -1637,14 +1970,27 @@ var BinaryTree = class extends IterableEntryBase {
1637
1970
  return this.search(keyNodeEntryOrPredicate, onlyOne, (node) => node, startNode, iterationType);
1638
1971
  }
1639
1972
  /**
1640
- * Gets the first node matching a predicate.
1641
- * @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`).
1642
- *
1643
- * @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
1644
- * @param [startNode=this._root] - The node to start the search from.
1645
- * @param [iterationType=this.iterationType] - The traversal method.
1646
- * @returns The first matching node, or undefined if not found.
1647
- */
1973
+ * Gets the first node matching a predicate.
1974
+ * @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`).
1975
+ *
1976
+ * @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
1977
+ * @param [startNode=this._root] - The node to start the search from.
1978
+ * @param [iterationType=this.iterationType] - The traversal method.
1979
+ * @returns The first matching node, or undefined if not found.
1980
+
1981
+
1982
+
1983
+
1984
+
1985
+
1986
+
1987
+
1988
+
1989
+ * @example
1990
+ * // Get node by key
1991
+ * const tree = new BinaryTree<number, string>([[1, 'root'], [2, 'child']]);
1992
+ * console.log(tree.getNode(2)?.value); // 'child';
1993
+ */
1648
1994
  getNode(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
1649
1995
  if (this._isMapMode && keyNodeEntryOrPredicate !== null && keyNodeEntryOrPredicate !== void 0) {
1650
1996
  if (!this._isPredicate(keyNodeEntryOrPredicate)) {
@@ -1656,14 +2002,30 @@ var BinaryTree = class extends IterableEntryBase {
1656
2002
  return this.search(keyNodeEntryOrPredicate, true, (node) => node, startNode, iterationType)[0];
1657
2003
  }
1658
2004
  /**
1659
- * Gets the value associated with a key.
1660
- * @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.
1661
- *
1662
- * @param keyNodeEntryOrPredicate - The key, node, or entry to get the value for.
1663
- * @param [startNode=this._root] - The node to start searching from (if not in Map mode).
1664
- * @param [iterationType=this.iterationType] - The traversal method (if not in Map mode).
1665
- * @returns The associated value, or undefined.
1666
- */
2005
+ * Gets the value associated with a key.
2006
+ * @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.
2007
+ *
2008
+ * @param keyNodeEntryOrPredicate - The key, node, or entry to get the value for.
2009
+ * @param [startNode=this._root] - The node to start searching from (if not in Map mode).
2010
+ * @param [iterationType=this.iterationType] - The traversal method (if not in Map mode).
2011
+ * @returns The associated value, or undefined.
2012
+
2013
+
2014
+
2015
+
2016
+
2017
+
2018
+
2019
+
2020
+
2021
+
2022
+
2023
+ * @example
2024
+ * // Retrieve value by key
2025
+ * const tree = new BinaryTree<number, string>([[1, 'root'], [2, 'left'], [3, 'right']]);
2026
+ * console.log(tree.get(2)); // 'left';
2027
+ * console.log(tree.get(99)); // undefined;
2028
+ */
1667
2029
  get(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
1668
2030
  if (this._isMapMode) {
1669
2031
  const key = this._extractKey(keyNodeEntryOrPredicate);
@@ -1683,19 +2045,45 @@ var BinaryTree = class extends IterableEntryBase {
1683
2045
  return this.search(keyNodeEntryOrPredicate, true, (node) => node, startNode, iterationType).length > 0;
1684
2046
  }
1685
2047
  /**
1686
- * Clears the tree of all nodes and values.
1687
- * @remarks Time O(N) if in Map mode (due to `_store.clear()`), O(1) otherwise. Space O(1)
1688
- */
2048
+ * Clears the tree of all nodes and values.
2049
+ * @remarks Time O(N) if in Map mode (due to `_store.clear()`), O(1) otherwise. Space O(1)
2050
+
2051
+
2052
+
2053
+
2054
+
2055
+
2056
+
2057
+
2058
+
2059
+ * @example
2060
+ * // Remove all nodes
2061
+ * const tree = new BinaryTree<number>([1, 2, 3]);
2062
+ * tree.clear();
2063
+ * console.log(tree.isEmpty()); // true;
2064
+ */
1689
2065
  clear() {
1690
2066
  this._clearNodes();
1691
2067
  if (this._isMapMode) this._clearValues();
1692
2068
  }
1693
2069
  /**
1694
- * Checks if the tree is empty.
1695
- * @remarks Time O(1), Space O(1)
1696
- *
1697
- * @returns True if the tree has no nodes, false otherwise.
1698
- */
2070
+ * Checks if the tree is empty.
2071
+ * @remarks Time O(1), Space O(1)
2072
+ *
2073
+ * @returns True if the tree has no nodes, false otherwise.
2074
+
2075
+
2076
+
2077
+
2078
+
2079
+
2080
+
2081
+
2082
+
2083
+ * @example
2084
+ * // Check empty
2085
+ * console.log(new BinaryTree().isEmpty()); // true;
2086
+ */
1699
2087
  isEmpty() {
1700
2088
  return this._size === 0;
1701
2089
  }
@@ -1710,13 +2098,27 @@ var BinaryTree = class extends IterableEntryBase {
1710
2098
  return this.getMinHeight(startNode) + 1 >= this.getHeight(startNode);
1711
2099
  }
1712
2100
  /**
1713
- * Checks if the tree is a valid Binary Search Tree (BST).
1714
- * @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).
1715
- *
1716
- * @param [startNode=this._root] - The node to start checking from.
1717
- * @param [iterationType=this.iterationType] - The traversal method.
1718
- * @returns True if it's a valid BST, false otherwise.
1719
- */
2101
+ * Checks if the tree is a valid Binary Search Tree (BST).
2102
+ * @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).
2103
+ *
2104
+ * @param [startNode=this._root] - The node to start checking from.
2105
+ * @param [iterationType=this.iterationType] - The traversal method.
2106
+ * @returns True if it's a valid BST, false otherwise.
2107
+
2108
+
2109
+
2110
+
2111
+
2112
+
2113
+
2114
+
2115
+
2116
+ * @example
2117
+ * // Check BST property
2118
+ * const tree = new BinaryTree<number>([1, 2, 3]);
2119
+ * // BinaryTree doesn't guarantee BST order
2120
+ * console.log(typeof tree.isBST()); // 'boolean';
2121
+ */
1720
2122
  isBST(startNode = this._root, iterationType = this.iterationType) {
1721
2123
  const startNodeSired = this.ensureNode(startNode);
1722
2124
  if (!startNodeSired) return true;
@@ -1754,13 +2156,29 @@ var BinaryTree = class extends IterableEntryBase {
1754
2156
  }
1755
2157
  }
1756
2158
  /**
1757
- * Gets the depth of a node (distance from `startNode`).
1758
- * @remarks Time O(H), where H is the depth of the `dist` node relative to `startNode`. O(N) worst-case. Space O(1).
1759
- *
1760
- * @param dist - The node to find the depth of.
1761
- * @param [startNode=this._root] - The node to measure depth from (defaults to root).
1762
- * @returns The depth (0 if `dist` is `startNode`).
1763
- */
2159
+ * Gets the depth of a node (distance from `startNode`).
2160
+ * @remarks Time O(H), where H is the depth of the `dist` node relative to `startNode`. O(N) worst-case. Space O(1).
2161
+ *
2162
+ * @param dist - The node to find the depth of.
2163
+ * @param [startNode=this._root] - The node to measure depth from (defaults to root).
2164
+ * @returns The depth (0 if `dist` is `startNode`).
2165
+
2166
+
2167
+
2168
+
2169
+
2170
+
2171
+
2172
+
2173
+
2174
+
2175
+
2176
+ * @example
2177
+ * // Get depth of a node
2178
+ * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
2179
+ * const node = tree.getNode(4);
2180
+ * console.log(tree.getDepth(node!)); // 2;
2181
+ */
1764
2182
  getDepth(dist, startNode = this._root) {
1765
2183
  let distEnsured = this.ensureNode(dist);
1766
2184
  const beginRootEnsured = this.ensureNode(startNode);
@@ -1775,13 +2193,28 @@ var BinaryTree = class extends IterableEntryBase {
1775
2193
  return depth;
1776
2194
  }
1777
2195
  /**
1778
- * Gets the maximum height of the tree (longest path from startNode to a leaf).
1779
- * @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).
1780
- *
1781
- * @param [startNode=this._root] - The node to start measuring from.
1782
- * @param [iterationType=this.iterationType] - The traversal method.
1783
- * @returns The height ( -1 for an empty tree, 0 for a single-node tree).
1784
- */
2196
+ * Gets the maximum height of the tree (longest path from startNode to a leaf).
2197
+ * @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).
2198
+ *
2199
+ * @param [startNode=this._root] - The node to start measuring from.
2200
+ * @param [iterationType=this.iterationType] - The traversal method.
2201
+ * @returns The height ( -1 for an empty tree, 0 for a single-node tree).
2202
+
2203
+
2204
+
2205
+
2206
+
2207
+
2208
+
2209
+
2210
+
2211
+
2212
+
2213
+ * @example
2214
+ * // Get tree height
2215
+ * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
2216
+ * console.log(tree.getHeight()); // 2;
2217
+ */
1785
2218
  getHeight(startNode = this._root, iterationType = this.iterationType) {
1786
2219
  startNode = this.ensureNode(startNode);
1787
2220
  if (!this.isRealNode(startNode)) return -1;
@@ -2043,7 +2476,7 @@ var BinaryTree = class extends IterableEntryBase {
2043
2476
  }
2044
2477
  /**
2045
2478
  * Finds all leaf nodes in the tree.
2046
- * @remarks Time O(N), visits every node. Space O(H) for recursive stack or O(N) for iterative queue.
2479
+ * @remarks Time O(N), visits every node. Space O(H) for recursive or iterative stack.
2047
2480
  *
2048
2481
  * @template C - The type of the callback function.
2049
2482
  * @param [callback=this._DEFAULT_NODE_CALLBACK] - Function to call on each leaf node.
@@ -2066,15 +2499,15 @@ var BinaryTree = class extends IterableEntryBase {
2066
2499
  }, "dfs");
2067
2500
  dfs(startNode);
2068
2501
  } else {
2069
- const queue = new Queue([startNode]);
2070
- while (queue.length > 0) {
2071
- const cur = queue.shift();
2502
+ const stack = [startNode];
2503
+ while (stack.length > 0) {
2504
+ const cur = stack.pop();
2072
2505
  if (this.isRealNode(cur)) {
2073
2506
  if (this.isLeaf(cur)) {
2074
2507
  leaves.push(callback(cur));
2075
2508
  }
2076
- if (this.isRealNode(cur.left)) queue.push(cur.left);
2077
- if (this.isRealNode(cur.right)) queue.push(cur.right);
2509
+ if (this.isRealNode(cur.right)) stack.push(cur.right);
2510
+ if (this.isRealNode(cur.left)) stack.push(cur.left);
2078
2511
  }
2079
2512
  }
2080
2513
  }
@@ -2217,24 +2650,53 @@ var BinaryTree = class extends IterableEntryBase {
2217
2650
  return ans;
2218
2651
  }
2219
2652
  /**
2220
- * Clones the tree.
2221
- * @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.
2222
- *
2223
- * @returns A new, cloned instance of the tree.
2224
- */
2653
+ * Clones the tree.
2654
+ * @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.
2655
+ *
2656
+ * @returns A new, cloned instance of the tree.
2657
+
2658
+
2659
+
2660
+
2661
+
2662
+
2663
+
2664
+
2665
+
2666
+ * @example
2667
+ * // Deep copy
2668
+ * const tree = new BinaryTree<number>([1, 2, 3]);
2669
+ * const copy = tree.clone();
2670
+ * copy.delete(1);
2671
+ * console.log(tree.has(1)); // true;
2672
+ */
2225
2673
  clone() {
2226
2674
  const out = this._createInstance();
2227
2675
  this._clone(out);
2228
2676
  return out;
2229
2677
  }
2230
2678
  /**
2231
- * Creates a new tree containing only the entries that satisfy the predicate.
2232
- * @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.
2233
- *
2234
- * @param predicate - A function to test each [key, value] pair.
2235
- * @param [thisArg] - `this` context for the predicate.
2236
- * @returns A new, filtered tree.
2237
- */
2679
+ * Creates a new tree containing only the entries that satisfy the predicate.
2680
+ * @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.
2681
+ *
2682
+ * @param predicate - A function to test each [key, value] pair.
2683
+ * @param [thisArg] - `this` context for the predicate.
2684
+ * @returns A new, filtered tree.
2685
+
2686
+
2687
+
2688
+
2689
+
2690
+
2691
+
2692
+
2693
+
2694
+ * @example
2695
+ * // Filter nodes by condition
2696
+ * const tree = new BinaryTree<number>([1, 2, 3, 4]);
2697
+ * const result = tree.filter((_, key) => key > 2);
2698
+ * console.log(result.size); // 2;
2699
+ */
2238
2700
  filter(predicate, thisArg) {
2239
2701
  const out = this._createInstance();
2240
2702
  let i = 0;
@@ -2242,17 +2704,31 @@ var BinaryTree = class extends IterableEntryBase {
2242
2704
  return out;
2243
2705
  }
2244
2706
  /**
2245
- * Creates a new tree by mapping each [key, value] pair to a new entry.
2246
- * @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.
2247
- *
2248
- * @template MK - New key type.
2249
- * @template MV - New value type.
2250
- * @template MR - New raw type.
2251
- * @param cb - A function to map each [key, value] pair.
2252
- * @param [options] - Options for the new tree.
2253
- * @param [thisArg] - `this` context for the callback.
2254
- * @returns A new, mapped tree.
2255
- */
2707
+ * Creates a new tree by mapping each [key, value] pair to a new entry.
2708
+ * @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.
2709
+ *
2710
+ * @template MK - New key type.
2711
+ * @template MV - New value type.
2712
+ * @template MR - New raw type.
2713
+ * @param cb - A function to map each [key, value] pair.
2714
+ * @param [options] - Options for the new tree.
2715
+ * @param [thisArg] - `this` context for the callback.
2716
+ * @returns A new, mapped tree.
2717
+
2718
+
2719
+
2720
+
2721
+
2722
+
2723
+
2724
+
2725
+
2726
+ * @example
2727
+ * // Transform to new tree
2728
+ * const tree = new BinaryTree<number, number>([[1, 10], [2, 20]]);
2729
+ * const mapped = tree.map((v, key) => [key, (v ?? 0) + 1] as [number, number]);
2730
+ * console.log([...mapped.values()]); // contains 11;
2731
+ */
2256
2732
  map(cb, options, thisArg) {
2257
2733
  const out = this._createLike([], options);
2258
2734
  let i = 0;
@@ -2290,12 +2766,25 @@ var BinaryTree = class extends IterableEntryBase {
2290
2766
  return output;
2291
2767
  }
2292
2768
  /**
2293
- * Prints a visual representation of the tree to the console.
2294
- * @remarks Time O(N) (via `toVisual`). Space O(N*H) or O(N^2) (via `toVisual`).
2295
- *
2296
- * @param [options] - Options to control the output.
2297
- * @param [startNode=this._root] - The node to start printing from.
2298
- */
2769
+ * Prints a visual representation of the tree to the console.
2770
+ * @remarks Time O(N) (via `toVisual`). Space O(N*H) or O(N^2) (via `toVisual`).
2771
+ *
2772
+ * @param [options] - Options to control the output.
2773
+ * @param [startNode=this._root] - The node to start printing from.
2774
+
2775
+
2776
+
2777
+
2778
+
2779
+
2780
+
2781
+
2782
+
2783
+ * @example
2784
+ * // Display tree
2785
+ * const tree = new BinaryTree<number>([1, 2, 3]);
2786
+ * expect(() => tree.print()).not.toThrow();
2787
+ */
2299
2788
  print(options, startNode = this._root) {
2300
2789
  console.log(this.toVisual(startNode, options));
2301
2790
  }
@@ -2534,44 +3023,99 @@ var BinaryTree = class extends IterableEntryBase {
2534
3023
  * @returns Layout information for this subtree.
2535
3024
  */
2536
3025
  _displayAux(node, options) {
2537
- const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
2538
3026
  const emptyDisplayLayout = [["\u2500"], 1, 0, 0];
2539
- if (node === null && !isShowNull) {
2540
- return emptyDisplayLayout;
2541
- } else if (node === void 0 && !isShowUndefined) {
2542
- return emptyDisplayLayout;
2543
- } else if (this.isNIL(node) && !isShowRedBlackNIL) {
2544
- return emptyDisplayLayout;
2545
- } else if (node !== null && node !== void 0) {
2546
- const key = node.key, line = this.isNIL(node) ? "S" : String(key), width = line.length;
2547
- return _buildNodeDisplay(
2548
- line,
2549
- width,
2550
- this._displayAux(node.left, options),
2551
- this._displayAux(node.right, options)
2552
- );
2553
- } else {
2554
- const line = node === void 0 ? "U" : "N", width = line.length;
2555
- return _buildNodeDisplay(line, width, [[""], 1, 0, 0], [[""], 1, 0, 0]);
2556
- }
2557
- function _buildNodeDisplay(line, width, left, right) {
2558
- const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
2559
- const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
2560
- 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));
2561
- const secondLine = (leftHeight > 0 ? " ".repeat(leftMiddle) + "/" + " ".repeat(leftWidth - leftMiddle - 1) : " ".repeat(leftWidth)) + " ".repeat(width) + (rightHeight > 0 ? " ".repeat(rightMiddle) + "\\" + " ".repeat(rightWidth - rightMiddle - 1) : " ".repeat(rightWidth));
2562
- const mergedLines = [firstLine, secondLine];
2563
- for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
2564
- const leftLine = i < leftHeight ? leftLines[i] : " ".repeat(leftWidth);
2565
- const rightLine = i < rightHeight ? rightLines[i] : " ".repeat(rightWidth);
2566
- mergedLines.push(leftLine + " ".repeat(width) + rightLine);
3027
+ const newFrame = /* @__PURE__ */ __name((n) => ({
3028
+ node: n,
3029
+ stage: 0,
3030
+ leftLayout: emptyDisplayLayout,
3031
+ rightLayout: emptyDisplayLayout
3032
+ }), "newFrame");
3033
+ const stack = [newFrame(node)];
3034
+ let result = emptyDisplayLayout;
3035
+ const setChildResult = /* @__PURE__ */ __name((layout) => {
3036
+ if (stack.length === 0) {
3037
+ result = layout;
3038
+ return;
3039
+ }
3040
+ const parent = stack[stack.length - 1];
3041
+ if (parent.stage === 1) parent.leftLayout = layout;
3042
+ else parent.rightLayout = layout;
3043
+ }, "setChildResult");
3044
+ while (stack.length > 0) {
3045
+ const frame = stack[stack.length - 1];
3046
+ const cur = frame.node;
3047
+ if (frame.stage === 0) {
3048
+ if (this._isDisplayLeaf(cur, options)) {
3049
+ stack.pop();
3050
+ const layout = this._resolveDisplayLeaf(cur, options, emptyDisplayLayout);
3051
+ setChildResult(layout);
3052
+ continue;
3053
+ }
3054
+ frame.stage = 1;
3055
+ stack.push(newFrame(cur.left));
3056
+ } else if (frame.stage === 1) {
3057
+ frame.stage = 2;
3058
+ stack.push(newFrame(cur.right));
3059
+ } else {
3060
+ stack.pop();
3061
+ const line = this.isNIL(cur) ? "S" : String(cur.key);
3062
+ const layout = _BinaryTree._buildNodeDisplay(line, line.length, frame.leftLayout, frame.rightLayout);
3063
+ setChildResult(layout);
2567
3064
  }
2568
- return [
2569
- mergedLines,
2570
- leftWidth + width + rightWidth,
2571
- Math.max(leftHeight, rightHeight) + 2,
2572
- leftWidth + Math.floor(width / 2)
2573
- ];
2574
3065
  }
3066
+ return result;
3067
+ }
3068
+ static _buildNodeDisplay(line, width, left, right) {
3069
+ const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
3070
+ const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
3071
+ 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));
3072
+ const secondLine = (leftHeight > 0 ? " ".repeat(leftMiddle) + "/" + " ".repeat(leftWidth - leftMiddle - 1) : " ".repeat(leftWidth)) + " ".repeat(width) + (rightHeight > 0 ? " ".repeat(rightMiddle) + "\\" + " ".repeat(rightWidth - rightMiddle - 1) : " ".repeat(rightWidth));
3073
+ const mergedLines = [firstLine, secondLine];
3074
+ for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
3075
+ const leftLine = i < leftHeight ? leftLines[i] : " ".repeat(leftWidth);
3076
+ const rightLine = i < rightHeight ? rightLines[i] : " ".repeat(rightWidth);
3077
+ mergedLines.push(leftLine + " ".repeat(width) + rightLine);
3078
+ }
3079
+ return [
3080
+ mergedLines,
3081
+ leftWidth + width + rightWidth,
3082
+ Math.max(leftHeight, rightHeight) + 2,
3083
+ leftWidth + Math.floor(width / 2)
3084
+ ];
3085
+ }
3086
+ /**
3087
+ * Check if a node is a display leaf (empty, null, undefined, NIL, or real leaf).
3088
+ */
3089
+ _isDisplayLeaf(node, options) {
3090
+ const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
3091
+ if (node === null && !isShowNull) return true;
3092
+ if (node === void 0 && !isShowUndefined) return true;
3093
+ if (this.isNIL(node) && !isShowRedBlackNIL) return true;
3094
+ if (node === null || node === void 0) return true;
3095
+ const hasDisplayableLeft = this._hasDisplayableChild(node.left, options);
3096
+ const hasDisplayableRight = this._hasDisplayableChild(node.right, options);
3097
+ return !hasDisplayableLeft && !hasDisplayableRight;
3098
+ }
3099
+ _hasDisplayableChild(child, options) {
3100
+ if (child === null) return !!options.isShowNull;
3101
+ if (child === void 0) return !!options.isShowUndefined;
3102
+ if (this.isNIL(child)) return !!options.isShowRedBlackNIL;
3103
+ return true;
3104
+ }
3105
+ /**
3106
+ * Resolve a display leaf node to its layout.
3107
+ */
3108
+ _resolveDisplayLeaf(node, options, emptyDisplayLayout) {
3109
+ const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
3110
+ if (node === null && !isShowNull) return emptyDisplayLayout;
3111
+ if (node === void 0 && !isShowUndefined) return emptyDisplayLayout;
3112
+ if (this.isNIL(node) && !isShowRedBlackNIL) return emptyDisplayLayout;
3113
+ if (node !== null && node !== void 0) {
3114
+ const line2 = this.isNIL(node) ? "S" : String(node.key);
3115
+ return _BinaryTree._buildNodeDisplay(line2, line2.length, emptyDisplayLayout, emptyDisplayLayout);
3116
+ }
3117
+ const line = node === void 0 ? "U" : "N";
3118
+ return _BinaryTree._buildNodeDisplay(line, line.length, [[""], 1, 0, 0], [[""], 1, 0, 0]);
2575
3119
  }
2576
3120
  /**
2577
3121
  * (Protected) Swaps the key/value properties of two nodes.
@@ -2715,6 +3259,6 @@ var BinaryTree = class extends IterableEntryBase {
2715
3259
  * @license MIT License
2716
3260
  */
2717
3261
 
2718
- export { BinaryTree, BinaryTreeNode, DFSOperation, Range };
3262
+ export { BinaryTree, BinaryTreeNode, DFSOperation, ERR, Range };
2719
3263
  //# sourceMappingURL=index.mjs.map
2720
3264
  //# sourceMappingURL=index.mjs.map