max-heap-typed 2.2.5 → 2.2.6

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.
@@ -331,7 +331,7 @@ export class BSTNode<K = any, V = any> {
331
331
  * return findFirstCommon(path1, path2);
332
332
  * };
333
333
  *
334
- * function findFirstCommon(arr1: number[], arr2: number[]): number | undefined {
334
+ * function findFirstCommon(arr1: (number | undefined)[], arr2: (number | undefined)[]): number | undefined {
335
335
  * for (const num of arr1) {
336
336
  * if (arr2.indexOf(num) !== -1) {
337
337
  * return num;
@@ -453,6 +453,16 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
453
453
  return isComparable(key);
454
454
  }
455
455
 
456
+ override dfs(): (K | undefined)[];
457
+
458
+ override dfs<C extends NodeCallback<BSTNode<K, V>>>(
459
+ callback: C,
460
+ pattern?: DFSOrderPattern,
461
+ onlyOne?: boolean,
462
+ startNode?: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
463
+ iterationType?: IterationType
464
+ ): ReturnType<C>[];
465
+
456
466
  /**
457
467
  * Performs a Depth-First Search (DFS) traversal.
458
468
  * @remarks Time O(N), visits every node. Space O(log N) for the call/explicit stack. O(N) worst-case.
@@ -475,6 +485,13 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
475
485
  return super.dfs(callback, pattern, onlyOne, startNode, iterationType);
476
486
  }
477
487
 
488
+ override bfs(): (K | undefined)[];
489
+ override bfs<C extends NodeCallback<BSTNode<K, V>>>(
490
+ callback: C,
491
+ startNode?: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
492
+ iterationType?: IterationType
493
+ ): ReturnType<C>[];
494
+
478
495
  /**
479
496
  * Performs a Breadth-First Search (BFS) or Level-Order traversal.
480
497
  * @remarks Time O(N), visits every node. Space O(N) in the worst case for the queue.
@@ -493,6 +510,14 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
493
510
  return super.bfs(callback, startNode, iterationType, false);
494
511
  }
495
512
 
513
+ override listLevels(): (K | undefined)[][];
514
+
515
+ override listLevels<C extends NodeCallback<BSTNode<K, V>>>(
516
+ callback: C,
517
+ startNode?: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
518
+ iterationType?: IterationType
519
+ ): ReturnType<C>[][];
520
+
496
521
  /**
497
522
  * Returns a 2D array of nodes, grouped by level.
498
523
  * @remarks Time O(N), visits every node. Space O(N) for the result array and the queue/stack.
@@ -534,6 +559,33 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
534
559
  return this.getNodes(keyNodeEntryOrPredicate, true, startNode, iterationType)[0] ?? undefined;
535
560
  }
536
561
 
562
+ override search(
563
+ keyNodeEntryOrPredicate:
564
+ | K
565
+ | BSTNode<K, V>
566
+ | [K | null | undefined, V | undefined]
567
+ | null
568
+ | undefined
569
+ | NodePredicate<BSTNode<K, V>>
570
+ | Range<K>,
571
+ onlyOne?: boolean
572
+ ): (K | undefined)[];
573
+
574
+ override search<C extends NodeCallback<BSTNode<K, V>>>(
575
+ keyNodeEntryOrPredicate:
576
+ | K
577
+ | BSTNode<K, V>
578
+ | [K | null | undefined, V | undefined]
579
+ | null
580
+ | undefined
581
+ | NodePredicate<BSTNode<K, V>>
582
+ | Range<K>,
583
+ onlyOne: boolean,
584
+ callback: C,
585
+ startNode?: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
586
+ iterationType?: IterationType
587
+ ): ReturnType<C>[];
588
+
537
589
  /**
538
590
  * Searches the tree for nodes matching a predicate, key, or range.
539
591
  * @remarks This is an optimized search for a BST. If searching by key or range, it prunes branches.
@@ -630,6 +682,15 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
630
682
  );
631
683
  }
632
684
 
685
+ rangeSearch(range: Range<K> | [K, K]): (K | undefined)[];
686
+
687
+ rangeSearch<C extends NodeCallback<BSTNode<K, V>>>(
688
+ range: Range<K> | [K, K],
689
+ callback: C,
690
+ startNode?: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
691
+ iterationType?: IterationType
692
+ ): ReturnType<C>[];
693
+
633
694
  /**
634
695
  * Performs an optimized search for nodes within a given key range.
635
696
  * @remarks Time O(H + M), where H is tree height and M is the number of matches.
@@ -807,39 +868,27 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
807
868
  }
808
869
 
809
870
  /**
810
- * Returns the first node with a key greater than or equal to the given key.
811
- * This is equivalent to C++ std::lower_bound on a BST.
812
- * Supports RECURSIVE and ITERATIVE implementations.
813
- * Time Complexity: O(log n) on average, O(h) where h is tree height.
871
+ * Returns the first key with a value >= target.
872
+ * Equivalent to Java TreeMap.ceiling.
873
+ * Time Complexity: O(log n) average, O(h) worst case.
814
874
  * Space Complexity: O(h) for recursion, O(1) for iteration.
815
- * @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
816
- * @param iterationType The iteration type (RECURSIVE or ITERATIVE). Defaults to this.iterationType.
817
- * @returns The first node with key >= given key, or undefined if no such node exists.
818
875
  */
819
- lowerBound(
876
+ ceiling(
820
877
  keyNodeEntryOrPredicate:
821
878
  | K
822
879
  | BSTNode<K, V>
823
880
  | [K | null | undefined, V | undefined]
824
881
  | null
825
882
  | undefined
826
- | NodePredicate<BSTNode<K, V>>,
827
- iterationType: IterationType = this.iterationType
828
- ): BSTNode<K, V> | undefined {
829
- return this._bound(keyNodeEntryOrPredicate, true, iterationType);
830
- }
883
+ | NodePredicate<BSTNode<K, V>>
884
+ ): K | undefined;
831
885
 
832
886
  /**
833
- * Returns the first node with a key strictly greater than the given key.
834
- * This is equivalent to C++ std::upper_bound on a BST.
835
- * Supports RECURSIVE and ITERATIVE implementations.
836
- * Time Complexity: O(log n) on average, O(h) where h is tree height.
887
+ * Returns the first node with a key >= target and applies callback.
888
+ * Time Complexity: O(log n) average, O(h) worst case.
837
889
  * Space Complexity: O(h) for recursion, O(1) for iteration.
838
- * @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
839
- * @param iterationType The iteration type (RECURSIVE or ITERATIVE). Defaults to this.iterationType.
840
- * @returns The first node with key > given key, or undefined if no such node exists.
841
890
  */
842
- upperBound(
891
+ ceiling<C extends NodeCallback<BSTNode<K, V>>>(
843
892
  keyNodeEntryOrPredicate:
844
893
  | K
845
894
  | BSTNode<K, V>
@@ -847,47 +896,64 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
847
896
  | null
848
897
  | undefined
849
898
  | NodePredicate<BSTNode<K, V>>,
850
- iterationType: IterationType = this.iterationType
851
- ): BSTNode<K, V> | undefined {
852
- return this._bound(keyNodeEntryOrPredicate, false, iterationType);
899
+ callback: C,
900
+ iterationType?: IterationType
901
+ ): ReturnType<C>;
902
+
903
+ ceiling<C extends NodeCallback<BSTNode<K, V>>>(
904
+ keyNodeEntryOrPredicate:
905
+ | K
906
+ | BSTNode<K, V>
907
+ | [K | null | undefined, V | undefined]
908
+ | null
909
+ | undefined
910
+ | NodePredicate<BSTNode<K, V>>,
911
+ callback: C = this._DEFAULT_NODE_CALLBACK as C,
912
+ iterationType?: IterationType
913
+ ): K | undefined | ReturnType<C> {
914
+ let actualCallback: C | undefined = undefined;
915
+ let actualIterationType: IterationType = this.iterationType;
916
+
917
+ if (typeof callback === 'string') {
918
+ actualIterationType = callback;
919
+ } else if (callback) {
920
+ actualCallback = callback;
921
+ if (iterationType) {
922
+ actualIterationType = iterationType;
923
+ }
924
+ }
925
+
926
+ const node = this._bound(keyNodeEntryOrPredicate, true, actualIterationType);
927
+
928
+ if (!actualCallback) {
929
+ return node?.key;
930
+ }
931
+
932
+ return node ? actualCallback(node) : undefined;
853
933
  }
854
934
 
855
935
  /**
856
- * Returns the first node with a key greater than or equal to the given key.
857
- * This is equivalent to Java TreeMap.ceilingEntry().
858
- * Supports RECURSIVE and ITERATIVE implementations.
859
- * @remarks Time Complexity: O(log n) on average, O(h) where h is tree height.
936
+ * Returns the first key with a value > target.
937
+ * Equivalent to Java TreeMap.higher.
938
+ * Time Complexity: O(log n) average, O(h) worst case.
860
939
  * Space Complexity: O(h) for recursion, O(1) for iteration.
861
- *
862
- * @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
863
- * @param [iterationType=this.iterationType] - The iteration type (RECURSIVE or ITERATIVE).
864
- * @returns The first node with key >= given key, or undefined if no such node exists.
865
940
  */
866
- ceilingEntry(
941
+ higher(
867
942
  keyNodeEntryOrPredicate:
868
943
  | K
869
944
  | BSTNode<K, V>
870
945
  | [K | null | undefined, V | undefined]
871
946
  | null
872
947
  | undefined
873
- | NodePredicate<BSTNode<K, V>>,
874
- iterationType: IterationType = this.iterationType
875
- ): BSTNode<K, V> | undefined {
876
- return this.lowerBound(keyNodeEntryOrPredicate, iterationType);
877
- }
948
+ | NodePredicate<BSTNode<K, V>>
949
+ ): K | undefined;
878
950
 
879
951
  /**
880
- * Returns the first node with a key strictly greater than the given key.
881
- * This is equivalent to Java TreeMap.higherEntry().
882
- * Supports RECURSIVE and ITERATIVE implementations.
883
- * @remarks Time Complexity: O(log n) on average, O(h) where h is tree height.
952
+ * Returns the first node with a key > target and applies callback.
953
+ * Time Complexity: O(log n) average, O(h) worst case.
884
954
  * Space Complexity: O(h) for recursion, O(1) for iteration.
885
- *
886
- * @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
887
- * @param [iterationType=this.iterationType] - The iteration type (RECURSIVE or ITERATIVE).
888
- * @returns The first node with key > given key, or undefined if no such node exists.
889
955
  */
890
- higherEntry(
956
+ higher<C extends NodeCallback<BSTNode<K, V>>>(
891
957
  keyNodeEntryOrPredicate:
892
958
  | K
893
959
  | BSTNode<K, V>
@@ -895,23 +961,64 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
895
961
  | null
896
962
  | undefined
897
963
  | NodePredicate<BSTNode<K, V>>,
898
- iterationType: IterationType = this.iterationType
899
- ): BSTNode<K, V> | undefined {
900
- return this.upperBound(keyNodeEntryOrPredicate, iterationType);
964
+ callback: C,
965
+ iterationType?: IterationType
966
+ ): ReturnType<C>;
967
+
968
+ higher<C extends NodeCallback<BSTNode<K, V>>>(
969
+ keyNodeEntryOrPredicate:
970
+ | K
971
+ | BSTNode<K, V>
972
+ | [K | null | undefined, V | undefined]
973
+ | null
974
+ | undefined
975
+ | NodePredicate<BSTNode<K, V>>,
976
+ callback: C = this._DEFAULT_NODE_CALLBACK as C,
977
+ iterationType?: IterationType
978
+ ): K | undefined | ReturnType<C> {
979
+ let actualCallback: C | undefined = undefined;
980
+ let actualIterationType: IterationType = this.iterationType;
981
+
982
+ if (typeof callback === 'string') {
983
+ actualIterationType = callback;
984
+ } else if (callback) {
985
+ actualCallback = callback;
986
+ if (iterationType) {
987
+ actualIterationType = iterationType;
988
+ }
989
+ }
990
+
991
+ const node = this._bound(keyNodeEntryOrPredicate, false, actualIterationType);
992
+
993
+ if (!actualCallback) {
994
+ return node?.key;
995
+ }
996
+
997
+ return node ? actualCallback(node) : undefined;
901
998
  }
902
999
 
903
1000
  /**
904
- * Returns the first node with a key less than or equal to the given key.
905
- * This is equivalent to Java TreeMap.floorEntry().
906
- * Supports RECURSIVE and ITERATIVE implementations.
907
- * @remarks Time Complexity: O(log n) on average, O(h) where h is tree height.
1001
+ * Returns the first key with a value <= target.
1002
+ * Equivalent to Java TreeMap.floor.
1003
+ * Time Complexity: O(log n) average, O(h) worst case.
908
1004
  * Space Complexity: O(h) for recursion, O(1) for iteration.
909
- *
910
- * @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
911
- * @param [iterationType=this.iterationType] - The iteration type (RECURSIVE or ITERATIVE).
912
- * @returns The first node with key <= given key, or undefined if no such node exists.
913
1005
  */
914
- floorEntry(
1006
+ floor(
1007
+ keyNodeEntryOrPredicate:
1008
+ | K
1009
+ | BSTNode<K, V>
1010
+ | [K | null | undefined, V | undefined]
1011
+ | null
1012
+ | undefined
1013
+ | NodePredicate<BSTNode<K, V>>
1014
+ ): K | undefined;
1015
+
1016
+ /**
1017
+ * Returns the first node with a key <= target and applies callback.
1018
+ * Time Complexity: O(log n) average, O(h) worst case.
1019
+ * Space Complexity: O(h) for recursion, O(1) for iteration.
1020
+ */
1021
+ floor<C extends NodeCallback<BSTNode<K, V>>>(
915
1022
  keyNodeEntryOrPredicate:
916
1023
  | K
917
1024
  | BSTNode<K, V>
@@ -919,54 +1026,104 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
919
1026
  | null
920
1027
  | undefined
921
1028
  | NodePredicate<BSTNode<K, V>>,
922
- iterationType: IterationType = this.iterationType
923
- ): BSTNode<K, V> | undefined {
1029
+ callback: C,
1030
+ iterationType?: IterationType
1031
+ ): ReturnType<C>;
1032
+
1033
+ floor<C extends NodeCallback<BSTNode<K, V>>>(
1034
+ keyNodeEntryOrPredicate:
1035
+ | K
1036
+ | BSTNode<K, V>
1037
+ | [K | null | undefined, V | undefined]
1038
+ | null
1039
+ | undefined
1040
+ | NodePredicate<BSTNode<K, V>>,
1041
+ callback: C = this._DEFAULT_NODE_CALLBACK as C,
1042
+ iterationType?: IterationType
1043
+ ): K | undefined | ReturnType<C> {
924
1044
  if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === undefined) {
1045
+ if (typeof callback === 'string' || !callback) {
1046
+ return undefined;
1047
+ }
925
1048
  return undefined;
926
1049
  }
927
1050
 
928
- // Check if input is a predicate function first
1051
+ let actualCallback: C | undefined = undefined;
1052
+ let actualIterationType: IterationType = this.iterationType;
1053
+
1054
+ if (typeof callback === 'string') {
1055
+ actualIterationType = callback;
1056
+ } else if (callback) {
1057
+ actualCallback = callback;
1058
+ if (iterationType) {
1059
+ actualIterationType = iterationType;
1060
+ }
1061
+ }
1062
+
929
1063
  if (this._isPredicate(keyNodeEntryOrPredicate)) {
930
- return this._floorByPredicate(keyNodeEntryOrPredicate, iterationType);
1064
+ const node = this._floorByPredicate(keyNodeEntryOrPredicate, actualIterationType);
1065
+
1066
+ if (!actualCallback) {
1067
+ return node?.key;
1068
+ }
1069
+
1070
+ return node ? actualCallback(node) : undefined;
931
1071
  }
932
1072
 
933
- // Resolve input to a comparable key
934
1073
  let targetKey: K | undefined;
935
1074
  if (this.isNode(keyNodeEntryOrPredicate)) {
936
- // Input is a BSTNode - extract its key
937
1075
  targetKey = keyNodeEntryOrPredicate.key;
938
1076
  } else if (this.isEntry(keyNodeEntryOrPredicate)) {
939
- // Input is a [key, value] entry - extract the key
940
1077
  const key = keyNodeEntryOrPredicate[0];
941
1078
  if (key === null || key === undefined) {
1079
+ if (typeof callback === 'string' || !callback) {
1080
+ return undefined;
1081
+ }
942
1082
  return undefined;
943
1083
  }
944
1084
  targetKey = key;
945
1085
  } else {
946
- // Input is a raw key
947
1086
  targetKey = keyNodeEntryOrPredicate;
948
1087
  }
949
1088
 
950
- // Execute key-based search with binary search optimization
951
1089
  if (targetKey !== undefined) {
952
- return this._floorByKey(targetKey, iterationType);
1090
+ const node = this._floorByKey(targetKey, actualIterationType);
1091
+
1092
+ if (!actualCallback) {
1093
+ return node?.key;
1094
+ }
1095
+
1096
+ return node ? actualCallback(node) : undefined;
953
1097
  }
954
1098
 
1099
+ if (typeof callback === 'string' || !callback) {
1100
+ return undefined;
1101
+ }
955
1102
  return undefined;
956
1103
  }
957
1104
 
958
1105
  /**
959
- * Returns the first node with a key strictly less than the given key.
960
- * This is equivalent to Java TreeMap.lowerEntry().
961
- * Supports RECURSIVE and ITERATIVE implementations.
962
- * @remarks Time Complexity: O(log n) on average, O(h) where h is tree height.
1106
+ * Returns the first key with a value < target.
1107
+ * Equivalent to Java TreeMap.lower.
1108
+ * Time Complexity: O(log n) average, O(h) worst case.
1109
+ * Space Complexity: O(h) for recursion, O(1) for iteration.
1110
+ */
1111
+ lower(
1112
+ keyNodeEntryOrPredicate:
1113
+ | K
1114
+ | BSTNode<K, V>
1115
+ | [K | null | undefined, V | undefined]
1116
+ | null
1117
+ | undefined
1118
+ | NodePredicate<BSTNode<K, V>>
1119
+ ): K | undefined;
1120
+
1121
+ /**
1122
+ * Returns the first node with a key < target and applies callback.
1123
+ * Time Complexity: O(log n) average, O(h) worst case.
963
1124
  * Space Complexity: O(h) for recursion, O(1) for iteration.
964
- *
965
- * @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
966
- * @param [iterationType=this.iterationType] - The iteration type (RECURSIVE or ITERATIVE).
967
- * @returns The first node with key < given key, or undefined if no such node exists.
968
1125
  */
969
- lowerEntry(
1126
+ lower<C extends NodeCallback<BSTNode<K, V>>>(
970
1127
  keyNodeEntryOrPredicate:
971
1128
  | K
972
1129
  | BSTNode<K, V>
@@ -974,42 +1131,91 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
974
1131
  | null
975
1132
  | undefined
976
1133
  | NodePredicate<BSTNode<K, V>>,
977
- iterationType: IterationType = this.iterationType
978
- ): BSTNode<K, V> | undefined {
1134
+ callback: C,
1135
+ iterationType?: IterationType
1136
+ ): ReturnType<C>;
1137
+
1138
+ lower<C extends NodeCallback<BSTNode<K, V>>>(
1139
+ keyNodeEntryOrPredicate:
1140
+ | K
1141
+ | BSTNode<K, V>
1142
+ | [K | null | undefined, V | undefined]
1143
+ | null
1144
+ | undefined
1145
+ | NodePredicate<BSTNode<K, V>>,
1146
+ callback?: C | IterationType,
1147
+ iterationType?: IterationType
1148
+ ): K | undefined | ReturnType<C> {
979
1149
  if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === undefined) {
1150
+ if (typeof callback === 'string' || !callback) {
1151
+ return undefined;
1152
+ }
980
1153
  return undefined;
981
1154
  }
982
1155
 
983
- // Check if input is a predicate function first
1156
+ let actualCallback: C | undefined = undefined;
1157
+ let actualIterationType: IterationType = this.iterationType;
1158
+
1159
+ if (typeof callback === 'string') {
1160
+ actualIterationType = callback;
1161
+ } else if (callback) {
1162
+ actualCallback = callback;
1163
+ if (iterationType) {
1164
+ actualIterationType = iterationType;
1165
+ }
1166
+ }
1167
+
984
1168
  if (this._isPredicate(keyNodeEntryOrPredicate)) {
985
- return this._lowerByPredicate(keyNodeEntryOrPredicate, iterationType);
1169
+ const node = this._lowerByPredicate(keyNodeEntryOrPredicate, actualIterationType);
1170
+
1171
+ if (!actualCallback) {
1172
+ return node?.key;
1173
+ }
1174
+
1175
+ return node ? actualCallback(node) : undefined;
986
1176
  }
987
1177
 
988
- // Resolve input to a comparable key
989
1178
  let targetKey: K | undefined;
990
1179
  if (this.isNode(keyNodeEntryOrPredicate)) {
991
- // Input is a BSTNode - extract its key
992
1180
  targetKey = keyNodeEntryOrPredicate.key;
993
1181
  } else if (this.isEntry(keyNodeEntryOrPredicate)) {
994
- // Input is a [key, value] entry - extract the key
995
1182
  const key = keyNodeEntryOrPredicate[0];
996
1183
  if (key === null || key === undefined) {
1184
+ if (typeof callback === 'string' || !callback) {
1185
+ return undefined;
1186
+ }
997
1187
  return undefined;
998
1188
  }
999
1189
  targetKey = key;
1000
1190
  } else {
1001
- // Input is a raw key
1002
1191
  targetKey = keyNodeEntryOrPredicate;
1003
1192
  }
1004
1193
 
1005
- // Execute key-based search with binary search optimization
1006
1194
  if (targetKey !== undefined) {
1007
- return this._lowerByKey(targetKey, iterationType);
1195
+ const node = this._lowerByKey(targetKey, actualIterationType);
1196
+
1197
+ if (!actualCallback) {
1198
+ return node?.key;
1199
+ }
1200
+
1201
+ return node ? actualCallback(node) : undefined;
1008
1202
  }
1009
1203
 
1204
+ if (typeof callback === 'string' || !callback) {
1205
+ return undefined;
1206
+ }
1010
1207
  return undefined;
1011
1208
  }
1012
1209
 
1210
+ lesserOrGreaterTraverse(): (K | undefined)[];
1211
+
1212
+ lesserOrGreaterTraverse<C extends NodeCallback<BSTNode<K, V>>>(
1213
+ callback: C,
1214
+ lesserOrGreater?: number,
1215
+ targetNode?: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
1216
+ iterationType?: IterationType
1217
+ ): ReturnType<C>[];
1218
+
1013
1219
  /**
1014
1220
  * Traverses the tree and returns nodes that are lesser or greater than a target node.
1015
1221
  * @remarks Time O(N), as it performs a full traversal. Space O(log N) or O(N).