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