doubly-linked-list-typed 1.52.4 → 1.52.5

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 (74) hide show
  1. package/dist/data-structures/base/iterable-element-base.d.ts +1 -37
  2. package/dist/data-structures/base/iterable-element-base.js +1 -37
  3. package/dist/data-structures/base/iterable-entry-base.d.ts +2 -54
  4. package/dist/data-structures/base/iterable-entry-base.js +1 -49
  5. package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +0 -32
  6. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +9 -41
  7. package/dist/data-structures/binary-tree/avl-tree.d.ts +0 -46
  8. package/dist/data-structures/binary-tree/avl-tree.js +0 -46
  9. package/dist/data-structures/binary-tree/binary-tree.d.ts +82 -147
  10. package/dist/data-structures/binary-tree/binary-tree.js +299 -331
  11. package/dist/data-structures/binary-tree/bst.d.ts +1 -40
  12. package/dist/data-structures/binary-tree/bst.js +12 -44
  13. package/dist/data-structures/binary-tree/rb-tree.d.ts +0 -48
  14. package/dist/data-structures/binary-tree/rb-tree.js +2 -50
  15. package/dist/data-structures/binary-tree/tree-multi-map.d.ts +0 -32
  16. package/dist/data-structures/binary-tree/tree-multi-map.js +9 -41
  17. package/dist/data-structures/graph/abstract-graph.d.ts +0 -75
  18. package/dist/data-structures/graph/abstract-graph.js +0 -75
  19. package/dist/data-structures/graph/directed-graph.d.ts +0 -98
  20. package/dist/data-structures/graph/directed-graph.js +0 -98
  21. package/dist/data-structures/graph/undirected-graph.d.ts +0 -50
  22. package/dist/data-structures/graph/undirected-graph.js +0 -50
  23. package/dist/data-structures/hash/hash-map.d.ts +5 -92
  24. package/dist/data-structures/hash/hash-map.js +27 -111
  25. package/dist/data-structures/heap/heap.d.ts +0 -32
  26. package/dist/data-structures/heap/heap.js +0 -32
  27. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +5 -88
  28. package/dist/data-structures/linked-list/doubly-linked-list.js +5 -88
  29. package/dist/data-structures/linked-list/singly-linked-list.d.ts +1 -83
  30. package/dist/data-structures/linked-list/singly-linked-list.js +2 -84
  31. package/dist/data-structures/linked-list/skip-linked-list.d.ts +1 -35
  32. package/dist/data-structures/linked-list/skip-linked-list.js +1 -35
  33. package/dist/data-structures/queue/deque.d.ts +1 -98
  34. package/dist/data-structures/queue/deque.js +3 -99
  35. package/dist/data-structures/queue/queue.d.ts +1 -54
  36. package/dist/data-structures/queue/queue.js +0 -53
  37. package/dist/data-structures/stack/stack.d.ts +1 -34
  38. package/dist/data-structures/stack/stack.js +1 -34
  39. package/dist/data-structures/tree/tree.js +2 -1
  40. package/dist/data-structures/trie/trie.d.ts +0 -64
  41. package/dist/data-structures/trie/trie.js +0 -64
  42. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +8 -0
  43. package/dist/types/data-structures/binary-tree/binary-tree.js +6 -0
  44. package/dist/types/utils/utils.d.ts +13 -12
  45. package/dist/utils/number.d.ts +13 -0
  46. package/dist/utils/number.js +13 -0
  47. package/dist/utils/utils.d.ts +125 -3
  48. package/dist/utils/utils.js +177 -21
  49. package/package.json +2 -2
  50. package/src/data-structures/base/iterable-element-base.ts +2 -42
  51. package/src/data-structures/base/iterable-entry-base.ts +3 -62
  52. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +8 -48
  53. package/src/data-structures/binary-tree/avl-tree.ts +0 -57
  54. package/src/data-structures/binary-tree/binary-tree.ts +329 -358
  55. package/src/data-structures/binary-tree/bst.ts +11 -54
  56. package/src/data-structures/binary-tree/rb-tree.ts +2 -62
  57. package/src/data-structures/binary-tree/tree-multi-map.ts +8 -48
  58. package/src/data-structures/graph/abstract-graph.ts +0 -92
  59. package/src/data-structures/graph/directed-graph.ts +0 -122
  60. package/src/data-structures/graph/undirected-graph.ts +0 -62
  61. package/src/data-structures/hash/hash-map.ts +29 -133
  62. package/src/data-structures/heap/heap.ts +0 -40
  63. package/src/data-structures/linked-list/doubly-linked-list.ts +5 -112
  64. package/src/data-structures/linked-list/singly-linked-list.ts +2 -104
  65. package/src/data-structures/linked-list/skip-linked-list.ts +1 -44
  66. package/src/data-structures/queue/deque.ts +2 -125
  67. package/src/data-structures/queue/queue.ts +1 -68
  68. package/src/data-structures/stack/stack.ts +1 -43
  69. package/src/data-structures/tree/tree.ts +1 -1
  70. package/src/data-structures/trie/trie.ts +0 -80
  71. package/src/types/data-structures/binary-tree/binary-tree.ts +8 -1
  72. package/src/types/utils/utils.ts +17 -15
  73. package/src/utils/number.ts +13 -0
  74. package/src/utils/utils.ts +174 -18
@@ -8,6 +8,7 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.BinaryTree = exports.BinaryTreeNode = void 0;
11
+ const types_1 = require("../../types");
11
12
  const utils_1 = require("../../utils");
12
13
  const queue_1 = require("../queue");
13
14
  const base_1 = require("../base");
@@ -187,30 +188,26 @@ class BinaryTree extends base_1.IterableEntryBase {
187
188
  return null;
188
189
  if (this.isNode(keyOrNodeOrEntryOrRawElement))
189
190
  return keyOrNodeOrEntryOrRawElement;
190
- if (this.toEntryFn) {
191
- const [key, entryValue] = this.toEntryFn(keyOrNodeOrEntryOrRawElement);
192
- if (key)
193
- return this.createNode(key, entryValue !== null && entryValue !== void 0 ? entryValue : value);
194
- else
195
- return;
196
- }
197
191
  if (this.isEntry(keyOrNodeOrEntryOrRawElement)) {
198
- const [key, value] = keyOrNodeOrEntryOrRawElement;
192
+ const [key, entryValue] = keyOrNodeOrEntryOrRawElement;
199
193
  if (key === undefined)
200
194
  return;
201
195
  else if (key === null)
202
196
  return null;
197
+ if (this.isKey(key))
198
+ return this.createNode(key, value !== null && value !== void 0 ? value : entryValue);
199
+ }
200
+ if (this.toEntryFn) {
201
+ const [key, entryValue] = this.toEntryFn(keyOrNodeOrEntryOrRawElement);
202
+ if (this.isKey(key))
203
+ return this.createNode(key, value !== null && value !== void 0 ? value : entryValue);
203
204
  else
204
- return this.createNode(key, value);
205
+ return;
205
206
  }
206
207
  if (this.isKey(keyOrNodeOrEntryOrRawElement))
207
208
  return this.createNode(keyOrNodeOrEntryOrRawElement, value);
208
209
  return;
209
210
  }
