data-structure-typed 2.6.0 → 2.6.1

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 (80) hide show
  1. package/.github/workflows/ci.yml +7 -2
  2. package/.github/workflows/release-package.yml +9 -2
  3. package/docs-site-docusaurus/docs/api/classes/AVLTree.md +108 -108
  4. package/docs-site-docusaurus/docs/api/classes/BST.md +101 -101
  5. package/docs-site-docusaurus/docs/api/classes/BinaryIndexedTree.md +13 -13
  6. package/docs-site-docusaurus/docs/api/classes/BinaryTree.md +66 -66
  7. package/docs-site-docusaurus/docs/api/classes/Deque.md +235 -51
  8. package/docs-site-docusaurus/docs/api/classes/DirectedGraph.md +21 -21
  9. package/docs-site-docusaurus/docs/api/classes/DoublyLinkedList.md +231 -67
  10. package/docs-site-docusaurus/docs/api/classes/FibonacciHeap.md +9 -9
  11. package/docs-site-docusaurus/docs/api/classes/FibonacciHeapNode.md +1 -1
  12. package/docs-site-docusaurus/docs/api/classes/HashMap.md +14 -14
  13. package/docs-site-docusaurus/docs/api/classes/Heap.md +117 -34
  14. package/docs-site-docusaurus/docs/api/classes/IterableElementBase.md +83 -13
  15. package/docs-site-docusaurus/docs/api/classes/LinearBase.md +124 -20
  16. package/docs-site-docusaurus/docs/api/classes/LinearLinkedBase.md +140 -32
  17. package/docs-site-docusaurus/docs/api/classes/LinkedHashMap.md +23 -23
  18. package/docs-site-docusaurus/docs/api/classes/LinkedListQueue.md +159 -51
  19. package/docs-site-docusaurus/docs/api/classes/MapGraph.md +20 -20
  20. package/docs-site-docusaurus/docs/api/classes/Matrix.md +23 -23
  21. package/docs-site-docusaurus/docs/api/classes/MaxHeap.md +117 -34
  22. package/docs-site-docusaurus/docs/api/classes/MaxPriorityQueue.md +117 -34
  23. package/docs-site-docusaurus/docs/api/classes/MinHeap.md +117 -34
  24. package/docs-site-docusaurus/docs/api/classes/MinPriorityQueue.md +117 -34
  25. package/docs-site-docusaurus/docs/api/classes/PriorityQueue.md +117 -34
  26. package/docs-site-docusaurus/docs/api/classes/Queue.md +142 -34
  27. package/docs-site-docusaurus/docs/api/classes/RedBlackTree.md +117 -117
  28. package/docs-site-docusaurus/docs/api/classes/SegmentTree.md +8 -8
  29. package/docs-site-docusaurus/docs/api/classes/SinglyLinkedList.md +158 -50
  30. package/docs-site-docusaurus/docs/api/classes/SkipList.md +21 -21
  31. package/docs-site-docusaurus/docs/api/classes/Stack.md +108 -26
  32. package/docs-site-docusaurus/docs/api/classes/TreeMap.md +33 -33
  33. package/docs-site-docusaurus/docs/api/classes/TreeMultiMap.md +75 -39
  34. package/docs-site-docusaurus/docs/api/classes/TreeSet.md +301 -39
  35. package/docs-site-docusaurus/docs/api/classes/Trie.md +110 -28
  36. package/docs-site-docusaurus/docs/api/classes/UndirectedGraph.md +20 -20
  37. package/package.json +45 -46
  38. package/src/common/error.ts +15 -32
  39. package/src/common/index.ts +0 -3
  40. package/src/data-structures/base/iterable-element-base.ts +0 -3
  41. package/src/data-structures/base/linear-base.ts +2 -36
  42. package/src/data-structures/binary-tree/avl-tree.ts +31 -529
  43. package/src/data-structures/binary-tree/binary-indexed-tree.ts +47 -572
  44. package/src/data-structures/binary-tree/binary-tree.ts +326 -1311
  45. package/src/data-structures/binary-tree/bst.ts +158 -1082
  46. package/src/data-structures/binary-tree/red-black-tree.ts +451 -1290
  47. package/src/data-structures/binary-tree/segment-tree.ts +73 -351
  48. package/src/data-structures/binary-tree/tree-map.ts +462 -5124
  49. package/src/data-structures/binary-tree/tree-multi-map.ts +302 -4914
  50. package/src/data-structures/binary-tree/tree-multi-set.ts +284 -3972
  51. package/src/data-structures/binary-tree/tree-set.ts +338 -4836
  52. package/src/data-structures/graph/abstract-graph.ts +98 -167
  53. package/src/data-structures/graph/directed-graph.ts +137 -562
  54. package/src/data-structures/graph/map-graph.ts +0 -3
  55. package/src/data-structures/graph/undirected-graph.ts +132 -511
  56. package/src/data-structures/hash/hash-map.ts +154 -582
  57. package/src/data-structures/heap/heap.ts +200 -795
  58. package/src/data-structures/linked-list/doubly-linked-list.ts +121 -865
  59. package/src/data-structures/linked-list/singly-linked-list.ts +122 -794
  60. package/src/data-structures/linked-list/skip-linked-list.ts +211 -918
  61. package/src/data-structures/matrix/matrix.ts +179 -518
  62. package/src/data-structures/matrix/navigator.ts +0 -1
  63. package/src/data-structures/priority-queue/max-priority-queue.ts +1 -6
  64. package/src/data-structures/priority-queue/min-priority-queue.ts +6 -11
  65. package/src/data-structures/priority-queue/priority-queue.ts +1 -2
  66. package/src/data-structures/queue/deque.ts +214 -882
  67. package/src/data-structures/queue/queue.ts +102 -625
  68. package/src/data-structures/stack/stack.ts +76 -505
  69. package/src/data-structures/trie/trie.ts +98 -628
  70. package/src/types/common.ts +0 -10
  71. package/src/types/data-structures/binary-tree/bst.ts +0 -7
  72. package/src/types/data-structures/binary-tree/red-black-tree.ts +0 -1
  73. package/src/types/data-structures/graph/abstract-graph.ts +0 -2
  74. package/src/types/data-structures/hash/hash-map.ts +0 -3
  75. package/src/types/data-structures/hash/index.ts +0 -1
  76. package/src/types/data-structures/matrix/navigator.ts +0 -2
  77. package/src/types/utils/utils.ts +0 -7
  78. package/src/types/utils/validate-type.ts +0 -7
  79. package/src/utils/number.ts +0 -2
  80. package/src/utils/utils.ts +0 -5
