min-heap-typed 1.42.6 → 1.42.8

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.
@@ -88,13 +88,12 @@ class BinaryTree {
88
88
  */
89
89
  constructor(options) {
90
90
  this.iterationType = types_1.IterationType.ITERATIVE;
91
- this._root = undefined;
92
- this._size = 0;
93
- this.defaultOneParamCallback = (node) => node.key;
94
- if (options !== undefined) {
91
+ this._defaultOneParamCallback = (node) => node.key;
92
+ if (options) {
95
93
  const { iterationType = types_1.IterationType.ITERATIVE } = options;
96
94
  this.iterationType = iterationType;
97
95
  }
96
+ this._size = 0;
98
97
  }
99
98
  /**
100
99
  * Get the root node of the binary tree.
@@ -117,20 +116,6 @@ class BinaryTree {
117
116
  createNode(key, value) {
118
117
  return new BinaryTreeNode(key, value);
119
118
  }
120
- /**
121
- * Clear the binary tree, removing all nodes.
122
- */
123
- clear() {
124
- this._setRoot(undefined);
125
- this._size = 0;
126
- }
127
- /**
128
- * Check if the binary tree is empty.
129
- * @returns {boolean} - True if the binary tree is empty, false otherwise.
130
- */
131
- isEmpty() {
132
- return this.size === 0;
133
- }
134
119
  /**
135
120
  * Add a node with the given key and value to the binary tree.
136
121
  * @param {BTNKey | N | null} keyOrNode - The key or node to add to the binary tree.
@@ -164,7 +149,7 @@ class BinaryTree {
164
149
  if (keyOrNode === null) {
165
150
  needInsert = null;
166
151
  }
167
- else if (typeof keyOrNode === 'number') {
152
+ else if (this.isNodeKey(keyOrNode)) {
168
153
  needInsert = this.createNode(keyOrNode, value);
169
154
  }
170
155
  else if (keyOrNode instanceof BinaryTreeNode) {
@@ -173,19 +158,12 @@ class BinaryTree {
173
158
  else {
174
159
  return;
175
160
  }
176
- // const key = typeof keyOrNode === 'number' ? keyOrNode : keyOrNode ? keyOrNode.key : undefined;
177
- // const existNode = key !== undefined ? this.getNode(key, (node: N) => node.key) : undefined;
178
161
  if (this.root) {
179
- // if (existNode) {
180
- // existNode.value = value;
181
- // inserted = existNode;
182
- // } else {
183
162
  inserted = _bfs(this.root, needInsert);
184
- // }
185
163
  }
186
164
  else {
187
165
  this._setRoot(needInsert);
188
- if (needInsert !== null) {
166
+ if (needInsert) {
189
167
  this._size = 1;
190
168
  }
191
169
  else {
@@ -222,40 +200,41 @@ class BinaryTree {
222
200
  * The `refill` function clears the binary tree and adds multiple nodes with the given IDs or nodes and optional data.
223
201
  * @param {(BTNKey | N)[]} keysOrNodes - The `keysOrNodes` parameter is an array that can contain either
224
202
  * `BTNKey` or `N` values.
225
- * @param {N[] | Array<V>} [data] - The `data` parameter is an optional array of values that will be assigned to
203
+ * @param {N[] | Array<V>} [values] - The `data` parameter is an optional array of values that will be assigned to
226
204
  * the nodes being added. If provided, the length of the `data` array should be equal to the length of the `keysOrNodes`
227
205
  * array. Each value in the `data` array will be assigned to the
228
206
  * @returns The method is returning a boolean value.
229
207
  */
230
- refill(keysOrNodes, data) {
208
+ refill(keysOrNodes, values) {
231
209
  this.clear();
232
- return keysOrNodes.length === this.addMany(keysOrNodes, data).length;
210
+ return keysOrNodes.length === this.addMany(keysOrNodes, values).length;
233
211
  }
234
212
  /**
235
213
  * The `delete` function removes a node from a binary search tree and returns the deleted node along
236
214
  * with the parent node that needs to be balanced.
237
215
  * a key (`BTNKey`). If it is a key, the function will find the corresponding node in the
238
216
  * binary tree.
239
- * @returns an array of `BinaryTreeDeletedResult<N>` objects.
217
+ * @returns an array of `BiTreeDeleteResult<N>` objects.
240
218
  * @param {ReturnType<C>} identifier - The `identifier` parameter is either a
241
219
  * `BTNKey` or a generic type `N`. It represents the property of the node that we are
242
220
  * searching for. It can be a specific key value or any other property of the node.
243
221
  * @param callback - The `callback` parameter is a function that takes a node as input and returns a
244
222
  * value. This value is compared with the `identifier` parameter to determine if the node should be
245
223
  * included in the result. The `callback` parameter has a default value of
246
- * `this.defaultOneParamCallback`, which
224
+ * `this._defaultOneParamCallback`, which
247
225
  */
248
- delete(identifier, callback = this.defaultOneParamCallback) {
249
- const bstDeletedResult = [];
226
+ delete(identifier, callback = this._defaultOneParamCallback) {
227
+ const deletedResult = [];
250
228
  if (!this.root)
251
- return bstDeletedResult;
229
+ return deletedResult;
252
230
  if (identifier instanceof BinaryTreeNode)
253
231
  callback = (node => node);
254
232
  const curr = this.getNode(identifier, callback);
255
233
  if (!curr)
256
- return bstDeletedResult;
234
+ return deletedResult;
257
235
  const parent = (curr === null || curr === void 0 ? void 0 : curr.parent) ? curr.parent : null;
258
- let needBalanced = null, orgCurrent = curr;
236
+ let needBalanced = undefined;
237
+ let orgCurrent = curr;
259
238
  if (!curr.left) {
260
239
  if (!parent) {
261
240
  // Handle the case when there's only one root node
@@ -287,8 +266,8 @@ class BinaryTree {
287
266
  }
288
267
  }
289
268
  this._size = this.size - 1;
290
- bstDeletedResult.push({ deleted: orgCurrent, needBalanced });
291
- return bstDeletedResult;
269
+ deletedResult.push({ deleted: orgCurrent, needBalanced });
270
+ return deletedResult;
292
271
  }
293
272
  /**
294
273
  * The function `getDepth` calculates the depth of a given node in a binary tree relative to a
@@ -303,10 +282,8 @@ class BinaryTree {
303
282
  * @returns the depth of the `distNode` relative to the `beginRoot`.
304
283
  */
305
284
  getDepth(distNode, beginRoot = this.root) {
306
- if (typeof distNode === 'number')
307
- distNode = this.getNode(distNode);
308
- if (typeof beginRoot === 'number')
309
- beginRoot = this.getNode(beginRoot);
285
+ distNode = this.ensureNotKey(distNode);
286
+ beginRoot = this.ensureNotKey(beginRoot);
310
287
  let depth = 0;
311
288
  while (distNode === null || distNode === void 0 ? void 0 : distNode.parent) {
312
289
  if (distNode === beginRoot) {
@@ -330,8 +307,7 @@ class BinaryTree {
330
307
  * @returns the height of the binary tree.
331
308
  */
332
309
  getHeight(beginRoot = this.root, iterationType = this.iterationType) {
333
- if (typeof beginRoot === 'number')
334
- beginRoot = this.getNode(beginRoot);
310
+ beginRoot = this.ensureNotKey(beginRoot);
335
311
  if (!beginRoot)
336
312
  return -1;
337
313
  if (iterationType === types_1.IterationType.RECURSIVE) {
@@ -352,12 +328,10 @@ class BinaryTree {
352
328
  let maxHeight = 0;
353
329
  while (stack.length > 0) {
354
330
  const { node, depth } = stack.pop();
355
- if (node.left) {
331
+ if (node.left)
356
332
  stack.push({ node: node.left, depth: depth + 1 });
357
- }
358
- if (node.right) {
333
+ if (node.right)
359
334
  stack.push({ node: node.right, depth: depth + 1 });
360
- }
361
335
  maxHeight = Math.max(maxHeight, depth);
362
336
  }
363
337
  return maxHeight;
@@ -375,6 +349,7 @@ class BinaryTree {
375
349
  */
376
350
  getMinHeight(beginRoot = this.root, iterationType = this.iterationType) {
377
351
  var _a, _b, _c;
352
+ beginRoot = this.ensureNotKey(beginRoot);
378
353
  if (!beginRoot)
379
354
  return -1;
380
355
  if (iterationType === types_1.IterationType.RECURSIVE) {
@@ -436,7 +411,7 @@ class BinaryTree {
436
411
  * @param callback - The `callback` parameter is a function that takes a node as input and returns a
437
412
  * value. This value is compared with the `identifier` parameter to determine if the node should be
438
413
  * included in the result. The `callback` parameter has a default value of
439
- * `this.defaultOneParamCallback`, which
414
+ * `this._defaultOneParamCallback`, which
440
415
  * @param [onlyOne=false] - A boolean value indicating whether to stop searching after finding the
441
416
  * first node that matches the identifier. If set to true, the function will return an array with
442
417
  * only one element (or an empty array if no matching node is found). If set to false (default), the
@@ -448,11 +423,14 @@ class BinaryTree {
448
423
  * traverse the binary tree. It can have two possible values:
449
424
  * @returns The function `getNodes` returns an array of nodes (`N[]`).
450
425
  */
451
- getNodes(identifier, callback = this.defaultOneParamCallback, onlyOne = false, beginRoot = this.root, iterationType = this.iterationType) {
426
+ getNodes(identifier, callback = this._defaultOneParamCallback, onlyOne = false, beginRoot = this.root, iterationType = this.iterationType) {
452
427
  if (!beginRoot)
453
428
  return [];
454
429
  if (identifier instanceof BinaryTreeNode)
455
430
  callback = (node => node);
431
+ beginRoot = this.ensureNotKey(beginRoot);
432
+ if (!beginRoot)
433
+ return [];
456
434
  const ans = [];
457
435
  if (iterationType === types_1.IterationType.RECURSIVE) {
458
436
  const _traverse = (cur) => {
@@ -493,7 +471,7 @@ class BinaryTree {
493
471
  * @param callback - The `callback` parameter is a function that is used to determine whether a node
494
472
  * matches the desired criteria. It takes a node as input and returns a boolean value indicating
495
473
  * whether the node matches the criteria or not. The default callback function
496
- * `this.defaultOneParamCallback` is used if no callback function is
474
+ * `this._defaultOneParamCallback` is used if no callback function is
497
475
  * @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
498
476
  * the node from which the search should begin. By default, it is set to `this.root`, which means the
499
477
  * search will start from the root node of the binary tree. However, you can provide a different node
@@ -502,7 +480,7 @@ class BinaryTree {
502
480
  * performed when searching for nodes in the binary tree. It can have one of the following values:
503
481
  * @returns a boolean value.
504
482
  */
505
- has(identifier, callback = this.defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
483
+ has(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
506
484
  if (identifier instanceof BinaryTreeNode)
507
485
  callback = (node => node);
508
486
  return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
@@ -515,19 +493,73 @@ class BinaryTree {
515
493
  * @param callback - The `callback` parameter is a function that is used to determine whether a node
516
494
  * matches the desired criteria. It takes a node as input and returns a boolean value indicating
517
495
  * whether the node matches the criteria or not. The default callback function
518
- * (`this.defaultOneParamCallback`) is used if no callback function is
496
+ * (`this._defaultOneParamCallback`) is used if no callback function is
519
497
  * @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
520
498
  * the root node from which the search should begin.
521
499
  * @param iterationType - The `iterationType` parameter specifies the type of iteration to be
522
500
  * performed when searching for a node in the binary tree. It can have one of the following values:
523
501
  * @returns either the found node (of type N) or null if no node is found.
524
502
  */
525
- getNode(identifier, callback = this.defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
503
+ getNode(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
526
504
  var _a;
527
505
  if (identifier instanceof BinaryTreeNode)
528
506
  callback = (node => node);
529
507
  return (_a = this.getNodes(identifier, callback, true, beginRoot, iterationType)[0]) !== null && _a !== void 0 ? _a : null;
530
508
  }
509
+ /**
510
+ * The function `getNodeByKey` searches for a node in a binary tree by its key, using either
511
+ * recursive or iterative iteration.
512
+ * @param {BTNKey} key - The `key` parameter is the key value that we are searching for in the tree.
513
+ * It is used to find the node with the matching key value.
514
+ * @param iterationType - The `iterationType` parameter is used to determine whether the search for
515
+ * the node with the given key should be performed iteratively or recursively. It has two possible
516
+ * values:
517
+ * @returns The function `getNodeByKey` returns a node (`N`) if a node with the specified key is
518
+ * found in the binary tree. If no node is found, it returns `undefined`.
519
+ */
520
+ getNodeByKey(key, iterationType = types_1.IterationType.ITERATIVE) {
521
+ if (!this.root)
522
+ return undefined;
523
+ if (iterationType === types_1.IterationType.RECURSIVE) {
524
+ const _dfs = (cur) => {
525
+ if (cur.key === key)
526
+ return cur;
527
+ if (!cur.left && !cur.right)
528
+ return;
529
+ if (cur.left)
530
+ return _dfs(cur.left);
531
+ if (cur.right)
532
+ return _dfs(cur.right);
533
+ };
534
+ return _dfs(this.root);
535
+ }
536
+ else {
537
+ const queue = new queue_1.Queue([this.root]);
538
+ while (queue.size > 0) {
539
+ const cur = queue.shift();
540
+ if (cur) {
541
+ if (cur.key === key)
542
+ return cur;
543
+ cur.left && queue.push(cur.left);
544
+ cur.right && queue.push(cur.right);
545
+ }
546
+ }
547
+ }
548
+ }
549
+ /**
550
+ * The function `ensureNotKey` returns the node corresponding to the given key if it is a valid node
551
+ * key, otherwise it returns the key itself.
552
+ * @param {BTNKey | N | null | undefined} key - The `key` parameter can be of type `BTNKey`, `N`,
553
+ * `null`, or `undefined`. It represents a key used to identify a node in a binary tree.
554
+ * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
555
+ * type of iteration to be used when searching for a node by key. It has a default value of
556
+ * `IterationType.ITERATIVE`.
557
+ * @returns either the node corresponding to the given key if it is a valid node key, or the key
558
+ * itself if it is not a valid node key.
559
+ */
560
+ ensureNotKey(key, iterationType = types_1.IterationType.ITERATIVE) {
561
+ return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key;
562
+ }
531
563
  /**
532
564
  * The function `get` returns the first node value in a binary tree that matches the given property or key.
533
565
  * @param {BTNKey | N} identifier - The `identifier` parameter is the key or value of
@@ -536,19 +568,33 @@ class BinaryTree {
536
568
  * @param callback - The `callback` parameter is a function that is used to determine whether a node
537
569
  * matches the desired criteria. It takes a node as input and returns a boolean value indicating
538
570
  * whether the node matches the criteria or not. The default callback function
539
- * (`this.defaultOneParamCallback`) is used if no callback function is
571
+ * (`this._defaultOneParamCallback`) is used if no callback function is
540
572
  * @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
541
573
  * the root node from which the search should begin.
542
574
  * @param iterationType - The `iterationType` parameter specifies the type of iteration to be
543
575
  * performed when searching for a node in the binary tree. It can have one of the following values:
544
576
  * @returns either the found value (of type V) or undefined if no node value is found.
545
577
  */
546
- get(identifier, callback = this.defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
578
+ get(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
547
579
  var _a, _b;
548
580
  if (identifier instanceof BinaryTreeNode)
549
581
  callback = (node => node);
550
582
  return (_b = (_a = this.getNode(identifier, callback, beginRoot, iterationType)) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : undefined;
551
583
  }
584
+ /**
585
+ * Clear the binary tree, removing all nodes.
586
+ */
587
+ clear() {
588
+ this._setRoot(undefined);
589
+ this._size = 0;
590
+ }
591
+ /**
592
+ * Check if the binary tree is empty.
593
+ * @returns {boolean} - True if the binary tree is empty, false otherwise.
594
+ */
595
+ isEmpty() {
596
+ return this.size === 0;
597
+ }
552
598
  /**
553
599
  * The function `getPathToRoot` returns an array of nodes starting from a given node and traversing
554
600
  * up to the root node, with the option to reverse the order of the nodes.
@@ -562,6 +608,9 @@ class BinaryTree {
562
608
  getPathToRoot(beginRoot, isReverse = true) {
563
609
  // TODO to support get path through passing key
564
610
  const result = [];
611
+ beginRoot = this.ensureNotKey(beginRoot);
612
+ if (!beginRoot)
613
+ return result;
565
614
  while (beginRoot.parent) {
566
615
  // Array.push + Array.reverse is more efficient than Array.unshift
567
616
  // TODO may consider using Deque, so far this is not the performance bottleneck
@@ -583,13 +632,12 @@ class BinaryTree {
583
632
  * no leftmost node, it returns `null`.
584
633
  */
585
634
  getLeftMost(beginRoot = this.root, iterationType = this.iterationType) {
586
- if (typeof beginRoot === 'number')
587
- beginRoot = this.getNode(beginRoot);
635
+ beginRoot = this.ensureNotKey(beginRoot);
588
636
  if (!beginRoot)
589
637
  return beginRoot;
590
638
  if (iterationType === types_1.IterationType.RECURSIVE) {
591
639
  const _traverse = (cur) => {
592
- if (!cur.left)
640
+ if (!this.isRealNode(cur.left))
593
641
  return cur;
594
642
  return _traverse(cur.left);
595
643
  };
@@ -598,7 +646,7 @@ class BinaryTree {
598
646
  else {
599
647
  // Indirect implementation of iteration using tail recursion optimization
600
648
  const _traverse = (0, utils_1.trampoline)((cur) => {
601
- if (!cur.left)
649
+ if (!this.isRealNode(cur.left))
602
650
  return cur;
603
651
  return _traverse.cont(cur.left);
604
652
  });
@@ -618,11 +666,12 @@ class BinaryTree {
618
666
  */
619
667
  getRightMost(beginRoot = this.root, iterationType = this.iterationType) {
620
668
  // TODO support get right most by passing key in
669
+ beginRoot = this.ensureNotKey(beginRoot);
621
670
  if (!beginRoot)
622
671
  return beginRoot;
623
672
  if (iterationType === types_1.IterationType.RECURSIVE) {
624
673
  const _traverse = (cur) => {
625
- if (!cur.right)
674
+ if (!this.isRealNode(cur.right))
626
675
  return cur;
627
676
  return _traverse(cur.right);
628
677
  };
@@ -631,7 +680,7 @@ class BinaryTree {
631
680
  else {
632
681
  // Indirect implementation of iteration using tail recursion optimization
633
682
  const _traverse = (0, utils_1.trampoline)((cur) => {
634
- if (!cur.right)
683
+ if (!this.isRealNode(cur.right))
635
684
  return cur;
636
685
  return _traverse.cont(cur.right);
637
686
  });
@@ -649,6 +698,7 @@ class BinaryTree {
649
698
  */
650
699
  isSubtreeBST(beginRoot, iterationType = this.iterationType) {
651
700
  // TODO there is a bug
701
+ beginRoot = this.ensureNotKey(beginRoot);
652
702
  if (!beginRoot)
653
703
  return true;
654
704
  if (iterationType === types_1.IterationType.RECURSIVE) {
@@ -706,9 +756,8 @@ class BinaryTree {
706
756
  * @param includeNull - The choice to output null values during binary tree traversal should be provided.
707
757
  * @returns The function `subTreeTraverse` returns an array of `ReturnType<BTNCallback<N>>`.
708
758
  */
709
- subTreeTraverse(callback = this.defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
710
- if (typeof beginRoot === 'number')
711
- beginRoot = this.getNode(beginRoot);
759
+ subTreeTraverse(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
760
+ beginRoot = this.ensureNotKey(beginRoot);
712
761
  const ans = [];
713
762
  if (!beginRoot)
714
763
  return ans;
@@ -747,21 +796,46 @@ class BinaryTree {
747
796
  }
748
797
  return ans;
749
798
  }
750
- isNode(node) {
799
+ /**
800
+ * The function checks if a given node is a real node by verifying if it is an instance of
801
+ * BinaryTreeNode and its key is not NaN.
802
+ * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type.
803
+ * @returns a boolean value.
804
+ */
805
+ isRealNode(node) {
751
806
  return node instanceof BinaryTreeNode && node.key.toString() !== 'NaN';
752
807
  }
808
+ /**
809
+ * The function checks if a given node is a BinaryTreeNode instance and has a key value of NaN.
810
+ * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type.
811
+ * @returns a boolean value.
812
+ */
753
813
  isNIL(node) {
754
814
  return node instanceof BinaryTreeNode && node.key.toString() === 'NaN';
755
815
  }
816
+ /**
817
+ * The function checks if a given node is a real node or null.
818
+ * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type.
819
+ * @returns a boolean value.
820
+ */
756
821
  isNodeOrNull(node) {
757
- return this.isNode(node) || node === null;
822
+ return this.isRealNode(node) || node === null;
823
+ }
824
+ /**
825
+ * The function "isNodeKey" checks if a potential key is a number.
826
+ * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any
827
+ * data type.
828
+ * @returns a boolean value indicating whether the potentialKey is of type number or not.
829
+ */
830
+ isNodeKey(potentialKey) {
831
+ return typeof potentialKey === 'number';
758
832
  }
759
833
  /**
760
834
  * The `dfs` function performs a depth-first search traversal on a binary tree, executing a callback
761
835
  * function on each node according to a specified order pattern.
762
836
  * @param callback - The `callback` parameter is a function that will be called on each node during
763
837
  * the depth-first search traversal. It takes a node as input and returns a value. The default value
764
- * is `this.defaultOneParamCallback`, which is a callback function defined elsewhere in the code.
838
+ * is `this._defaultOneParamCallback`, which is a callback function defined elsewhere in the code.
765
839
  * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter determines the order in which the
766
840
  * nodes are visited during the depth-first search. There are three possible values for `pattern`:
767
841
  * @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node for the depth-first
@@ -772,7 +846,8 @@ class BinaryTree {
772
846
  * @param includeNull - The choice to output null values during binary tree traversal should be provided.
773
847
  * @returns The function `dfs` returns an array of `ReturnType<BTNCallback<N>>` values.
774
848
  */
775
- dfs(callback = this.defaultOneParamCallback, pattern = 'in', beginRoot = this.root, iterationType = types_1.IterationType.ITERATIVE, includeNull = false) {
849
+ dfs(callback = this._defaultOneParamCallback, pattern = 'in', beginRoot = this.root, iterationType = types_1.IterationType.ITERATIVE, includeNull = false) {
850
+ beginRoot = this.ensureNotKey(beginRoot);
776
851
  if (!beginRoot)
777
852
  return [];
778
853
  const ans = [];
@@ -790,7 +865,7 @@ class BinaryTree {
790
865
  else {
791
866
  if (node && node.left)
792
867
  _traverse(node.left);
793
- this.isNode(node) && ans.push(callback(node));
868
+ this.isRealNode(node) && ans.push(callback(node));
794
869
  if (node && node.right)
795
870
  _traverse(node.right);
796
871
  }
@@ -804,7 +879,7 @@ class BinaryTree {
804
879
  _traverse(node.right);
805
880
  }
806
881
  else {
807
- this.isNode(node) && ans.push(callback(node));
882
+ this.isRealNode(node) && ans.push(callback(node));
808
883
  if (node && node.left)
809
884
  _traverse(node.left);
810
885
  if (node && node.right)
@@ -824,7 +899,7 @@ class BinaryTree {
824
899
  _traverse(node.left);
825
900
  if (node && node.right)
826
901
  _traverse(node.right);
827
- this.isNode(node) && ans.push(callback(node));
902
+ this.isRealNode(node) && ans.push(callback(node));
828
903
  }
829
904
  break;
830
905
  }
@@ -882,7 +957,7 @@ class BinaryTree {
882
957
  * function on each node.
883
958
  * @param callback - The `callback` parameter is a function that will be called for each node in the
884
959
  * breadth-first search. It takes a node of type `N` as its argument and returns a value of type
885
- * `ReturnType<BTNCallback<N>>`. The default value for this parameter is `this.defaultOneParamCallback
960
+ * `ReturnType<BTNCallback<N>>`. The default value for this parameter is `this._defaultOneParamCallback
886
961
  * @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node for the breadth-first
887
962
  * search. It determines from which node the search will begin. If `beginRoot` is `null`, the search
888
963
  * will not be performed and an empty array will be returned.
@@ -891,7 +966,8 @@ class BinaryTree {
891
966
  * @param includeNull - The choice to output null values during binary tree traversal should be provided.
892
967
  * @returns The function `bfs` returns an array of `ReturnType<BTNCallback<N>>[]`.
893
968
  */
894
- bfs(callback = this.defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
969
+ bfs(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
970
+ beginRoot = this.ensureNotKey(beginRoot);
895
971
  if (!beginRoot)
896
972
  return [];
897
973
  const ans = [];
@@ -958,10 +1034,11 @@ class BinaryTree {
958
1034
  * level in a binary tree. Each inner array contains the return type of the provided callback
959
1035
  * function `C` applied to the nodes at that level.
960
1036
  */
961
- listLevels(callback = this.defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
962
- if (!beginRoot)
963
- return [];
1037
+ listLevels(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
1038
+ beginRoot = this.ensureNotKey(beginRoot);
964
1039
  const levelsNodes = [];
1040
+ if (!beginRoot)
1041
+ return levelsNodes;
965
1042
  if (iterationType === types_1.IterationType.RECURSIVE) {
966
1043
  const _recursive = (node, level) => {
967
1044
  if (!levelsNodes[level])
@@ -1012,9 +1089,12 @@ class BinaryTree {
1012
1089
  * @returns The function `getPredecessor` returns the predecessor node of the given node `node`.
1013
1090
  */
1014
1091
  getPredecessor(node) {
1092
+ node = this.ensureNotKey(node);
1093
+ if (!this.isRealNode(node))
1094
+ return undefined;
1015
1095
  if (node.left) {
1016
1096
  let predecessor = node.left;
1017
- while (!predecessor || (predecessor.right && predecessor.right !== node)) {
1097
+ while (!this.isRealNode(predecessor) || (this.isRealNode(predecessor.right) && predecessor.right !== node)) {
1018
1098
  if (predecessor) {
1019
1099
  predecessor = predecessor.right;
1020
1100
  }
@@ -1033,6 +1113,9 @@ class BinaryTree {
1033
1113
  * if there is no successor, or `undefined` if the input `x` is `undefined`.
1034
1114
  */
1035
1115
  getSuccessor(x) {
1116
+ x = this.ensureNotKey(x);
1117
+ if (!x)
1118
+ return undefined;
1036
1119
  if (x.right) {
1037
1120
  return this.getLeftMost(x.right);
1038
1121
  }
@@ -1048,7 +1131,7 @@ class BinaryTree {
1048
1131
  * algorithm and returns an array of values obtained by applying a callback function to each node.
1049
1132
  * @param callback - The `callback` parameter is a function that will be called on each node in the
1050
1133
  * tree. It takes a node of type `N` as input and returns a value of type `ReturnType<BTNCallback<N>>`. The
1051
- * default value for this parameter is `this.defaultOneParamCallback`.
1134
+ * default value for this parameter is `this._defaultOneParamCallback`.
1052
1135
  * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter in the `morris` function
1053
1136
  * determines the order in which the nodes of a binary tree are traversed. It can have one of the
1054
1137
  * following values:
@@ -1057,7 +1140,8 @@ class BinaryTree {
1057
1140
  * `beginRoot` is `null`, an empty array will be returned.
1058
1141
  * @returns The `morris` function returns an array of `ReturnType<BTNCallback<N>>` values.
1059
1142
  */
1060
- morris(callback = this.defaultOneParamCallback, pattern = 'in', beginRoot = this.root) {
1143
+ morris(callback = this._defaultOneParamCallback, pattern = 'in', beginRoot = this.root) {
1144
+ beginRoot = this.ensureNotKey(beginRoot);
1061
1145
  if (beginRoot === null)
1062
1146
  return [];
1063
1147
  const ans = [];
@@ -1189,15 +1273,20 @@ class BinaryTree {
1189
1273
  * @returns {N} - The destination node after the swap.
1190
1274
  */
1191
1275
  _swap(srcNode, destNode) {
1192
- const { key, value } = destNode;
1193
- const tempNode = this.createNode(key, value);
1194
- if (tempNode) {
1195
- destNode.key = srcNode.key;
1196
- destNode.value = srcNode.value;
1197
- srcNode.key = tempNode.key;
1198
- srcNode.value = tempNode.value;
1276
+ srcNode = this.ensureNotKey(srcNode);
1277
+ destNode = this.ensureNotKey(destNode);
1278
+ if (srcNode && destNode) {
1279
+ const { key, value } = destNode;
1280
+ const tempNode = this.createNode(key, value);
1281
+ if (tempNode) {
1282
+ destNode.key = srcNode.key;
1283
+ destNode.value = srcNode.value;
1284
+ srcNode.key = tempNode.key;
1285
+ srcNode.value = tempNode.value;
1286
+ }
1287
+ return destNode;
1199
1288
  }
1200
- return destNode;
1289
+ return undefined;
1201
1290
  }
1202
1291
  /**
1203
1292
  * The function `_addTo` adds a new node to a binary tree if there is an available position.
@@ -1211,6 +1300,8 @@ class BinaryTree {
1211
1300
  * If the parent node is null, the function also returns undefined.
1212
1301
  */
1213
1302
  _addTo(newNode, parent) {
1303
+ if (this.isNodeKey(parent))
1304
+ parent = this.getNode(parent);
1214
1305
  if (parent) {
1215
1306
  // When all leaf nodes are null, it will no longer be possible to add new entity nodes to this binary tree.
1216
1307
  // In this scenario, null nodes serve as "sentinel nodes," "virtual nodes," or "placeholder nodes."
@@ -1248,7 +1339,16 @@ class BinaryTree {
1248
1339
  }
1249
1340
  this._root = v;
1250
1341
  }
1342
+ /**
1343
+ * The `print` function is used to display a binary tree structure in a visually appealing way.
1344
+ * @param {N | null | undefined} root - The `root` parameter in the `print` function represents the
1345
+ * root node of a binary tree. It can have one of the following types: `BTNKey`, `N`, `null`, or
1346
+ * `undefined`. The default value is `this.root`, which suggests that `this.root` is the
1347
+ */
1251
1348
  print(beginRoot = this.root) {
1349
+ beginRoot = this.ensureNotKey(beginRoot);
1350
+ if (!beginRoot)
1351
+ return;
1252
1352
  const display = (root) => {
1253
1353
  const [lines, , ,] = _displayAux(root);
1254
1354
  for (const line of lines) {