210
- /**
211
- * Time Complexity: O(n)
212
- * Space Complexity: O(log n)
213
- */
214
211
  /**
215
212
  * Time Complexity: O(n)
216
213
  * Space Complexity: O(log n)
@@ -225,7 +222,7 @@ class BinaryTree extends base_1.IterableEntryBase {
225
222
  * default value of `'ITERATIVE'`.
226
223
  * @returns The function `ensureNode` returns either a `NODE` object, `null`, or `undefined`.
227
224
  */
228
- ensureNode(keyOrNodeOrEntryOrRawElement, iterationType = 'ITERATIVE') {
225
+ ensureNode(keyOrNodeOrEntryOrRawElement, iterationType = this.iterationType) {
229
226
  if (keyOrNodeOrEntryOrRawElement === null)
230
227
  return null;
231
228
  if (keyOrNodeOrEntryOrRawElement === undefined)
@@ -236,7 +233,7 @@ class BinaryTree extends base_1.IterableEntryBase {
236
233
  return keyOrNodeOrEntryOrRawElement;
237
234
  if (this.toEntryFn) {
238
235
  const [key] = this.toEntryFn(keyOrNodeOrEntryOrRawElement);
239
- if (key)
236
+ if (this.isKey(key))
240
237
  return this.getNodeByKey(key);
241
238
  }
242
239
  if (this.isEntry(keyOrNodeOrEntryOrRawElement)) {
@@ -278,7 +275,7 @@ class BinaryTree extends base_1.IterableEntryBase {
278
275
  * `BTNKeyOrNodeOrEntry<K, V, NODE>`.
279
276
  * @returns a boolean value.
280
277
  */
281
- isNodeOrNull(node) {
278
+ isRealNodeOrNull(node) {
282
279
  return this.isRealNode(node) || node === null;
283
280
  }
284
281
  /**
@@ -290,6 +287,23 @@ class BinaryTree extends base_1.IterableEntryBase {
290
287
  isNIL(node) {
291
288
  return node === this.NIL;
292
289
  }
290
+ /**
291
+ * The function `isLeaf` determines whether a given node is a leaf node in a binary tree structure.
292
+ * @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} node - The `node` parameter in the `isLeaf` function
293
+ * can be either a regular node (`R`) or a `BTNKeyOrNodeOrEntry<K, V, NODE>`.
294
+ * @returns The `isLeaf` function is checking if the provided node is a leaf node in a binary tree.
295
+ * If the node is `undefined`, it returns `false`. If the node is `null`, it returns `true`.
296
+ * Otherwise, it checks if both the left and right children of the node are not real nodes, and
297
+ * returns `true` if they are not, indicating that the node is a
298
+ */
299
+ isLeaf(node) {
300
+ node = this.ensureNode(node);
301
+ if (node === undefined)
302
+ return false;
303
+ if (node === null)
304
+ return true;
305
+ return !this.isRealNode(node.left) && !this.isRealNode(node.right);
306
+ }
293
307
  /**
294
308
  * The function checks if the input is an array with two elements, indicating it is a binary tree
295
309
  * node entry.
@@ -301,41 +315,21 @@ class BinaryTree extends base_1.IterableEntryBase {
301
315
  return Array.isArray(keyOrNodeOrEntryOrRawElement) && keyOrNodeOrEntryOrRawElement.length === 2;
302
316
  }
303
317
  /**
304
- * The function checks if a given value is a valid key by evaluating its type and value.
305
- * @param {any} key - The `key` parameter can be of any type. It is the value that we want to check
306
- * if it is a valid key.
307
- * @param [isCheckValueOf=true] - The `isCheckValueOf` parameter is a boolean flag that determines
308
- * whether the function should check the valueOf() method of an object when the key is of type
309
- * 'object'. If `isCheckValueOf` is true, the function will recursively call itself with the value
310
- * returned by key.valueOf().
311
- * @returns a boolean value.
312
- */
313
- isKey(key, isCheckValueOf = true) {
318
+ * Time Complexity O(1)
319
+ * Space Complexity O(1)
320
+ *
321
+ * The function `isKey` checks if a given key is comparable.
322
+ * @param {any} key - The `key` parameter is of type `any`, which means it can be any data type in
323
+ * TypeScript.
324
+ * @returns The function `isKey` is checking if the `key` parameter is `null` or if it is comparable.
325
+ * If the `key` is `null`, the function returns `true`. Otherwise, it returns the result of the
326
+ * `isComparable` function, which is not provided in the code snippet.
327
+ */
328
+ isKey(key) {
314
329
  if (key === null)
315
330
  return true;
316
- const keyType = typeof key;
317
- if (keyType === 'string' || keyType === 'bigint' || keyType === 'boolean')
318
- return true;
319
- if (keyType === 'number')
320
- return !isNaN(key);
321
- if (keyType === 'symbol' || keyType === 'undefined')
322
- return false;
323
- if (keyType === 'function')
324
- return this.isKey(key());
325
- if (keyType === 'object') {
326
- if (typeof key.toString === 'function')
327
- return true;
328
- if (isCheckValueOf && typeof key.valueOf === 'function') {
329
- this.isKey(key.valueOf(), false);
330
- }
331
- return false;
332
- }
333
- return false;
331
+ return (0, utils_1.isComparable)(key);
334
332
  }
335
- /**
336
- * Time Complexity O(n)
337
- * Space Complexity O(1)
338
- */
339
333
  /**
340
334
  * Time Complexity O(n)
341
335
  * Space Complexity O(1)
@@ -398,11 +392,6 @@ class BinaryTree extends base_1.IterableEntryBase {
398
392
  }
399
393
  return false; // If the insertion position cannot be found, return undefined
400
394
  }
401
- /**
402
- * Time Complexity: O(k * n)
403
- * Space Complexity: O(1)
404
- * Comments: The time complexity for adding a node depends on the depth of the tree. In the best case (when the tree is empty), it's O(1). In the worst case (when the tree is a degenerate tree), it's O(n). The space complexity is constant.
405
- */
406
395
  /**
407
396
  * Time Complexity: O(k * n)
408
397
  * Space Complexity: O(1)
@@ -436,11 +425,6 @@ class BinaryTree extends base_1.IterableEntryBase {
436
425
  }
437
426
  return inserted;
438
427
  }
439
- /**
440
- * Time Complexity: O(k * n)
441
- * Space Complexity: O(1)
442
- * "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
443
- */
444
428
  /**
445
429
  * Time Complexity: O(k * n)
446
430
  * Space Complexity: O(1)
@@ -456,10 +440,6 @@ class BinaryTree extends base_1.IterableEntryBase {
456
440
  this.clear();
457
441
  this.addMany(keysOrNodesOrEntriesOrRawElements, values);
458
442
  }
459
- /**
460
- * Time Complexity: O(n)
461
- * Space Complexity: O(1)
462
- */
463
443
  /**
464
444
  * Time Complexity: O(n)
465
445
  * Space Complexity: O(1)
@@ -490,7 +470,7 @@ class BinaryTree extends base_1.IterableEntryBase {
490
470
  this._setRoot(undefined);
491
471
  }
492
472
  else if (curr.left) {
493
- const leftSubTreeRightMost = this.getRightMost(curr.left);
473
+ const leftSubTreeRightMost = this.getRightMost(node => node, curr.left);
494
474
  if (leftSubTreeRightMost) {
495
475
  const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
496
476
  orgCurrent = this._swapProperties(curr, leftSubTreeRightMost);
@@ -521,10 +501,6 @@ class BinaryTree extends base_1.IterableEntryBase {
521
501
  deletedResult.push({ deleted: orgCurrent, needBalanced });
522
502
  return deletedResult;
523
503
  }
524
- /**
525
- * Time Complexity: O(n)
526
- * Space Complexity: O(k + log n)
527
- */
528
504
  /**
529
505
  * Time Complexity: O(n)
530
506
  * Space Complexity: O(k + log n)
@@ -550,6 +526,10 @@ class BinaryTree extends base_1.IterableEntryBase {
550
526
  * @returns an array of NODE objects.
551
527
  */
552
528
  getNodes(identifier, callback = this._DEFAULT_CALLBACK, onlyOne = false, beginRoot = this.root, iterationType = this.iterationType) {
529
+ if (identifier === undefined)
530
+ return [];
531
+ if (identifier === null)
532
+ return [];
553
533
  beginRoot = this.ensureNode(beginRoot);
554
534
  if (!beginRoot)
555
535
  return [];
@@ -586,10 +566,6 @@ class BinaryTree extends base_1.IterableEntryBase {
586
566
  }
587
567
  return ans;
588
568
  }
589
- /**
590
- * Time Complexity: O(n)
591
- * Space Complexity: O(log n).
592
- */
593
569
  /**
594
570
  * Time Complexity: O(n)
595
571
  * Space Complexity: O(log n).
@@ -612,10 +588,6 @@ class BinaryTree extends base_1.IterableEntryBase {
612
588
  var _a;
613
589
  return (_a = this.getNodes(identifier, callback, true, beginRoot, iterationType)[0]) !== null && _a !== void 0 ? _a : null;
614
590
  }
615
- /**
616
- * Time Complexity: O(n)
617
- * Space Complexity: O(log n)
618
- */
619
591
  /**
620
592
  * Time Complexity: O(n)
621
593
  * Space Complexity: O(log n)
@@ -628,13 +600,9 @@ class BinaryTree extends base_1.IterableEntryBase {
628
600
  * It has a default value of `'ITERATIVE'`.
629
601
  * @returns a value of type NODE, null, or undefined.
630
602
  */
631
- getNodeByKey(key, iterationType = 'ITERATIVE') {
603
+ getNodeByKey(key, iterationType = this.iterationType) {
632
604
  return this.getNode(key, this._DEFAULT_CALLBACK, this.root, iterationType);
633
605
  }
634
- /**
635
- * Time Complexity: O(n)
636
- * Space Complexity: O(log n)
637
- */
638
606
  /**
639
607
  * Time Complexity: O(n)
640
608
  * Space Complexity: O(log n)
@@ -660,10 +628,6 @@ class BinaryTree extends base_1.IterableEntryBase {
660
628
  var _a;
661
629
  return (_a = this.getNode(identifier, callback, beginRoot, iterationType)) === null || _a === void 0 ? void 0 : _a.value;
662
630
  }
663
- /**
664
- * Time Complexity: O(n)
665
- * Space Complexity: O(log n)
666
- */
667
631
  /**
668
632
  * Time Complexity: O(n)
669
633
  * Space Complexity: O(log n)
@@ -688,10 +652,6 @@ class BinaryTree extends base_1.IterableEntryBase {
688
652
  callback = this._ensureCallback(identifier, callback);
689
653
  return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
690
654
  }
691
- /**
692
- * Time Complexity: O(1)
693
- * Space Complexity: O(1)
694
- */
695
655
  /**
696
656
  * Time Complexity: O(1)
697
657
  * Space Complexity: O(1)
@@ -702,10 +662,6 @@ class BinaryTree extends base_1.IterableEntryBase {
702
662
  this._setRoot(undefined);
703
663
  this._size = 0;
704
664
  }
705
- /**
706
- * Time Complexity: O(1)
707
- * Space Complexity: O(1)
708
- */
709
665
  /**
710
666
  * Time Complexity: O(1)
711
667
  * Space Complexity: O(1)
@@ -716,10 +672,6 @@ class BinaryTree extends base_1.IterableEntryBase {
716
672
  isEmpty() {
717
673
  return this.size === 0;
718
674
  }
719
- /**
720
- * Time Complexity: O(n)
721
- * Space Complexity: O(log n)
722
- */
723
675
  /**
724
676
  * Time Complexity: O(n)
725
677
  * Space Complexity: O(log n)
@@ -735,10 +687,6 @@ class BinaryTree extends base_1.IterableEntryBase {
735
687
  isPerfectlyBalanced(beginRoot = this.root) {
736
688
  return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
737
689
  }
738
- /**
739
- * Time Complexity: O(n)
740
- * Space Complexity: O(1)
741
- */
742
690
  /**
743
691
  * Time Complexity: O(n)
744
692
  * Space Complexity: O(1)
@@ -795,10 +743,6 @@ class BinaryTree extends base_1.IterableEntryBase {
795
743
  return isStandardBST || isInverseBST;
796
744
  }
797
745
  }
798
- /**
799
- * Time Complexity: O(n)
800
- * Space Complexity: O(1)
801
- */
802
746
  /**
803
747
  * Time Complexity: O(n)
804
748
  * Space Complexity: O(1)
@@ -826,10 +770,6 @@ class BinaryTree extends base_1.IterableEntryBase {
826
770
  }
827
771
  return depth;
828
772
  }
829
- /**
830
- * Time Complexity: O(n)
831
- * Space Complexity: O(1)
832
- */
833
773
  /**
834
774
  * Time Complexity: O(n)
835
775
  * Space Complexity: O(1)
@@ -871,10 +811,6 @@ class BinaryTree extends base_1.IterableEntryBase {
871
811
  return maxHeight;
872
812
  }
873
813
  }
874
- /**
875
- * Time Complexity: O(n)
876
- * Space Complexity: O(log n)
877
- */
878
814
  /**
879
815
  * Time Complexity: O(n)
880
816
  * Space Complexity: O(log n)
@@ -936,10 +872,6 @@ class BinaryTree extends base_1.IterableEntryBase {
936
872
  return (_c = depths.get(beginRoot)) !== null && _c !== void 0 ? _c : -1;
937
873
  }
938
874
  }
939
- /**
940
- * Time Complexity: O(log n)
941
- * Space Complexity: O(log n)
942
- */
943
875
  /**
944
876
  * Time Complexity: O(log n)
945
877
  * Space Complexity: O(log n)
@@ -966,36 +898,40 @@ class BinaryTree extends base_1.IterableEntryBase {
966
898
  result.push(beginNodeEnsured);
967
899
  return isReverse ? result.reverse() : result;
968
900
  }
969
- /**
970
- * Time Complexity: O(log n)
971
- * Space Complexity: O(1)
972
- */
973
901
  /**
974
902
  * Time Complexity: O(log n)
975
903
  * Space Complexity: O(1)
976
904
  *
977
- * The `getLeftMost` function returns the leftmost node in a binary tree, either using recursive or
978
- * iterative traversal.
979
- * @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter represents the
980
- * starting point for finding the leftmost node in a binary tree. It can be either a root node (`R`),
981
- * a key or node or entry (`BTNKeyOrNodeOrEntry<K, V, NODE>`), or `null` or `undefined`.
982
- * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type
983
- * of iteration to be performed. It can have two possible values:
984
- * @returns The function `getLeftMost` returns the leftmost node in a binary tree.
905
+ * The function `getLeftMost` retrieves the leftmost node in a binary tree using either recursive or
906
+ * tail-recursive iteration.
907
+ * @param {C} callback - The `callback` parameter is a function that will be called with the leftmost
908
+ * node of a binary tree or null if the tree is empty. It has a default value of `_DEFAULT_CALLBACK`
909
+ * if not provided explicitly.
910
+ * @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter in the
911
+ * `getLeftMost` function represents the starting point for finding the leftmost node in a binary
912
+ * tree. It can be either a reference to the root node of the tree (`R`), or a key, node, or entry in
913
+ * the binary tree structure (`
914
+ * @param {IterationType} iterationType - The `iterationType` parameter in the `getLeftMost` function
915
+ * specifies the type of iteration to be used when traversing the binary tree nodes. It can have two
916
+ * possible values:
917
+ * @returns The `getLeftMost` function returns the result of the callback function `C` applied to the
918
+ * leftmost node in the binary tree starting from the `beginRoot` node. If the `beginRoot` is `NIL`,
919
+ * it returns the result of the callback function applied to `undefined`. If the `beginRoot` is not a
920
+ * real node, it returns the result of the callback function applied
985
921
  */
986
- getLeftMost(beginRoot = this.root, iterationType = this.iterationType) {
922
+ getLeftMost(callback = this._DEFAULT_CALLBACK, beginRoot = this.root, iterationType = this.iterationType) {
987
923
  if (this.isNIL(beginRoot))
988
- return beginRoot;
924
+ return callback(undefined);
989
925
  beginRoot = this.ensureNode(beginRoot);
990
926
  if (!this.isRealNode(beginRoot))
991
- return beginRoot;
927
+ return callback(beginRoot);
992
928
  if (iterationType === 'RECURSIVE') {
993
929
  const dfs = (cur) => {
994
930
  if (!this.isRealNode(cur.left))
995
931
  return cur;
996
932
  return dfs(cur.left);
997
933
  };
998
- return dfs(beginRoot);
934
+ return callback(dfs(beginRoot));
999
935
  }
1000
936
  else {
1001
937
  // Indirect implementation of iteration using tail recursion optimization
@@ -1004,41 +940,45 @@ class BinaryTree extends base_1.IterableEntryBase {
1004
940
  return cur;
1005
941
  return dfs.cont(cur.left);
1006
942
  });
1007
- return dfs(beginRoot);
943
+ return callback(dfs(beginRoot));
1008
944
  }
1009
945
  }
1010
- /**
1011
- * Time Complexity: O(log n)
1012
- * Space Complexity: O(1)
1013
- */
1014
946
  /**
1015
947
  * Time Complexity: O(log n)
1016
948
  * Space Complexity: O(1)
1017
949
  *
1018
- * The `getRightMost` function returns the rightmost node in a binary tree, either recursively or
1019
- * iteratively.
1020
- * @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter represents the
1021
- * starting point for finding the rightmost node in a binary tree. It can be either a root node
1022
- * (`R`), a key or node or entry (`BTNKeyOrNodeOrEntry<K, V, NODE>`), or `null` or `undefined`.
1023
- * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type
1024
- * of iteration to be performed when finding the rightmost node in a binary tree. It can have two
1025
- * possible values:
1026
- * @returns The function `getRightMost` returns a NODE object, `null`, or `undefined`.
1027
- */
1028
- getRightMost(beginRoot = this.root, iterationType = this.iterationType) {
950
+ * The function `getRightMost` retrieves the rightmost node in a binary tree using either recursive
951
+ * or iterative traversal methods.
952
+ * @param {C} callback - The `callback` parameter is a function that will be called with the result
953
+ * of the operation. It has a generic type `C` which extends `BTNCallback<OptBTNOrNull<NODE>>`. The
954
+ * default value for `callback` is `this._DEFAULT_CALLBACK` if it is not provided.
955
+ * @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter in the
956
+ * `getRightMost` function represents the starting point for finding the rightmost node in a binary
957
+ * tree. It can be either a reference to the root node of the tree (`this.root`) or a specific key,
958
+ * node, or entry in the tree. If
959
+ * @param {IterationType} iterationType - The `iterationType` parameter in the `getRightMost`
960
+ * function specifies the type of iteration to be used when finding the rightmost node in a binary
961
+ * tree. It can have two possible values:
962
+ * @returns The `getRightMost` function returns the result of the callback function `C` applied to
963
+ * the rightmost node in the binary tree. The rightmost node is found either through a recursive
964
+ * depth-first search (if `iterationType` is 'RECURSIVE') or through an indirect implementation of
965
+ * iteration using tail recursion optimization. The result of the callback function applied to the
966
+ * rightmost node is returned
967
+ */
968
+ getRightMost(callback = this._DEFAULT_CALLBACK, beginRoot = this.root, iterationType = this.iterationType) {
1029
969
  if (this.isNIL(beginRoot))
1030
- return beginRoot;
970
+ return callback(undefined);
1031
971
  // TODO support get right most by passing key in
1032
972
  beginRoot = this.ensureNode(beginRoot);
1033
973
  if (!beginRoot)
1034
- return beginRoot;
974
+ return callback(beginRoot);
1035
975
  if (iterationType === 'RECURSIVE') {
1036
976
  const dfs = (cur) => {
1037
977
  if (!this.isRealNode(cur.right))
1038
978
  return cur;
1039
979
  return dfs(cur.right);
1040
980
  };
1041
- return dfs(beginRoot);
981
+ return callback(dfs(beginRoot));
1042
982
  }
1043
983
  else {
1044
984
  // Indirect implementation of iteration using tail recursion optimization
@@ -1047,13 +987,9 @@ class BinaryTree extends base_1.IterableEntryBase {
1047
987
  return cur;
1048
988
  return dfs.cont(cur.right);
1049
989
  });
1050
- return dfs(beginRoot);
990
+ return callback(dfs(beginRoot));
1051
991
  }
1052
992
  }
1053
- /**
1054
- * Time Complexity: O(log n)
1055
- * Space Complexity: O(1)
1056
- */
1057
993
  /**
1058
994
  * Time Complexity: O(log n)
1059
995
  * Space Complexity: O(1)
@@ -1077,10 +1013,6 @@ class BinaryTree extends base_1.IterableEntryBase {
1077
1013
  return node;
1078
1014
  }
1079
1015
  }
1080
- /**
1081
- * Time Complexity: O(log n)
1082
- * Space Complexity: O(1)
1083
- */
1084
1016
  /**
1085
1017
  * Time Complexity: O(log n)
1086
1018
  * Space Complexity: O(1)
@@ -1095,7 +1027,7 @@ class BinaryTree extends base_1.IterableEntryBase {
1095
1027
  if (!this.isRealNode(x))
1096
1028
  return undefined;
1097
1029
  if (this.isRealNode(x.right)) {
1098
- return this.getLeftMost(x.right);
1030
+ return this.getLeftMost(node => node, x.right);
1099
1031
  }
1100
1032
  let y = x.parent;
1101
1033
  while (this.isRealNode(y) && x === y.right) {
@@ -1104,10 +1036,6 @@ class BinaryTree extends base_1.IterableEntryBase {
1104
1036
  }
1105
1037
  return y;
1106
1038
  }
1107
- /**
1108
- * Time complexity: O(n)
1109
- * Space complexity: O(n)
1110
- */
1111
1039
  /**
1112
1040
  * Time complexity: O(n)
1113
1041
  * Space complexity: O(n)
@@ -1131,116 +1059,12 @@ class BinaryTree extends base_1.IterableEntryBase {
1131
1059
  * values will
1132
1060
  * @returns an array of the return types of the callback function.
1133
1061
  */
1134
- dfs(callback = this._DEFAULT_CALLBACK, pattern = 'IN', beginRoot = this.root, iterationType = 'ITERATIVE', includeNull = false) {
1062
+ dfs(callback = this._DEFAULT_CALLBACK, pattern = 'IN', beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
1135
1063
  beginRoot = this.ensureNode(beginRoot);
1136
1064
  if (!beginRoot)
1137
1065
  return [];
1138
- const ans = [];
1139
- if (iterationType === 'RECURSIVE') {
1140
- const dfs = (node) => {
1141
- switch (pattern) {
1142
- case 'IN':
1143
- if (includeNull) {
1144
- if (this.isRealNode(node) && this.isNodeOrNull(node.left))
1145
- dfs(node.left);
1146
- this.isNodeOrNull(node) && ans.push(callback(node));
1147
- if (this.isRealNode(node) && this.isNodeOrNull(node.right))
1148
- dfs(node.right);
1149
- }
1150
- else {
1151
- if (this.isRealNode(node) && this.isRealNode(node.left))
1152
- dfs(node.left);
1153
- this.isRealNode(node) && ans.push(callback(node));
1154
- if (this.isRealNode(node) && this.isRealNode(node.right))
1155
- dfs(node.right);
1156
- }
1157
- break;
1158
- case 'PRE':
1159
- if (includeNull) {
1160
- this.isNodeOrNull(node) && ans.push(callback(node));
1161
- if (this.isRealNode(node) && this.isNodeOrNull(node.left))
1162
- dfs(node.left);
1163
- if (this.isRealNode(node) && this.isNodeOrNull(node.right))
1164
- dfs(node.right);
1165
- }
1166
- else {
1167
- this.isRealNode(node) && ans.push(callback(node));
1168
- if (this.isRealNode(node) && this.isRealNode(node.left))
1169
- dfs(node.left);
1170
- if (this.isRealNode(node) && this.isRealNode(node.right))
1171
- dfs(node.right);
1172
- }
1173
- break;
1174
- case 'POST':
1175
- if (includeNull) {
1176
- if (this.isRealNode(node) && this.isNodeOrNull(node.left))
1177
- dfs(node.left);
1178
- if (this.isRealNode(node) && this.isNodeOrNull(node.right))
1179
- dfs(node.right);
1180
- this.isNodeOrNull(node) && ans.push(callback(node));
1181
- }
1182
- else {
1183
- if (this.isRealNode(node) && this.isRealNode(node.left))
1184
- dfs(node.left);
1185
- if (this.isRealNode(node) && this.isRealNode(node.right))
1186
- dfs(node.right);
1187
- this.isRealNode(node) && ans.push(callback(node));
1188
- }
1189
- break;
1190
- }
1191
- };
1192
- dfs(beginRoot);
1193
- }
1194
- else {
1195
- // 0: visit, 1: print
1196
- const stack = [{ opt: 0, node: beginRoot }];
1197
- while (stack.length > 0) {
1198
- const cur = stack.pop();
1199
- if (cur === undefined || this.isNIL(cur.node))
1200
- continue;
1201
- if (includeNull) {
1202
- if (cur.node === undefined)
1203
- continue;
1204
- }
1205
- else {
1206
- if (cur.node === null || cur.node === undefined)
1207
- continue;
1208
- }
1209
- if (cur.opt === 1) {
1210
- ans.push(callback(cur.node));
1211
- }
1212
- else {
1213
- switch (pattern) {
1214
- case 'IN':
1215
- cur.node && stack.push({ opt: 0, node: cur.node.right });
1216
- stack.push({ opt: 1, node: cur.node });
1217
- cur.node && stack.push({ opt: 0, node: cur.node.left });
1218
- break;
1219
- case 'PRE':
1220
- cur.node && stack.push({ opt: 0, node: cur.node.right });
1221
- cur.node && stack.push({ opt: 0, node: cur.node.left });
1222
- stack.push({ opt: 1, node: cur.node });
1223
- break;
1224
- case 'POST':
1225
- stack.push({ opt: 1, node: cur.node });
1226
- cur.node && stack.push({ opt: 0, node: cur.node.right });
1227
- cur.node && stack.push({ opt: 0, node: cur.node.left });
1228
- break;
1229
- default:
1230
- cur.node && stack.push({ opt: 0, node: cur.node.right });
1231
- stack.push({ opt: 1, node: cur.node });
1232
- cur.node && stack.push({ opt: 0, node: cur.node.left });
1233
- break;
1234
- }
1235
- }
1236
- }
1237
- }
1238
- return ans;
1066
+ return this._dfs(callback, pattern, beginRoot, iterationType, includeNull);
1239
1067
  }
1240
- /**
1241
- * Time complexity: O(n)
1242
- * Space complexity: O(n)
1243
- */
1244
1068
  /**
1245
1069
  * Time complexity: O(n)
1246
1070
  * Space complexity: O(n)
@@ -1276,9 +1100,9 @@ class BinaryTree extends base_1.IterableEntryBase {
1276
1100
  const current = queue.shift();
1277
1101
  ans.push(callback(current));
1278
1102
  if (includeNull) {
1279
- if (current && this.isNodeOrNull(current.left))
1103
+ if (current && this.isRealNodeOrNull(current.left))
1280
1104
  queue.push(current.left);
1281
- if (current && this.isNodeOrNull(current.right))
1105
+ if (current && this.isRealNodeOrNull(current.right))
1282
1106
  queue.push(current.right);
1283
1107
  }
1284
1108
  else {
@@ -1299,9 +1123,9 @@ class BinaryTree extends base_1.IterableEntryBase {
1299
1123
  const current = queue.shift();
1300
1124
  ans.push(callback(current));
1301
1125
  if (includeNull) {
1302
- if (current && this.isNodeOrNull(current.left))
1126
+ if (current && this.isRealNodeOrNull(current.left))
1303
1127
  queue.push(current.left);
1304
- if (current && this.isNodeOrNull(current.right))
1128
+ if (current && this.isRealNodeOrNull(current.right))
1305
1129
  queue.push(current.right);
1306
1130
  }
1307
1131
  else {
@@ -1318,7 +1142,55 @@ class BinaryTree extends base_1.IterableEntryBase {
1318
1142
  /**
1319
1143
  * Time complexity: O(n)
1320
1144
  * Space complexity: O(n)
1321
- */
1145
+ *
1146
+ * The `leaves` function in TypeScript iterates through a binary tree to find and return the leaf
1147
+ * nodes based on a specified callback and iteration type.
1148
+ * @param {C} callback - The `callback` parameter is a function that will be called on each leaf node
1149
+ * in the binary tree. It is a generic type `C` that extends `BTNCallback<NODE | null>`, where `NODE`
1150
+ * represents a node in the binary tree. The default value for `callback` is
1151
+ * @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter in the `leaves`
1152
+ * method is used to specify the starting point for finding and processing the leaves of a binary
1153
+ * tree. It represents the root node of the binary tree or a specific key, node, or entry within the
1154
+ * tree from which the search for leaves should begin
1155
+ * @param {IterationType} iterationType - The `iterationType` parameter in the `leaves` method
1156
+ * specifies the type of iteration to be performed when collecting the leaves of a binary tree. It
1157
+ * can have two possible values:
1158
+ * @returns The `leaves` method returns an array of values that are the result of applying the
1159
+ * provided callback function to the leaf nodes in the binary tree structure.
1160
+ */
1161
+ leaves(callback = this._DEFAULT_CALLBACK, beginRoot = this.root, iterationType = this.iterationType) {
1162
+ beginRoot = this.ensureNode(beginRoot);
1163
+ const leaves = [];
1164
+ if (!this.isRealNode(beginRoot)) {
1165
+ return [];
1166
+ }
1167
+ if (iterationType === 'RECURSIVE') {
1168
+ const dfs = (cur) => {
1169
+ if (this.isLeaf(cur)) {
1170
+ leaves.push(callback(cur));
1171
+ }
1172
+ if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right))
1173
+ return;
1174
+ this.isRealNode(cur.left) && dfs(cur.left);
1175
+ this.isRealNode(cur.right) && dfs(cur.right);
1176
+ };
1177
+ dfs(beginRoot);
1178
+ }
1179
+ else {
1180
+ const queue = new queue_1.Queue([beginRoot]);
1181
+ while (queue.size > 0) {
1182
+ const cur = queue.shift();
1183
+ if (this.isRealNode(cur)) {
1184
+ if (this.isLeaf(cur)) {
1185
+ leaves.push(callback(cur));
1186
+ }
1187
+ this.isRealNode(cur.left) && queue.push(cur.left);
1188
+ this.isRealNode(cur.right) && queue.push(cur.right);
1189
+ }
1190
+ }
1191
+ }
1192
+ return leaves;
1193
+ }
1322
1194
  /**
1323
1195
  * Time complexity: O(n)
1324
1196
  * Space complexity: O(n)
@@ -1351,9 +1223,9 @@ class BinaryTree extends base_1.IterableEntryBase {
1351
1223
  levelsNodes[level] = [];
1352
1224
  levelsNodes[level].push(callback(node));
1353
1225
  if (includeNull) {
1354
- if (node && this.isNodeOrNull(node.left))
1226
+ if (node && this.isRealNodeOrNull(node.left))
1355
1227
  _recursive(node.left, level + 1);
1356
- if (node && this.isNodeOrNull(node.right))
1228
+ if (node && this.isRealNodeOrNull(node.right))
1357
1229
  _recursive(node.right, level + 1);
1358
1230
  }
1359
1231
  else {
@@ -1374,9 +1246,9 @@ class BinaryTree extends base_1.IterableEntryBase {
1374
1246
  levelsNodes[level] = [];
1375
1247
  levelsNodes[level].push(callback(node));
1376
1248
  if (includeNull) {
1377
- if (node && this.isNodeOrNull(node.right))
1249
+ if (node && this.isRealNodeOrNull(node.right))
1378
1250
  stack.push([node.right, level + 1]);
1379
- if (node && this.isNodeOrNull(node.left))
1251
+ if (node && this.isRealNodeOrNull(node.left))
1380
1252
  stack.push([node.left, level + 1]);
1381
1253
  }
1382
1254
  else {
@@ -1389,10 +1261,6 @@ class BinaryTree extends base_1.IterableEntryBase {
1389
1261
  }
1390
1262
  return levelsNodes;
1391
1263
  }
1392
- /**
1393
- * Time complexity: O(n)
1394
- * Space complexity: O(n)
1395
- */
1396
1264
  /**
1397
1265
  * Time complexity: O(n)
1398
1266
  * Space complexity: O(n)
@@ -1497,10 +1365,6 @@ class BinaryTree extends base_1.IterableEntryBase {
1497
1365
  }
1498
1366
  return ans;
1499
1367
  }
1500
- /**
1501
- * Time complexity: O(n)
1502
- * Space complexity: O(n)
1503
- */
1504
1368
  /**
1505
1369
  * Time complexity: O(n)
1506
1370
  * Space complexity: O(n)
@@ -1518,10 +1382,6 @@ class BinaryTree extends base_1.IterableEntryBase {
1518
1382
  }, this.root, this.iterationType, true);
1519
1383
  return cloned;
1520
1384
  }
1521
- /**
1522
- * Time Complexity: O(n)
1523
- * Space Complexity: O(n)
1524
- */
1525
1385
  /**
1526
1386
  * Time Complexity: O(n)
1527
1387
  * Space Complexity: O(n)
@@ -1547,10 +1407,6 @@ class BinaryTree extends base_1.IterableEntryBase {
1547
1407
  }
1548
1408
  return newTree;
1549
1409
  }
1550
- /**
1551
- * Time Complexity: O(n)
1552
- * Space Complexity: O(n)
1553
- */
1554
1410
  /**
1555
1411
  * Time Complexity: O(n)
1556
1412
  * Space Complexity: O(n)
@@ -1583,10 +1439,6 @@ class BinaryTree extends base_1.IterableEntryBase {
1583
1439
  // // return newTree;
1584
1440
  // // }
1585
1441
  //
1586
- /**
1587
- * Time Complexity: O(n)
1588
- * Space Complexity: O(n)
1589
- */
1590
1442
  /**
1591
1443
  * Time Complexity: O(n)
1592
1444
  * Space Complexity: O(n)
@@ -1604,29 +1456,165 @@ class BinaryTree extends base_1.IterableEntryBase {
1604
1456
  print(beginRoot = this.root, options) {
1605
1457
  const opts = Object.assign({ isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false }, options);
1606
1458
  beginRoot = this.ensureNode(beginRoot);
1459
+ let output = '';
1607
1460
  if (!beginRoot)
1608
- return;
1461
+ return output;
1609
1462
  if (opts.isShowUndefined)
1610
- console.log(`U for undefined
1611
- `);
1463
+ output += `U for undefined
1464
+ `;
1612
1465
  if (opts.isShowNull)
1613
- console.log(`N for null
1614
- `);
1466
+ output += `N for null
1467
+ `;
1615
1468
  if (opts.isShowRedBlackNIL)
1616
- console.log(`S for Sentinel Node(NIL)
1617
- `);
1469
+ output += `S for Sentinel Node(NIL)
1470
+ `;
1618
1471
  const display = (root) => {
1619
1472
  const [lines, , ,] = this._displayAux(root, opts);
1473
+ let paragraph = '';
1620
1474
  for (const line of lines) {
1621
- console.log(line);
1475
+ paragraph += line + '\n';
1622
1476
  }
1477
+ output += paragraph;
1623
1478
  };
1624
1479
  display(beginRoot);
1480
+ return output;
1625
1481
  }
1626
1482
  /**
1627
- * Time Complexity: O(1)
1628
- * Space Complexity: O(1)
1629
- */
1483
+ * Time complexity: O(n)
1484
+ * Space complexity: O(n)
1485
+ *
1486
+ * The function `_dfs` performs a depth-first search traversal on a binary tree structure based on
1487
+ * the specified order pattern and callback function.
1488
+ * @param {C} callback - The `callback` parameter is a function that will be called on each node
1489
+ * visited during the depth-first search. It is of type `C`, which extends
1490
+ * `BTNCallback<OptBTNOrNull<NODE>>`. The default value is set to `this._DEFAULT_CALLBACK` if not
1491
+ * provided.
1492
+ * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `_dfs` method specifies the
1493
+ * order in which the Depth-First Search (DFS) algorithm should traverse the nodes in a binary tree.
1494
+ * It can have one of the following values:
1495
+ * @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter in the `_dfs`
1496
+ * method is used to specify the starting point for the depth-first search traversal in a binary
1497
+ * tree. It can be provided as either the root node of the tree or a key, node, or entry that exists
1498
+ * in the tree. If no specific `
1499
+ * @param {IterationType} iterationType - The `iterationType` parameter in the `_dfs` method
1500
+ * specifies the type of iteration to be performed during the Depth-First Search (DFS) traversal. It
1501
+ * can have two possible values:
1502
+ * @param [includeNull=false] - The `includeNull` parameter in the `_dfs` method is a boolean flag
1503
+ * that determines whether null nodes should be included in the depth-first search traversal. If
1504
+ * `includeNull` is set to `true`, the traversal will consider null nodes as valid nodes to visit and
1505
+ * process. If set to `
1506
+ * @param shouldVisitLeft - The `shouldVisitLeft` parameter is a function that takes a node as input
1507
+ * and returns a boolean value. It is used to determine whether the left child of a node should be
1508
+ * visited during the depth-first search traversal. By default, it checks if the node is truthy (not
1509
+ * null or undefined
1510
+ * @param shouldVisitRight - The `shouldVisitRight` parameter is a function that takes a node as
1511
+ * input and returns a boolean value. It is used to determine whether the right child of a node
1512
+ * should be visited during the depth-first search traversal. The default implementation checks if
1513
+ * the node is truthy before visiting the right child.
1514
+ * @param shouldVisitRoot - The `shouldVisitRoot` parameter is a function that takes a node as an
1515
+ * argument and returns a boolean value. It is used to determine whether a given node should be
1516
+ * visited during the depth-first search traversal based on certain conditions. The default
1517
+ * implementation checks if the node is a real node or null based
1518
+ * @param shouldProcessRoot - The `shouldProcessRoot` parameter is a function that takes a node as
1519
+ * input and returns a boolean value indicating whether the node should be processed during the
1520
+ * depth-first search traversal. The default implementation of this function simply returns `true`,
1521
+ * meaning that by default all nodes will be processed. However, you can
1522
+ * @returns The `_dfs` method returns an array of the return type of the callback function provided
1523
+ * as input.
1524
+ */
1525
+ _dfs(callback = this._DEFAULT_CALLBACK, pattern = 'IN', beginRoot = this.root, iterationType = this.iterationType, includeNull = false, shouldVisitLeft = node => !!node, shouldVisitRight = node => !!node, shouldVisitRoot = node => {
1526
+ if (includeNull)
1527
+ return this.isRealNodeOrNull(node);
1528
+ return this.isRealNode(node);
1529
+ }, shouldProcessRoot = node => true) {
1530
+ beginRoot = this.ensureNode(beginRoot);
1531
+ if (!beginRoot)
1532
+ return [];
1533
+ const ans = [];
1534
+ if (iterationType === 'RECURSIVE') {
1535
+ const dfs = (node) => {
1536
+ if (!shouldVisitRoot(node))
1537
+ return;
1538
+ const visitLeft = () => {
1539
+ if (shouldVisitLeft(node))
1540
+ dfs(node === null || node === void 0 ? void 0 : node.left);
1541
+ };
1542
+ const visitRight = () => {
1543
+ if (shouldVisitRight(node))
1544
+ dfs(node === null || node === void 0 ? void 0 : node.right);
1545
+ };
1546
+ switch (pattern) {
1547
+ case 'IN':
1548
+ visitLeft();
1549
+ if (shouldProcessRoot(node))
1550
+ ans.push(callback(node));
1551
+ visitRight();
1552
+ break;
1553
+ case 'PRE':
1554
+ if (shouldProcessRoot(node))
1555
+ ans.push(callback(node));
1556
+ visitLeft();
1557
+ visitRight();
1558
+ break;
1559
+ case 'POST':
1560
+ visitLeft();
1561
+ visitRight();
1562
+ if (shouldProcessRoot(node))
1563
+ ans.push(callback(node));
1564
+ break;
1565
+ }
1566
+ };
1567
+ dfs(beginRoot);
1568
+ }
1569
+ else {
1570
+ const stack = [{ opt: types_1.DFSOperation.VISIT, node: beginRoot }];
1571
+ const pushLeft = (cur) => {
1572
+ var _a;
1573
+ if (shouldVisitLeft(cur.node))
1574
+ stack.push({ opt: types_1.DFSOperation.VISIT, node: (_a = cur.node) === null || _a === void 0 ? void 0 : _a.left });
1575
+ };
1576
+ const pushRight = (cur) => {
1577
+ var _a;
1578
+ if (shouldVisitRight(cur.node))
1579
+ stack.push({ opt: types_1.DFSOperation.VISIT, node: (_a = cur.node) === null || _a === void 0 ? void 0 : _a.right });
1580
+ };
1581
+ const pushRoot = (cur) => {
1582
+ if (shouldVisitRoot(cur.node))
1583
+ stack.push({ opt: types_1.DFSOperation.PROCESS, node: cur.node });
1584
+ };
1585
+ while (stack.length > 0) {
1586
+ const cur = stack.pop();
1587
+ if (cur === undefined)
1588
+ continue;
1589
+ if (!shouldVisitRoot(cur.node))
1590
+ continue;
1591
+ if (cur.opt === types_1.DFSOperation.PROCESS) {
1592
+ if (shouldProcessRoot(cur.node))
1593
+ ans.push(callback(cur.node));
1594
+ }
1595
+ else {
1596
+ switch (pattern) {
1597
+ case 'IN':
1598
+ pushRight(cur);
1599
+ pushRoot(cur);
1600
+ pushLeft(cur);
1601
+ break;
1602
+ case 'PRE':
1603
+ pushRight(cur);
1604
+ pushLeft(cur);
1605
+ pushRoot(cur);
1606
+ break;
1607
+ case 'POST':
1608
+ pushRoot(cur);
1609
+ pushRight(cur);
1610
+ pushLeft(cur);
1611
+ break;
1612
+ }
1613
+ }
1614
+ }
1615
+ }
1616
+ return ans;
1617
+ }
1630
1618
  /**
1631
1619
  * Time Complexity: O(1)
1632
1620
  * Space Complexity: O(1)
@@ -1665,10 +1653,6 @@ class BinaryTree extends base_1.IterableEntryBase {
1665
1653
  }
1666
1654
  }
1667
1655
  }
1668
- /**
1669
- * Time Complexity: O(n)
1670
- * Space Complexity: O(n)
1671
- */
1672
1656
  /**
1673
1657
  * Time Complexity: O(n)
1674
1658
  * Space Complexity: O(n)
@@ -1738,10 +1722,6 @@ class BinaryTree extends base_1.IterableEntryBase {
1738
1722
  ];
1739
1723
  }
1740
1724
  }
1741
- /**
1742
- * Time Complexity: O(1)
1743
- * Space Complexity: O(1)
1744
- */
1745
1725
  /**
1746
1726
  * Time Complexity: O(1)
1747
1727
  * Space Complexity: O(1)
@@ -1771,10 +1751,6 @@ class BinaryTree extends base_1.IterableEntryBase {
1771
1751
  }
1772
1752
  return undefined;
1773
1753
  }
1774
- /**
1775
- * Time Complexity: O(1)
1776
- * Space Complexity: O(1)
1777
- */
1778
1754
  /**
1779
1755
  * Time Complexity: O(1)
1780
1756
  * Space Complexity: O(1)
@@ -1804,10 +1780,6 @@ class BinaryTree extends base_1.IterableEntryBase {
1804
1780
  }
1805
1781
  return newNode;
1806
1782
  }
1807
- /**
1808
- * Time Complexity: O(1)
1809
- * Space Complexity: O(1)
1810
- */
1811
1783
  /**
1812
1784
  * Time Complexity: O(1)
1813
1785
  * Space Complexity: O(1)
@@ -1823,10 +1795,6 @@ class BinaryTree extends base_1.IterableEntryBase {
1823
1795
  }
1824
1796
  this._root = v;
1825
1797
  }
1826
- /**
1827
- * Time Complexity: O(1)
1828
- * Space Complexity: O(1)
1829
- */
1830
1798
  /**
1831
1799
  * Time Complexity: O(1)
1832
1800
  * Space Complexity: O(1)