@@ -10,7 +10,8 @@ import type {
10
10
  BinaryTreeDeleteResult,
11
11
  BinaryTreeOptions,
12
12
  BinaryTreePrintOptions,
13
- BTNEntry, BTNRep,
13
+ BTNEntry,
14
+ BTNRep,
14
15
  DFSOrderPattern,
15
16
  DFSStackItem,
16
17
  EntryCallback,
@@ -272,6 +273,10 @@ export class BinaryTree<K = any, V = any, R = any>
272
273
  implements IBinaryTree<K, V, R>
273
274
  {
274
275
  iterationType: IterationType = 'ITERATIVE';
276
+ protected readonly _isMapMode: boolean = true;
277
+ protected readonly _isDuplicate: boolean = false;
278
+ protected readonly _NIL = new BinaryTreeNode<K, V>(NaN as K);
279
+ protected readonly _toEntryFn?: ToEntryFn<K, V, R>;
275
280
 
276
281
  /**
277
282
  * Creates an instance of BinaryTree.
@@ -299,7 +304,8 @@ export class BinaryTree<K = any, V = any, R = any>
299
304
  if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
300
305
  }
301
306
 
302
- protected readonly _isMapMode: boolean = true;
307
+ // Map mode acceleration store:
308
+ // - isMapMode=false: unused
303
309
 
304
310
  /**
305
311
  * Gets whether the tree is in Map mode.
@@ -311,8 +317,6 @@ export class BinaryTree<K = any, V = any, R = any>
311
317
  return this._isMapMode;
312
318
  }
313
319
 
314
- protected readonly _isDuplicate: boolean = false;
315
-
316
320
  /**
317
321
  * Gets whether the tree allows duplicate keys.
318
322
  * @remarks Time O(1)
@@ -323,8 +327,6 @@ export class BinaryTree<K = any, V = any, R = any>
323
327
  return this._isDuplicate;
324
328
  }
325
329
 
326
- // Map mode acceleration store:
327
- // - isMapMode=false: unused
328
330
  // - isMapMode=true: key -> node reference (O(1) has/getNode + fast get)
329
331
  protected _store = new Map<K, BinaryTreeNode<K, V>>();
330
332
 
@@ -362,8 +364,6 @@ export class BinaryTree<K = any, V = any, R = any>
362
364
  return this._size;
363
365
  }
364
366
 
365
- protected readonly _NIL = new BinaryTreeNode<K, V>(NaN as K);
366
-
367
367
  /**
368
368
  * Gets the sentinel NIL node (used in self-balancing trees like Red-Black Tree).
369
369
  * @remarks Time O(1)
@@ -374,8 +374,6 @@ export class BinaryTree<K = any, V = any, R = any>
374
374
  return this._NIL;
375
375
  }
376
376
 
377
- protected readonly _toEntryFn?: ToEntryFn<K, V, R>;
378
-
379
377
  /**
380
378
  * Gets the function used to convert raw data objects (R) into [key, value] entries.
381
379
  * @remarks Time O(1)
@@ -386,6 +384,39 @@ export class BinaryTree<K = any, V = any, R = any>
386
384
  return this._toEntryFn;
387
385
  }
388
386
 
387
+ protected static _buildNodeDisplay(line: string, width: number, left: NodeDisplayLayout, right: NodeDisplayLayout) {
388
+ const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
389
+ const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
390
+ const firstLine =
391
+ ' '.repeat(Math.max(0, leftMiddle + 1)) +
392
+ '_'.repeat(Math.max(0, leftWidth - leftMiddle - 1)) +
393
+ line +
394
+ '_'.repeat(Math.max(0, rightMiddle)) +
395
+ ' '.repeat(Math.max(0, rightWidth - rightMiddle));
396
+
397
+ const secondLine =
398
+ (leftHeight > 0 ? ' '.repeat(leftMiddle) + '/' + ' '.repeat(leftWidth - leftMiddle - 1) : ' '.repeat(leftWidth)) +
399
+ ' '.repeat(width) +
400
+ (rightHeight > 0
401
+ ? ' '.repeat(rightMiddle) + '\\' + ' '.repeat(rightWidth - rightMiddle - 1)
402
+ : ' '.repeat(rightWidth));
403
+
404
+ const mergedLines = [firstLine, secondLine];
405
+
406
+ for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
407
+ const leftLine = i < leftHeight ? leftLines[i] : ' '.repeat(leftWidth);
408
+ const rightLine = i < rightHeight ? rightLines[i] : ' '.repeat(rightWidth);
409
+ mergedLines.push(leftLine + ' '.repeat(width) + rightLine);
410
+ }
411
+
412
+ return <NodeDisplayLayout>[
413
+ mergedLines,
414
+ leftWidth + width + rightWidth,
415
+ Math.max(leftHeight, rightHeight) + 2,
416
+ leftWidth + Math.floor(width / 2)
417
+ ];
418
+ }
419
+
389
420
  /**
390
421
  * (Protected) Creates a new node.
391
422
  * @remarks Time O(1), Space O(1)
@@ -566,55 +597,16 @@ export class BinaryTree<K = any, V = any, R = any>
566
597
  *
567
598
  * @param keyNodeOrEntry - The key, node, or entry to add.
568
599
  * @returns True if the addition was successful, false otherwise.
569
-
570
-
571
-
572
-
573
-
574
-
575
-
576
-
577
-
578
-
579
-
580
-
581
-
582
-
583
-
584
-
585
-
586
-
587
-
588
-
589
-
590
-
591
-
592
-
593
-
594
-
595
-
596
-
597
-
598
-
599
-
600
-
601
-
602
-
603
-
604
-
605
-
606
- * @example
607
- * // Add a single node
608
- * const tree = new BinaryTree<number>();
609
- * tree.add(1);
610
- * tree.add(2);
611
- * tree.add(3);
612
- * console.log(tree.size); // 3;
613
- * console.log(tree.has(1)); // true;
614
- */
615
- add(
616
- keyNodeOrEntry: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined
617
- ): boolean {
600
+ * @example
601
+ * // Add a single node
602
+ * const tree = new BinaryTree<number>();
603
+ * tree.add(1);
604
+ * tree.add(2);
605
+ * tree.add(3);
606
+ * console.log(tree.size); // 3;
607
+ * console.log(tree.has(1)); // true;
608
+ */
609
+ add(keyNodeOrEntry: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): boolean {
618
610
  return this.set(keyNodeOrEntry);
619
611
  }
620
612
 
@@ -625,77 +617,34 @@ export class BinaryTree<K = any, V = any, R = any>
625
617
  * @param keyNodeOrEntry - The key, node, or entry to set or update.
626
618
  * @param [value] - The value, if providing just a key.
627
619
  * @returns True if the addition was successful, false otherwise.
628
-
629
-
630
-
631
-
632
-
633
-
634
-
635
-
636
-
637
-
638
-
639
-
640
-
641
-
642
-
643
-
644
-
645
-
646
-
647
-
648
-
649
-
650
-
651
-
652
-
653
-
654
-
655
-
656
-
657
-
658
-
659
-
660
-
661
-
662
-
663
-
664
-
665
-
666
-
667
-
668
-
669
-
670
- * @example
671
- * // basic BinaryTree creation and insertion
672
- * // Create a BinaryTree with entries
673
- * const entries: [number, string][] = [
674
- * [6, 'six'],
675
- * [1, 'one'],
676
- * [2, 'two'],
677
- * [7, 'seven'],
678
- * [5, 'five'],
679
- * [3, 'three'],
680
- * [4, 'four'],
681
- * [9, 'nine'],
682
- * [8, 'eight']
683
- * ];
684
- *
685
- * const tree = new BinaryTree(entries);
686
- *
687
- * // Verify size
688
- * console.log(tree.size); // 9;
689
- *
690
- * // Add new element
691
- * tree.set(10, 'ten');
692
- * console.log(tree.size); // 10;
620
+ * @example
621
+ * // basic BinaryTree creation and insertion
622
+ * // Create a BinaryTree with entries
623
+ * const entries: [number, string][] = [
624
+ * [6, 'six'],
625
+ * [1, 'one'],
626
+ * [2, 'two'],
627
+ * [7, 'seven'],
628
+ * [5, 'five'],
629
+ * [3, 'three'],
630
+ * [4, 'four'],
631
+ * [9, 'nine'],
632
+ * [8, 'eight']
633
+ * ];
634
+ *
635
+ * const tree = new BinaryTree(entries);
636
+ *
637
+ * // Verify size
638
+ * console.log(tree.size); // 9;
639
+ *
640
+ * // Add new element
641
+ * tree.set(10, 'ten');
642
+ * console.log(tree.size); // 10;
693
643
  */
694
644
  set(
695
645
  keyNodeOrEntry: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
696
646
  value?: V
697
647
  ): boolean {
698
-
699
648
  const [newNode] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
700
649
  if (newNode === undefined) return false;
701
650
 
@@ -753,51 +702,11 @@ export class BinaryTree<K = any, V = any, R = any>
753
702
  *
754
703
  * @param keysNodesEntriesOrRaws - An iterable of items to set.
755
704
  * @returns An array of booleans indicating the success of each individual `set` operation.
756
-
757
-
758
-
759
-
760
-
761
-
762
-
763
-
764
-
765
-
766
-
767
-
768
-
769
-
770
-
771
-
772
-
773
-
774
-
775
-
776
-
777
-
778
-
779
-
780
-
781
-
782
-
783
-
784
-
785
-
786
-
787
-
788
-
789
-
790
-
791
-
792
-
793
-
794
-
795
-
796
- * @example
797
- * // Bulk add
798
- * const tree = new BinaryTree<number>();
799
- * tree.addMany([1, 2, 3, 4, 5]);
800
- * console.log(tree.size); // 5;
705
+ * @example
706
+ * // Bulk add
707
+ * const tree = new BinaryTree<number>();
708
+ * tree.addMany([1, 2, 3, 4, 5]);
709
+ * console.log(tree.size); // 5;
801
710
  */
802
711
  addMany(
803
712
  keysNodesEntriesOrRaws: Iterable<
@@ -814,44 +723,15 @@ export class BinaryTree<K = any, V = any, R = any>
814
723
  * @param keysNodesEntriesOrRaws - An iterable of items to set or update.
815
724
  * @param [values] - An optional parallel iterable of values.
816
725
  * @returns An array of booleans indicating the success of each individual `set` operation.
817
-
818
-
819
-
820
-
821
-
822
-
823
-
824
-
825
-
826
-
827
-
828
-
829
-
830
-
831
-
832
-
833
-
834
-
835
-
836
-
837
-
838
-
839
-
840
-
841
-
842
-
843
-
844
-
845
-
846
-
847
-
848
-
849
-
850
- * @example
851
- * // Set multiple entries
852
- * const tree = new BinaryTree<number, string>();
853
- * tree.setMany([[1, 'a'], [2, 'b'], [3, 'c']]);
854
- * console.log(tree.size); // 3;
726
+ * @example
727
+ * // Set multiple entries
728
+ * const tree = new BinaryTree<number, string>();
729
+ * tree.setMany([
730
+ * [1, 'a'],
731
+ * [2, 'b'],
732
+ * [3, 'c']
733
+ * ]);
734
+ * console.log(tree.size); // 3;
855
735
  */
856
736
  setMany(
857
737
  keysNodesEntriesOrRaws: Iterable<
@@ -887,172 +767,29 @@ export class BinaryTree<K = any, V = any, R = any>
887
767
  * @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`).
888
768
  *
889
769
  * @param anotherTree - The tree to merge.
890
-
891
-
892
-
893
-
894
-
895
-
896
-
897
-
898
-
899
-
900
-
901
-
902
-
903
-
904
-
905
-
906
-
907
-
908
-
909
-
910
-
911
-
912
-
913
-
914
-
915
-
916
-
917
-
918
-
919
-
920
-
921
-
922
-
923
-
924
-
925
-
926
-
927
-
928
-
929
-
930
- * @example
931
- * // Combine trees
932
- * const t1 = new BinaryTree<number>([1, 2]);
933
- * const t2 = new BinaryTree<number>([3, 4]);
934
- * t1.merge(t2);
935
- * console.log(t1.size); // 4;
770
+ * @example
771
+ * // Combine trees
772
+ * const t1 = new BinaryTree<number>([1, 2]);
773
+ * const t2 = new BinaryTree<number>([3, 4]);
774
+ * t1.merge(t2);
775
+ * console.log(t1.size); // 4;
936
776
  */
937
777
  merge(anotherTree: BinaryTree<K, V, R>) {
938
778
  this.setMany(anotherTree, []);
939
779
  }
940
780
 
941
- /**
942
- * Deletes a node from the tree (internal, returns balancing metadata).
943
- * @remarks Time O(N) — O(N) to find the node + O(H) for predecessor swap. Space O(1). BST/Red-Black Tree/AVL Tree subclasses override to O(log N).
944
- * @internal Used by AVL/BST subclasses that need balancing metadata after deletion.
945
- *
946
- * @param keyNodeEntryRawOrPredicate - The node to delete.
947
- * @returns An array containing deletion results with balancing metadata.
948
- */
949
- protected _deleteInternal(
950
- keyNodeEntryRawOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V> | null>
951
- ): BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[] {
952
- const deletedResult: BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[] = [];
953
- if (!this._root) return deletedResult;
954
-
955
- const curr = this.getNode(keyNodeEntryRawOrPredicate);
956
- if (!curr) return deletedResult;
957
-
958
- const parent: BinaryTreeNode<K, V> | undefined = curr?.parent;
959
- let needBalanced: BinaryTreeNode<K, V> | undefined;
960
- let orgCurrent: BinaryTreeNode<K, V> | undefined = curr;
961
-
962
- if (!curr.left && !curr.right && !parent) {
963
- this._setRoot(undefined);
964
- } else if (curr.left) {
965
- const leftSubTreeRightMost = this.getRightMost(node => node, curr.left);
966
- if (leftSubTreeRightMost) {
967
- const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
968
- orgCurrent = this._swapProperties(curr, leftSubTreeRightMost);
969
-
970
- if (this._isMapMode) {
971
- this._store.set(curr.key, curr);
972
- this._store.set(leftSubTreeRightMost.key, leftSubTreeRightMost);
973
- }
974
-
975
- if (parentOfLeftSubTreeMax) {
976
- if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
977
- parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
978
- else parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left;
979
- needBalanced = parentOfLeftSubTreeMax;
980
- }
981
- }
982
- } else if (parent) {
983
- const { familyPosition: fp } = curr;
984
- if (fp === 'LEFT' || fp === 'ROOT_LEFT') {
985
- parent.left = curr.right;
986
- } else if (fp === 'RIGHT' || fp === 'ROOT_RIGHT') {
987
- parent.right = curr.right;
988
- }
989
- needBalanced = parent;
990
- } else {
991
- this._setRoot(curr.right);
992
- curr.right = undefined;
993
- }
994
-
995
- this._size = this._size - 1;
996
-
997
- deletedResult.push({ deleted: orgCurrent, needBalanced });
998
- if (this._isMapMode && orgCurrent) this._store.delete(orgCurrent.key);
999
- return deletedResult;
1000
- }
1001
-
1002
781
  /**
1003
782
  * Deletes a node from the tree.
1004
783
  * @remarks Time O(N) — O(N) to find the node + O(H) for predecessor swap. Space O(1). BST/Red-Black Tree/AVL Tree subclasses override to O(log N).
1005
784
  *
1006
785
  * @param keyNodeEntryRawOrPredicate - The node to delete.
1007
786
  * @returns True if the node was found and deleted, false otherwise.
1008
-
1009
-
1010
-
1011
-
1012
-
1013
-
1014
-
1015
-
1016
-
1017
-
1018
-
1019
-
1020
-
1021
-
1022
-
1023
-
1024
-
1025
-
1026
-
1027
-
1028
-
1029
-
1030
-
1031
-
1032
-
1033
-
1034
-
1035
-
1036
-
1037
-
1038
-
1039
-
1040
-
1041
-
1042
-
1043
-
1044
-
1045
-
1046
-
1047
-
1048
-
1049
-
1050
- * @example
1051
- * // Remove a node
1052
- * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
1053
- * tree.delete(3);
1054
- * console.log(tree.has(3)); // false;
1055
- * console.log(tree.size); // 4;
787
+ * @example
788
+ * // Remove a node
789
+ * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
790
+ * tree.delete(3);
791
+ * console.log(tree.has(3)); // false;
792
+ * console.log(tree.size); // 4;
1056
793
  */
1057
794
  delete(
1058
795
  keyNodeEntryRawOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V> | null>
@@ -1060,46 +797,13 @@ export class BinaryTree<K = any, V = any, R = any>
1060
797
  return this._deleteInternal(keyNodeEntryRawOrPredicate).length > 0;
1061
798
  }
1062
799
 
1063
- /**
800
+ /**
1064
801
  * Search by predicate
1065
-
1066
-
1067
-
1068
-
1069
-
1070
-
1071
-
1072
-
1073
-
1074
-
1075
-
1076
-
1077
-
1078
-
1079
-
1080
-
1081
-
1082
-
1083
-
1084
-
1085
-
1086
-
1087
-
1088
-
1089
-
1090
-
1091
-
1092
-
1093
-
1094
-
1095
-
1096
-
1097
-
1098
- * @example
1099
- * // Search by predicate
1100
- * const tree = new BinaryTree<number>([5, 3, 7, 1, 9]);
1101
- * const found = tree.search(n => n!.key > 5, true);
1102
- * console.log(found.length); // >= 1;
802
+ * @example
803
+ * // Search by predicate
804
+ * const tree = new BinaryTree<number>([5, 3, 7, 1, 9]);
805
+ * const found = tree.search(n => n!.key > 5, true);
806
+ * console.log(found.length); // >= 1;
1103
807
  */
1104
808
  search(
1105
809
  keyNodeEntryOrPredicate:
@@ -1199,50 +903,11 @@ export class BinaryTree<K = any, V = any, R = any>
1199
903
  * @param [startNode=this._root] - The node to start the search from.
1200
904
  * @param [iterationType=this.iterationType] - The traversal method.
1201
905
  * @returns An array of matching nodes.
1202
-
1203
-
1204
-
1205
-
1206
-
1207
-
1208
-
1209
-
1210
-
1211
-
1212
-
1213
-
1214
-
1215
-
1216
-
1217
-
1218
-
1219
-
1220
-
1221
-
1222
-
1223
-
1224
-
1225
-
1226
-
1227
-
1228
-
1229
-
1230
-
1231
-
1232
-
1233
-
1234
-
1235
-
1236
-
1237
-
1238
-
1239
-
1240
-
1241
- * @example
1242
- * // Get nodes by condition
1243
- * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
1244
- * const nodes = tree.getNodes(node => node.key > 3);
1245
- * console.log(nodes.length); // 2;
906
+ * @example
907
+ * // Get nodes by condition
908
+ * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
909
+ * const nodes = tree.getNodes(node => node.key > 3);
910
+ * console.log(nodes.length); // 2;
1246
911
  */
1247
912
  getNodes(
1248
913
  keyNodeEntryOrPredicate:
@@ -1280,50 +945,13 @@ export class BinaryTree<K = any, V = any, R = any>
1280
945
  * @param [startNode=this._root] - The node to start the search from.
1281
946
  * @param [iterationType=this.iterationType] - The traversal method.
1282
947
  * @returns The first matching node, or undefined if not found.
1283
-
1284
-
1285
-
1286
-
1287
-
1288
-
1289
-
1290
-
1291
-
1292
-
1293
-
1294
-
1295
-
1296
-
1297
-
1298
-
1299
-
1300
-
1301
-
1302
-
1303
-
1304
-
1305
-
1306
-
1307
-
1308
-
1309
-
1310
-
1311
-
1312
-
1313
-
1314
-
1315
-
1316
-
1317
-
1318
-
1319
-
1320
-
1321
-
1322
-
1323
- * @example
1324
- * // Get node by key
1325
- * const tree = new BinaryTree<number, string>([[1, 'root'], [2, 'child']]);
1326
- * console.log(tree.getNode(2)?.value); // 'child';
948
+ * @example
949
+ * // Get node by key
950
+ * const tree = new BinaryTree<number, string>([
951
+ * [1, 'root'],
952
+ * [2, 'child']
953
+ * ]);
954
+ * console.log(tree.getNode(2)?.value); // 'child';
1327
955
  */
1328
956
  getNode(
1329
957
  keyNodeEntryOrPredicate:
@@ -1354,53 +982,15 @@ export class BinaryTree<K = any, V = any, R = any>
1354
982
  * @param [startNode=this._root] - The node to start searching from (if not in Map mode).
1355
983
  * @param [iterationType=this.iterationType] - The traversal method (if not in Map mode).
1356
984
  * @returns The associated value, or undefined.
1357
-
1358
-
1359
-
1360
-
1361
-
1362
-
1363
-
1364
-
1365
-
1366
-
1367
-
1368
-
1369
-
1370
-
1371
-
1372
-
1373
-
1374
-
1375
-
1376
-
1377
-
1378
-
1379
-
1380
-
1381
-
1382
-
1383
-
1384
-
1385
-
1386
-
1387
-
1388
-
1389
-
1390
-
1391
-
1392
-
1393
-
1394
-
1395
-
1396
-
1397
-
1398
-
1399
- * @example
1400
- * // Retrieve value by key
1401
- * const tree = new BinaryTree<number, string>([[1, 'root'], [2, 'left'], [3, 'right']]);
1402
- * console.log(tree.get(2)); // 'left';
1403
- * console.log(tree.get(99)); // undefined;
985
+ * @example
986
+ * // Retrieve value by key
987
+ * const tree = new BinaryTree<number, string>([
988
+ * [1, 'root'],
989
+ * [2, 'left'],
990
+ * [3, 'right']
991
+ * ]);
992
+ * console.log(tree.get(2)); // 'left';
993
+ * console.log(tree.get(99)); // undefined;
1404
994
  */
1405
995
  override get(
1406
996
  keyNodeEntryOrPredicate: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
@@ -1423,76 +1013,34 @@ export class BinaryTree<K = any, V = any, R = any>
1423
1013
  * @param [startNode] - The node to start the search from.
1424
1014
  * @param [iterationType] - The traversal method.
1425
1015
  * @returns True if a matching node exists, false otherwise.
1426
-
1427
-
1428
-
1429
-
1430
-
1431
-
1432
-
1433
-
1434
-
1435
-
1436
-
1437
-
1438
-
1439
-
1440
-
1441
-
1442
-
1443
-
1444
-
1445
-
1446
-
1447
-
1448
-
1449
-
1450
-
1451
-
1452
-
1453
-
1454
-
1455
-
1456
-
1457
-
1458
-
1459
-
1460
-
1461
-
1462
-
1463
-
1464
-
1465
-
1466
-
1467
-
1468
- * @example
1469
- * // BinaryTree get and has operations
1470
- * const tree = new BinaryTree(
1471
- * [
1472
- * [5, 'five'],
1473
- * [3, 'three'],
1474
- * [7, 'seven'],
1475
- * [1, 'one'],
1476
- * [4, 'four'],
1477
- * [6, 'six'],
1478
- * [8, 'eight']
1479
- * ],
1480
- * { isMapMode: false }
1481
- * );
1482
- *
1483
- * // Check if key exists
1484
- * console.log(tree.has(5)); // true;
1485
- * console.log(tree.has(10)); // false;
1486
- *
1487
- * // Get value by key
1488
- * console.log(tree.get(3)); // 'three';
1489
- * console.log(tree.get(7)); // 'seven';
1490
- * console.log(tree.get(100)); // undefined;
1491
- *
1492
- * // Get node structure
1493
- * const node = tree.getNode(5);
1494
- * console.log(node?.key); // 5;
1495
- * console.log(node?.value); // 'five';
1016
+ * @example
1017
+ * // BinaryTree get and has operations
1018
+ * const tree = new BinaryTree(
1019
+ * [
1020
+ * [5, 'five'],
1021
+ * [3, 'three'],
1022
+ * [7, 'seven'],
1023
+ * [1, 'one'],
1024
+ * [4, 'four'],
1025
+ * [6, 'six'],
1026
+ * [8, 'eight']
1027
+ * ],
1028
+ * { isMapMode: false }
1029
+ * );
1030
+ *
1031
+ * // Check if key exists
1032
+ * console.log(tree.has(5)); // true;
1033
+ * console.log(tree.has(10)); // false;
1034
+ *
1035
+ * // Get value by key
1036
+ * console.log(tree.get(3)); // 'three';
1037
+ * console.log(tree.get(7)); // 'seven';
1038
+ * console.log(tree.get(100)); // undefined;
1039
+ *
1040
+ * // Get node structure
1041
+ * const node = tree.getNode(5);
1042
+ * console.log(node?.key); // 5;
1043
+ * console.log(node?.value); // 'five';
1496
1044
  */
1497
1045
  override has(
1498
1046
  keyNodeEntryOrPredicate?:
@@ -1530,51 +1078,11 @@ export class BinaryTree<K = any, V = any, R = any>
1530
1078
  /**
1531
1079
  * Clears the tree of all nodes and values.
1532
1080
  * @remarks Time O(N) if in Map mode (due to `_store.clear()`), O(1) otherwise. Space O(1)
1533
-
1534
-
1535
-
1536
-
1537
-
1538
-
1539
-
1540
-
1541
-
1542
-
1543
-
1544
-
1545
-
1546
-
1547
-
1548
-
1549
-
1550
-
1551
-
1552
-
1553
-
1554
-
1555
-
1556
-
1557
-
1558
-
1559
-
1560
-
1561
-
1562
-
1563
-
1564
-
1565
-
1566
-
1567
-
1568
-
1569
-
1570
-
1571
-
1572
-
1573
- * @example
1574
- * // Remove all nodes
1575
- * const tree = new BinaryTree<number>([1, 2, 3]);
1576
- * tree.clear();
1577
- * console.log(tree.isEmpty()); // true;
1081
+ * @example
1082
+ * // Remove all nodes
1083
+ * const tree = new BinaryTree<number>([1, 2, 3]);
1084
+ * tree.clear();
1085
+ * console.log(tree.isEmpty()); // true;
1578
1086
  */
1579
1087
  clear() {
1580
1088
  this._clearNodes();
@@ -1586,49 +1094,9 @@ export class BinaryTree<K = any, V = any, R = any>
1586
1094
  * @remarks Time O(1), Space O(1)
1587
1095
  *
1588
1096
  * @returns True if the tree has no nodes, false otherwise.
1589
-
1590
-
1591
-
1592
-
1593
-
1594
-
1595
-
1596
-
1597
-
1598
-
1599
-
1600
-
1601
-
1602
-
1603
-
1604
-
1605
-
1606
-
1607
-
1608
-
1609
-
1610
-
1611
-
1612
-
1613
-
1614
-
1615
-
1616
-
1617
-
1618
-
1619
-
1620
-
1621
-
1622
-
1623
-
1624
-
1625
-
1626
-
1627
-
1628
-
1629
- * @example
1630
- * // Check empty
1631
- * console.log(new BinaryTree().isEmpty()); // true;
1097
+ * @example
1098
+ * // Check empty
1099
+ * console.log(new BinaryTree().isEmpty()); // true;
1632
1100
  */
1633
1101
  isEmpty(): boolean {
1634
1102
  return this._size === 0;
@@ -1654,51 +1122,11 @@ export class BinaryTree<K = any, V = any, R = any>
1654
1122
  * @param [startNode=this._root] - The node to start checking from.
1655
1123
  * @param [iterationType=this.iterationType] - The traversal method.
1656
1124
  * @returns True if it's a valid BST, false otherwise.
1657
-
1658
-
1659
-
1660
-
1661
-
1662
-
1663
-
1664
-
1665
-
1666
-
1667
-
1668
-
1669
-
1670
-
1671
-
1672
-
1673
-
1674
-
1675
-
1676
-
1677
-
1678
-
1679
-
1680
-
1681
-
1682
-
1683
-
1684
-
1685
-
1686
-
1687
-
1688
-
1689
-
1690
-
1691
-
1692
-
1693
-
1694
-
1695
-
1696
-
1697
- * @example
1698
- * // Check BST property
1699
- * const tree = new BinaryTree<number>([1, 2, 3]);
1700
- * // BinaryTree doesn't guarantee BST order
1701
- * console.log(typeof tree.isBST()); // 'boolean';
1125
+ * @example
1126
+ * // Check BST property
1127
+ * const tree = new BinaryTree<number>([1, 2, 3]);
1128
+ * // BinaryTree doesn't guarantee BST order
1129
+ * console.log(typeof tree.isBST()); // 'boolean';
1702
1130
  */
1703
1131
  isBST(
1704
1132
  startNode: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined = this._root,
@@ -1750,53 +1178,11 @@ export class BinaryTree<K = any, V = any, R = any>
1750
1178
  * @param dist - The node to find the depth of.
1751
1179
  * @param [startNode=this._root] - The node to measure depth from (defaults to root).
1752
1180
  * @returns The depth (0 if `dist` is `startNode`).
1753
-
1754
-
1755
-
1756
-
1757
-
1758
-
1759
-
1760
-
1761
-
1762
-
1763
-
1764
-
1765
-
1766
-
1767
-
1768
-
1769
-
1770
-
1771
-
1772
-
1773
-
1774
-
1775
-
1776
-
1777
-
1778
-
1779
-
1780
-
1781
-
1782
-
1783
-
1784
-
1785
-
1786
-
1787
-
1788
-
1789
-
1790
-
1791
-
1792
-
1793
-
1794
-
1795
- * @example
1796
- * // Get depth of a node
1797
- * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
1798
- * const node = tree.getNode(4);
1799
- * console.log(tree.getDepth(node!)); // 2;
1181
+ * @example
1182
+ * // Get depth of a node
1183
+ * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
1184
+ * const node = tree.getNode(4);
1185
+ * console.log(tree.getDepth(node!)); // 2;
1800
1186
  */
1801
1187
  getDepth(
1802
1188
  dist: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
@@ -1822,52 +1208,10 @@ export class BinaryTree<K = any, V = any, R = any>
1822
1208
  * @param [startNode=this._root] - The node to start measuring from.
1823
1209
  * @param [iterationType=this.iterationType] - The traversal method.
1824
1210
  * @returns The height ( -1 for an empty tree, 0 for a single-node tree).
1825
-
1826
-
1827
-
1828
-
1829
-
1830
-
1831
-
1832
-
1833
-
1834
-
1835
-
1836
-
1837
-
1838
-
1839
-
1840
-
1841
-
1842
-
1843
-
1844
-
1845
-
1846
-
1847
-
1848
-
1849
-
1850
-
1851
-
1852
-
1853
-
1854
-
1855
-
1856
-
1857
-
1858
-
1859
-
1860
-
1861
-
1862
-
1863
-
1864
-
1865
-
1866
-
1867
- * @example
1868
- * // Get tree height
1869
- * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
1870
- * console.log(tree.getHeight()); // 2;
1211
+ * @example
1212
+ * // Get tree height
1213
+ * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
1214
+ * console.log(tree.getHeight()); // 2;
1871
1215
  */
1872
1216
  getHeight(
1873
1217
  startNode: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined = this._root,
@@ -2133,55 +1477,13 @@ export class BinaryTree<K = any, V = any, R = any>
2133
1477
  return y;
2134
1478
  }
2135
1479
 
2136
- /**
1480
+ /**
2137
1481
  * Depth-first search traversal
2138
-
2139
-
2140
-
2141
-
2142
-
2143
-
2144
-
2145
-
2146
-
2147
-
2148
-
2149
-
2150
-
2151
-
2152
-
2153
-
2154
-
2155
-
2156
-
2157
-
2158
-
2159
-
2160
-
2161
-
2162
-
2163
-
2164
-
2165
-
2166
-
2167
-
2168
-
2169
-
2170
-
2171
-
2172
-
2173
-
2174
-
2175
-
2176
-
2177
-
2178
-
2179
-
2180
- * @example
2181
- * // Depth-first search traversal
2182
- * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
2183
- * const inOrder = tree.dfs(node => node.key, 'IN');
2184
- * console.log(inOrder); // [4, 2, 5, 1, 3];
1482
+ * @example
1483
+ * // Depth-first search traversal
1484
+ * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
1485
+ * const inOrder = tree.dfs(node => node.key, 'IN');
1486
+ * console.log(inOrder); // [4, 2, 5, 1, 3];
2185
1487
  */
2186
1488
  dfs(): (K | undefined)[];
2187
1489
 
@@ -2228,77 +1530,35 @@ export class BinaryTree<K = any, V = any, R = any>
2228
1530
  return this._dfs(callback, pattern, onlyOne, startNode, iterationType, includeNull);
2229
1531
  }
2230
1532
 
2231
- /**
1533
+ /**
2232
1534
  * BinaryTree level-order traversal
2233
-
2234
-
2235
-
2236
-
2237
-
2238
-
2239
-
2240
-
2241
-
2242
-
2243
-
2244
-
2245
-
2246
-
2247
-
2248
-
2249
-
2250
-
2251
-
2252
-
2253
-
2254
-
2255
-
2256
-
2257
-
2258
-
2259
-
2260
-
2261
-
2262
-
2263
-
2264
-
2265
-
2266
-
2267
-
2268
-
2269
-
2270
-
2271
-
2272
-
2273
-
2274
-
2275
- * @example
2276
- * // BinaryTree level-order traversal
2277
- * const tree = new BinaryTree([
2278
- * [1, 'one'],
2279
- * [2, 'two'],
2280
- * [3, 'three'],
2281
- * [4, 'four'],
2282
- * [5, 'five'],
2283
- * [6, 'six'],
2284
- * [7, 'seven']
2285
- * ]);
2286
- *
2287
- * // Binary tree maintains level-order insertion
2288
- * // Complete binary tree structure
2289
- * console.log(tree.size); // 7;
2290
- *
2291
- * // Verify all keys are present
2292
- * console.log(tree.has(1)); // true;
2293
- * console.log(tree.has(4)); // true;
2294
- * console.log(tree.has(7)); // true;
2295
- *
2296
- * // Iterate through tree
2297
- * const keys: number[] = [];
2298
- * for (const [key] of tree) {
2299
- * keys.push(key);
2300
- * }
2301
- * console.log(keys.length); // 7;
1535
+ * @example
1536
+ * // BinaryTree level-order traversal
1537
+ * const tree = new BinaryTree([
1538
+ * [1, 'one'],
1539
+ * [2, 'two'],
1540
+ * [3, 'three'],
1541
+ * [4, 'four'],
1542
+ * [5, 'five'],
1543
+ * [6, 'six'],
1544
+ * [7, 'seven']
1545
+ * ]);
1546
+ *
1547
+ * // Binary tree maintains level-order insertion
1548
+ * // Complete binary tree structure
1549
+ * console.log(tree.size); // 7;
1550
+ *
1551
+ * // Verify all keys are present
1552
+ * console.log(tree.has(1)); // true;
1553
+ * console.log(tree.has(4)); // true;
1554
+ * console.log(tree.has(7)); // true;
1555
+ *
1556
+ * // Iterate through tree
1557
+ * const keys: number[] = [];
1558
+ * for (const [key] of tree) {
1559
+ * keys.push(key);
1560
+ * }
1561
+ * console.log(keys.length); // 7;
2302
1562
  */
2303
1563
  bfs(): (K | undefined)[];
2304
1564
 
@@ -2384,53 +1644,13 @@ export class BinaryTree<K = any, V = any, R = any>
2384
1644
  return ans;
2385
1645
  }
2386
1646
 
2387
- /**
1647
+ /**
2388
1648
  * Get leaf nodes
2389
-
2390
-
2391
-
2392
-
2393
-
2394
-
2395
-
2396
-
2397
-
2398
-
2399
-
2400
-
2401
-
2402
-
2403
-
2404
-
2405
-
2406
-
2407
-
2408
-
2409
-
2410
-
2411
-
2412
-
2413
-
2414
-
2415
-
2416
-
2417
-
2418
-
2419
-
2420
-
2421
-
2422
-
2423
-
2424
-
2425
-
2426
-
2427
-
2428
-
2429
- * @example
2430
- * // Get leaf nodes
2431
- * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
2432
- * const leafKeys = tree.leaves(node => node.key);
2433
- * console.log(leafKeys.length); // > 0;
1649
+ * @example
1650
+ * // Get leaf nodes
1651
+ * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
1652
+ * const leafKeys = tree.leaves(node => node.key);
1653
+ * console.log(leafKeys.length); // > 0;
2434
1654
  */
2435
1655
  leaves(): (K | undefined)[];
2436
1656
 
@@ -2492,53 +1712,14 @@ export class BinaryTree<K = any, V = any, R = any>
2492
1712
  return leaves;
2493
1713
  }
2494
1714
 
2495
- /**
1715
+ /**
2496
1716
  * Level-order grouping
2497
-
2498
-
2499
-
2500
-
2501
-
2502
-
2503
-
2504
-
2505
-
2506
-
2507
-
2508
-
2509
-
2510
-
2511
-
2512
-
2513
-
2514
-
2515
-
2516
-
2517
-
2518
-
2519
-
2520
-
2521
-
2522
-
2523
-
2524
-
2525
-
2526
-
2527
-
2528
-
2529
-
2530
-
2531
-
2532
-
2533
-
2534
-
2535
-
2536
- * @example
2537
- * // Level-order grouping
2538
- * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
2539
- * const levels = tree.listLevels(node => node.key);
2540
- * console.log(levels[0]); // [1];
2541
- * console.log(levels[1].sort()); // [2, 3];
1717
+ * @example
1718
+ * // Level-order grouping
1719
+ * const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
1720
+ * const levels = tree.listLevels(node => node.key);
1721
+ * console.log(levels[0]); // [1];
1722
+ * console.log(levels[1].sort()); // [2, 3];
2542
1723
  */
2543
1724
  listLevels(): (K | undefined)[][];
2544
1725
 
@@ -2617,52 +1798,13 @@ export class BinaryTree<K = any, V = any, R = any>
2617
1798
  return levelsNodes;
2618
1799
  }
2619
1800
 
2620
- /**
1801
+ /**
2621
1802
  * Morris traversal (O(1) space)
2622
-
2623
-
2624
-
2625
-
2626
-
2627
-
2628
-
2629
-
2630
-
2631
-
2632
-
2633
-
2634
-
2635
-
2636
-
2637
-
2638
-
2639
-
2640
-
2641
-
2642
-
2643
-
2644
-
2645
-
2646
-
2647
-
2648
-
2649
-
2650
-
2651
-
2652
-
2653
-
2654
-
2655
-
2656
-
2657
-
2658
-
2659
-
2660
-
2661
- * @example
2662
- * // Morris traversal (O(1) space)
2663
- * const tree = new BinaryTree<number>([1, 2, 3]);
2664
- * const result = tree.morris(node => node.key, 'IN');
2665
- * console.log(result.length); // 3;
1803
+ * @example
1804
+ * // Morris traversal (O(1) space)
1805
+ * const tree = new BinaryTree<number>([1, 2, 3]);
1806
+ * const result = tree.morris(node => node.key, 'IN');
1807
+ * console.log(result.length); // 3;
2666
1808
  */
2667
1809
  morris(): (K | undefined)[];
2668
1810
 
@@ -2787,52 +1929,12 @@ export class BinaryTree<K = any, V = any, R = any>
2787
1929
  * @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.
2788
1930
  *
2789
1931
  * @returns A new, cloned instance of the tree.
2790
-
2791
-
2792
-
2793
-
2794
-
2795
-
2796
-
2797
-
2798
-
2799
-
2800
-
2801
-
2802
-
2803
-
2804
-
2805
-
2806
-
2807
-
2808
-
2809
-
2810
-
2811
-
2812
-
2813
-
2814
-
2815
-
2816
-
2817
-
2818
-
2819
-
2820
-
2821
-
2822
-
2823
-
2824
-
2825
-
2826
-
2827
-
2828
-
2829
-
2830
- * @example
2831
- * // Deep copy
2832
- * const tree = new BinaryTree<number>([1, 2, 3]);
2833
- * const copy = tree.clone();
2834
- * copy.delete(1);
2835
- * console.log(tree.has(1)); // true;
1932
+ * @example
1933
+ * // Deep copy
1934
+ * const tree = new BinaryTree<number>([1, 2, 3]);
1935
+ * const copy = tree.clone();
1936
+ * copy.delete(1);
1937
+ * console.log(tree.has(1)); // true;
2836
1938
  */
2837
1939
  clone(): this {
2838
1940
  const out = this._createInstance<K, V, R>();
@@ -2847,51 +1949,11 @@ export class BinaryTree<K = any, V = any, R = any>
2847
1949
  * @param predicate - A function to test each [key, value] pair.
2848
1950
  * @param [thisArg] - `this` context for the predicate.
2849
1951
  * @returns A new, filtered tree.
2850
-
2851
-
2852
-
2853
-
2854
-
2855
-
2856
-
2857
-
2858
-
2859
-
2860
-
2861
-
2862
-
2863
-
2864
-
2865
-
2866
-
2867
-
2868
-
2869
-
2870
-
2871
-
2872
-
2873
-
2874
-
2875
-
2876
-
2877
-
2878
-
2879
-
2880
-
2881
-
2882
-
2883
-
2884
-
2885
-
2886
-
2887
-
2888
-
2889
-
2890
- * @example
2891
- * // Filter nodes by condition
2892
- * const tree = new BinaryTree<number>([1, 2, 3, 4]);
2893
- * const result = tree.filter((_, key) => key > 2);
2894
- * console.log(result.size); // 2;
1952
+ * @example
1953
+ * // Filter nodes by condition
1954
+ * const tree = new BinaryTree<number>([1, 2, 3, 4]);
1955
+ * const result = tree.filter((_, key) => key > 2);
1956
+ * console.log(result.size); // 2;
2895
1957
  */
2896
1958
  filter(predicate: EntryCallback<K, V | undefined, boolean>, thisArg?: unknown): this {
2897
1959
  const out = this._createInstance<K, V, R>();
@@ -2911,51 +1973,14 @@ export class BinaryTree<K = any, V = any, R = any>
2911
1973
  * @param [options] - Options for the new tree.
2912
1974
  * @param [thisArg] - `this` context for the callback.
2913
1975
  * @returns A new, mapped tree.
2914
-
2915
-
2916
-
2917
-
2918
-
2919
-
2920
-
2921
-
2922
-
2923
-
2924
-
2925
-
2926
-
2927
-
2928
-
2929
-
2930
-
2931
-
2932
-
2933
-
2934
-
2935
-
2936
-
2937
-
2938
-
2939
-
2940
-
2941
-
2942
-
2943
-
2944
-
2945
-
2946
-
2947
-
2948
-
2949
-
2950
-
2951
-
2952
-
2953
-
2954
- * @example
2955
- * // Transform to new tree
2956
- * const tree = new BinaryTree<number, number>([[1, 10], [2, 20]]);
2957
- * const mapped = tree.map((v, key) => [key, (v ?? 0) + 1] as [number, number]);
2958
- * console.log([...mapped.values()]); // contains 11;
1976
+ * @example
1977
+ * // Transform to new tree
1978
+ * const tree = new BinaryTree<number, number>([
1979
+ * [1, 10],
1980
+ * [2, 20]
1981
+ * ]);
1982
+ * const mapped = tree.map((v, key) => [key, (v ?? 0) + 1] as [number, number]);
1983
+ * console.log([...mapped.values()]); // contains 11;
2959
1984
  */
2960
1985
  map<MK = K, MV = V, MR = any>(
2961
1986
  cb: EntryCallback<K, V | undefined, [MK, MV]>,
@@ -3008,50 +2033,10 @@ export class BinaryTree<K = any, V = any, R = any>
3008
2033
  *
3009
2034
  * @param [options] - Options to control the output.
3010
2035
  * @param [startNode=this._root] - The node to start printing from.
3011
-
3012
-
3013
-
3014
-
3015
-
3016
-
3017
-
3018
-
3019
-
3020
-
3021
-
3022
-
3023
-
3024
-
3025
-
3026
-
3027
-
3028
-
3029
-
3030
-
3031
-
3032
-
3033
-
3034
-
3035
-
3036
-
3037
-
3038
-
3039
-
3040
-
3041
-
3042
-
3043
-
3044
-
3045
-
3046
-
3047
-
3048
-
3049
-
3050
-
3051
- * @example
3052
- * // Display tree
3053
- * const tree = new BinaryTree<number>([1, 2, 3]);
3054
- * expect(() => tree.print()).not.toThrow();
2036
+ * @example
2037
+ * // Display tree
2038
+ * const tree = new BinaryTree<number>([1, 2, 3]);
2039
+ * expect(() => tree.print()).not.toThrow();
3055
2040
  */
3056
2041
  override print(
3057
2042
  options?: BinaryTreePrintOptions,
@@ -3060,6 +2045,67 @@ export class BinaryTree<K = any, V = any, R = any>
3060
2045
  console.log(this.toVisual(startNode, options));
3061
2046
  }
3062
2047
 
2048
+ /**
2049
+ * Deletes a node from the tree (internal, returns balancing metadata).
2050
+ * @remarks Time O(N) — O(N) to find the node + O(H) for predecessor swap. Space O(1). BST/Red-Black Tree/AVL Tree subclasses override to O(log N).
2051
+ * @internal Used by AVL/BST subclasses that need balancing metadata after deletion.
2052
+ *
2053
+ * @param keyNodeEntryRawOrPredicate - The node to delete.
2054
+ * @returns An array containing deletion results with balancing metadata.
2055
+ */
2056
+ protected _deleteInternal(
2057
+ keyNodeEntryRawOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V> | null>
2058
+ ): BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[] {
2059
+ const deletedResult: BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[] = [];
2060
+ if (!this._root) return deletedResult;
2061
+
2062
+ const curr = this.getNode(keyNodeEntryRawOrPredicate);
2063
+ if (!curr) return deletedResult;
2064
+
2065
+ const parent: BinaryTreeNode<K, V> | undefined = curr?.parent;
2066
+ let needBalanced: BinaryTreeNode<K, V> | undefined;
2067
+ let orgCurrent: BinaryTreeNode<K, V> | undefined = curr;
2068
+
2069
+ if (!curr.left && !curr.right && !parent) {
2070
+ this._setRoot(undefined);
2071
+ } else if (curr.left) {
2072
+ const leftSubTreeRightMost = this.getRightMost(node => node, curr.left);
2073
+ if (leftSubTreeRightMost) {
2074
+ const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
2075
+ orgCurrent = this._swapProperties(curr, leftSubTreeRightMost);
2076
+
2077
+ if (this._isMapMode) {
2078
+ this._store.set(curr.key, curr);
2079
+ this._store.set(leftSubTreeRightMost.key, leftSubTreeRightMost);
2080
+ }
2081
+
2082
+ if (parentOfLeftSubTreeMax) {
2083
+ if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
2084
+ parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
2085
+ else parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left;
2086
+ needBalanced = parentOfLeftSubTreeMax;
2087
+ }
2088
+ }
2089
+ } else if (parent) {
2090
+ const { familyPosition: fp } = curr;
2091
+ if (fp === 'LEFT' || fp === 'ROOT_LEFT') {
2092
+ parent.left = curr.right;
2093
+ } else if (fp === 'RIGHT' || fp === 'ROOT_RIGHT') {
2094
+ parent.right = curr.right;
2095
+ }
2096
+ needBalanced = parent;
2097
+ } else {
2098
+ this._setRoot(curr.right);
2099
+ curr.right = undefined;
2100
+ }
2101
+
2102
+ this._size = this._size - 1;
2103
+
2104
+ deletedResult.push({ deleted: orgCurrent, needBalanced });
2105
+ if (this._isMapMode && orgCurrent) this._store.delete(orgCurrent.key);
2106
+ return deletedResult;
2107
+ }
2108
+
3063
2109
  protected _dfs<C extends NodeCallback<BinaryTreeNode<K, V>>>(
3064
2110
  callback: C,
3065
2111
  pattern?: DFSOrderPattern,
@@ -3249,8 +2295,9 @@ export class BinaryTree<K = any, V = any, R = any>
3249
2295
  * @param node - The node.
3250
2296
  * @returns The node's key or undefined.
3251
2297
  */
3252
- protected readonly _DEFAULT_NODE_CALLBACK: NodeCallback<BinaryTreeNode<K, V> | null | undefined, K | undefined> =
3253
- (node): K | undefined => node?.key;
2298
+ protected readonly _DEFAULT_NODE_CALLBACK: NodeCallback<BinaryTreeNode<K, V> | null | undefined, K | undefined> = (
2299
+ node
2300
+ ): K | undefined => node?.key;
3254
2301
 
3255
2302
  /**
3256
2303
  * (Protected) Snapshots the current tree's configuration options.
@@ -3382,14 +2429,20 @@ export class BinaryTree<K = any, V = any, R = any>
3382
2429
  };
3383
2430
 
3384
2431
  const newFrame = (n: BinaryTreeNode<K, V> | null | undefined): Frame => ({
3385
- node: n, stage: 0, leftLayout: emptyDisplayLayout, rightLayout: emptyDisplayLayout
2432
+ node: n,
2433
+ stage: 0,
2434
+ leftLayout: emptyDisplayLayout,
2435
+ rightLayout: emptyDisplayLayout
3386
2436
  });
3387
2437
 
3388
2438
  const stack: Frame[] = [newFrame(node)];
3389
2439
  let result: NodeDisplayLayout = emptyDisplayLayout;
3390
2440
 
3391
2441
  const setChildResult = (layout: NodeDisplayLayout) => {
3392
- if (stack.length === 0) { result = layout; return; }
2442
+ if (stack.length === 0) {
2443
+ result = layout;
2444
+ return;
2445
+ }
3393
2446
  const parent = stack[stack.length - 1];
3394
2447
  if (parent.stage === 1) parent.leftLayout = layout;
3395
2448
  else parent.rightLayout = layout;
@@ -3423,48 +2476,10 @@ export class BinaryTree<K = any, V = any, R = any>
3423
2476
  return result;
3424
2477
  }
3425
2478
 
3426
- protected static _buildNodeDisplay(line: string, width: number, left: NodeDisplayLayout, right: NodeDisplayLayout) {
3427
- const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
3428
- const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
3429
- const firstLine =
3430
- ' '.repeat(Math.max(0, leftMiddle + 1)) +
3431
- '_'.repeat(Math.max(0, leftWidth - leftMiddle - 1)) +
3432
- line +
3433
- '_'.repeat(Math.max(0, rightMiddle)) +
3434
- ' '.repeat(Math.max(0, rightWidth - rightMiddle));
3435
-
3436
- const secondLine =
3437
- (leftHeight > 0
3438
- ? ' '.repeat(leftMiddle) + '/' + ' '.repeat(leftWidth - leftMiddle - 1)
3439
- : ' '.repeat(leftWidth)) +
3440
- ' '.repeat(width) +
3441
- (rightHeight > 0
3442
- ? ' '.repeat(rightMiddle) + '\\' + ' '.repeat(rightWidth - rightMiddle - 1)
3443
- : ' '.repeat(rightWidth));
3444
-
3445
- const mergedLines = [firstLine, secondLine];
3446
-
3447
- for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
3448
- const leftLine = i < leftHeight ? leftLines[i] : ' '.repeat(leftWidth);
3449
- const rightLine = i < rightHeight ? rightLines[i] : ' '.repeat(rightWidth);
3450
- mergedLines.push(leftLine + ' '.repeat(width) + rightLine);
3451
- }
3452
-
3453
- return <NodeDisplayLayout>[
3454
- mergedLines,
3455
- leftWidth + width + rightWidth,
3456
- Math.max(leftHeight, rightHeight) + 2,
3457
- leftWidth + Math.floor(width / 2)
3458
- ];
3459
- }
3460
-
3461
2479
  /**
3462
2480
  * Check if a node is a display leaf (empty, null, undefined, NIL, or real leaf).
3463
2481
  */
3464
- protected _isDisplayLeaf(
3465
- node: BinaryTreeNode<K, V> | null | undefined,
3466
- options: BinaryTreePrintOptions
3467
- ): boolean {
2482
+ protected _isDisplayLeaf(node: BinaryTreeNode<K, V> | null | undefined, options: BinaryTreePrintOptions): boolean {
3468
2483
  const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
3469
2484
  // Empty/hidden nodes are always leaves
3470
2485
  if (node === null && !isShowNull) return true;