bst-typed 1.47.5 → 1.47.7

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 (71) hide show
  1. package/dist/data-structures/binary-tree/avl-tree.d.ts +36 -18
  2. package/dist/data-structures/binary-tree/avl-tree.js +46 -29
  3. package/dist/data-structures/binary-tree/binary-tree.d.ts +158 -129
  4. package/dist/data-structures/binary-tree/binary-tree.js +182 -184
  5. package/dist/data-structures/binary-tree/bst.d.ts +73 -63
  6. package/dist/data-structures/binary-tree/bst.js +168 -169
  7. package/dist/data-structures/binary-tree/rb-tree.d.ts +54 -17
  8. package/dist/data-structures/binary-tree/rb-tree.js +77 -31
  9. package/dist/data-structures/binary-tree/tree-multimap.d.ts +29 -40
  10. package/dist/data-structures/binary-tree/tree-multimap.js +66 -136
  11. package/dist/data-structures/graph/abstract-graph.js +1 -1
  12. package/dist/data-structures/hash/hash-map.d.ts +2 -6
  13. package/dist/data-structures/hash/hash-map.js +5 -8
  14. package/dist/data-structures/heap/heap.d.ts +19 -21
  15. package/dist/data-structures/heap/heap.js +52 -34
  16. package/dist/data-structures/heap/max-heap.d.ts +2 -5
  17. package/dist/data-structures/heap/max-heap.js +2 -2
  18. package/dist/data-structures/heap/min-heap.d.ts +2 -5
  19. package/dist/data-structures/heap/min-heap.js +2 -2
  20. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +2 -1
  21. package/dist/data-structures/linked-list/doubly-linked-list.js +9 -1
  22. package/dist/data-structures/linked-list/singly-linked-list.d.ts +2 -1
  23. package/dist/data-structures/linked-list/singly-linked-list.js +8 -1
  24. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +2 -5
  25. package/dist/data-structures/priority-queue/max-priority-queue.js +2 -2
  26. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +2 -5
  27. package/dist/data-structures/priority-queue/min-priority-queue.js +2 -2
  28. package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -5
  29. package/dist/data-structures/priority-queue/priority-queue.js +2 -2
  30. package/dist/data-structures/queue/deque.d.ts +1 -0
  31. package/dist/data-structures/queue/deque.js +3 -0
  32. package/dist/data-structures/queue/queue.d.ts +1 -0
  33. package/dist/data-structures/queue/queue.js +3 -0
  34. package/dist/data-structures/stack/stack.d.ts +2 -1
  35. package/dist/data-structures/stack/stack.js +10 -2
  36. package/dist/data-structures/trie/trie.d.ts +3 -0
  37. package/dist/data-structures/trie/trie.js +19 -4
  38. package/dist/interfaces/binary-tree.d.ts +4 -2
  39. package/dist/types/common.d.ts +7 -0
  40. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
  41. package/dist/types/data-structures/binary-tree/bst.d.ts +2 -2
  42. package/dist/types/data-structures/hash/hash-map.d.ts +1 -2
  43. package/dist/types/data-structures/heap/heap.d.ts +4 -1
  44. package/dist/types/data-structures/priority-queue/priority-queue.d.ts +2 -1
  45. package/package.json +2 -2
  46. package/src/data-structures/binary-tree/avl-tree.ts +61 -31
  47. package/src/data-structures/binary-tree/binary-tree.ts +283 -254
  48. package/src/data-structures/binary-tree/bst.ts +193 -170
  49. package/src/data-structures/binary-tree/rb-tree.ts +87 -32
  50. package/src/data-structures/binary-tree/tree-multimap.ts +76 -136
  51. package/src/data-structures/graph/abstract-graph.ts +1 -1
  52. package/src/data-structures/hash/hash-map.ts +8 -8
  53. package/src/data-structures/heap/heap.ts +57 -39
  54. package/src/data-structures/heap/max-heap.ts +5 -5
  55. package/src/data-structures/heap/min-heap.ts +5 -5
  56. package/src/data-structures/linked-list/doubly-linked-list.ts +10 -1
  57. package/src/data-structures/linked-list/singly-linked-list.ts +9 -1
  58. package/src/data-structures/priority-queue/max-priority-queue.ts +4 -3
  59. package/src/data-structures/priority-queue/min-priority-queue.ts +12 -12
  60. package/src/data-structures/priority-queue/priority-queue.ts +3 -3
  61. package/src/data-structures/queue/deque.ts +4 -0
  62. package/src/data-structures/queue/queue.ts +4 -0
  63. package/src/data-structures/stack/stack.ts +12 -3
  64. package/src/data-structures/trie/trie.ts +23 -4
  65. package/src/interfaces/binary-tree.ts +14 -2
  66. package/src/types/common.ts +15 -1
  67. package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
  68. package/src/types/data-structures/binary-tree/bst.ts +2 -3
  69. package/src/types/data-structures/hash/hash-map.ts +1 -2
  70. package/src/types/data-structures/heap/heap.ts +3 -1
  71. package/src/types/data-structures/priority-queue/priority-queue.ts +3 -1
@@ -17,41 +17,22 @@ const queue_1 = require("../queue");
17
17
  * @template N - The type of the family relationship in the binary tree.
18
18
  */
19
19
  class BinaryTreeNode {
20
- /**
21
- * Creates a new instance of BinaryTreeNode.
22
- * @param {BTNKey} key - The key associated with the node.
23
- * @param {V} value - The value stored in the node.
24
- */
25
20
  constructor(key, value) {
26
21
  this.key = key;
27
22
  this.value = value;
28
23
  }
29
- /**
30
- * Get the left child node.
31
- */
32
24
  get left() {
33
25
  return this._left;
34
26
  }
35
- /**
36
- * Set the left child node.
37
- * @param {N | null | undefined} v - The left child node.
38
- */
39
27
  set left(v) {
40
28
  if (v) {
41
29
  v.parent = this;
42
30
  }
43
31
  this._left = v;
44
32
  }
45
- /**
46
- * Get the right child node.
47
- */
48
33
  get right() {
49
34
  return this._right;
50
35
  }
51
- /**
52
- * Set the right child node.
53
- * @param {N | null | undefined} v - The right child node.
54
- */
55
36
  set right(v) {
56
37
  if (v) {
57
38
  v.parent = this;
@@ -78,33 +59,42 @@ class BinaryTreeNode {
78
59
  }
79
60
  exports.BinaryTreeNode = BinaryTreeNode;
80
61
  /**
81
- * Represents a binary tree data structure.
82
- * @template N - The type of the binary tree's nodes.
62
+ * 1. Two Children Maximum: Each node has at most two children.
63
+ * 2. Left and Right Children: Nodes have distinct left and right children.
64
+ * 3. Depth and Height: Depth is the number of edges from the root to a node; height is the maximum depth in the tree.
65
+ * 4. Subtrees: Each child of a node forms the root of a subtree.
66
+ * 5. Leaf Nodes: Nodes without children are leaves.
67
+ * 6. Internal Nodes: Nodes with at least one child are internal.
68
+ * 7. Balanced Trees: The heights of the left and right subtrees of any node differ by no more than one.
69
+ * 8. Full Trees: Every node has either 0 or 2 children.
70
+ * 9. Complete Trees: All levels are fully filled except possibly the last, filled from left to right.
83
71
  */
84
72
  class BinaryTree {
85
73
  /**
86
- * Creates a new instance of BinaryTree.
87
- * @param {BinaryTreeOptions} [options] - The options for the binary tree.
74
+ * The constructor function initializes a binary tree object with optional elements and options.
75
+ * @param [elements] - An optional iterable of BTNodeExemplar objects. These objects represent the
76
+ * elements to be added to the binary tree.
77
+ * @param [options] - The `options` parameter is an optional object that can contain additional
78
+ * configuration options for the binary tree. In this case, it is of type
79
+ * `Partial<BinaryTreeOptions>`, which means that not all properties of `BinaryTreeOptions` are
80
+ * required.
88
81
  */
89
- constructor(options) {
82
+ constructor(elements, options) {
83
+ this.iterationType = types_1.IterationType.ITERATIVE;
90
84
  this._defaultOneParamCallback = (node) => node.key;
91
85
  if (options) {
92
- this.options = Object.assign({ iterationType: types_1.IterationType.ITERATIVE }, options);
93
- }
94
- else {
95
- this.options = { iterationType: types_1.IterationType.ITERATIVE };
86
+ const { iterationType } = options;
87
+ if (iterationType) {
88
+ this.iterationType = iterationType;
89
+ }
96
90
  }
97
91
  this._size = 0;
92
+ if (elements)
93
+ this.addMany(elements);
98
94
  }
99
- /**
100
- * Get the root node of the binary tree.
101
- */
102
95
  get root() {
103
96
  return this._root;
104
97
  }
105
- /**
106
- * Get the number of nodes in the binary tree.
107
- */
108
98
  get size() {
109
99
  return this._size;
110
100
  }
@@ -117,35 +107,46 @@ class BinaryTree {
117
107
  createNode(key, value) {
118
108
  return new BinaryTreeNode(key, value);
119
109
  }
110
+ /**
111
+ * The function creates a binary tree with the given options.
112
+ * @param [options] - The `options` parameter is an optional object that allows you to customize the
113
+ * behavior of the `BinaryTree` class. It is of type `Partial<BinaryTreeOptions>`, which means that
114
+ * you can provide only a subset of the properties defined in the `BinaryTreeOptions` interface.
115
+ * @returns a new instance of a binary tree.
116
+ */
120
117
  createTree(options) {
121
- return new BinaryTree(Object.assign(Object.assign({}, this.options), options));
118
+ return new BinaryTree([], Object.assign({ iterationType: this.iterationType }, options));
122
119
  }
123
120
  /**
124
- * Time Complexity: O(n)
125
- * Space Complexity: O(1)
126
- * 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.
121
+ * The function checks if a given value is an entry in a binary tree node.
122
+ * @param kne - BTNodeExemplar<V, N> - A generic type representing a node in a binary tree. It has
123
+ * two type parameters V and N, representing the value and node type respectively.
124
+ * @returns a boolean value.
127
125
  */
126
+ isEntry(kne) {
127
+ return Array.isArray(kne) && kne.length === 2;
128
+ }
128
129
  /**
129
- * Time Complexity: O(n)
130
- * Space Complexity: O(1)
130
+ * Time Complexity O(log n) - O(n)
131
+ * Space Complexity O(1)
132
+ */
133
+ /**
134
+ * Time Complexity O(log n) - O(n)
135
+ * Space Complexity O(1)
131
136
  *
132
- * The `add` function adds a new node with a key and value to a binary tree, or updates the value of
133
- * an existing node with the same key.
134
- * @param {BTNKey | N | null | undefined} keyOrNode - The `keyOrNode` parameter can be one of the
135
- * following types:
136
- * @param {V} [value] - The value to be associated with the key or node being added to the binary
137
- * tree.
138
- * @returns The function `add` returns a node (`N`) if it was successfully inserted into the binary
139
- * tree, or `null` or `undefined` if the insertion was not successful.
137
+ * The `add` function adds a new node to a binary tree, either by key or by providing a node object.
138
+ * @param keyOrNodeOrEntry - The parameter `keyOrNodeOrEntry` can be one of the following:
139
+ * @returns The function `add` returns the inserted node (`N`), `null`, or `undefined`.
140
140
  */
141
- add(keyOrNode, value) {
141
+ add(keyOrNodeOrEntry) {
142
+ let inserted, needInsert;
142
143
  const _bfs = (root, newNode) => {
143
144
  const queue = new queue_1.Queue([root]);
144
145
  while (queue.size > 0) {
145
146
  const cur = queue.shift();
146
147
  if (newNode && cur.key === newNode.key) {
147
- cur.value = newNode.value;
148
- return;
148
+ this._replaceNode(cur, newNode);
149
+ return newNode;
149
150
  }
150
151
  const inserted = this._addTo(newNode, cur);
151
152
  if (inserted !== undefined)
@@ -156,15 +157,26 @@ class BinaryTree {
156
157
  queue.push(cur.right);
157
158
  }
158
159
  };
159
- let inserted, needInsert;
160
- if (keyOrNode === null) {
160
+ if (keyOrNodeOrEntry === null) {
161
161
  needInsert = null;
162
162
  }
163
- else if (this.isNodeKey(keyOrNode)) {
164
- needInsert = this.createNode(keyOrNode, value);
163
+ else if (this.isNodeKey(keyOrNodeOrEntry)) {
164
+ needInsert = this.createNode(keyOrNodeOrEntry);
165
165
  }
166
- else if (keyOrNode instanceof BinaryTreeNode) {
167
- needInsert = keyOrNode;
166
+ else if (keyOrNodeOrEntry instanceof BinaryTreeNode) {
167
+ needInsert = keyOrNodeOrEntry;
168
+ }
169
+ else if (this.isEntry(keyOrNodeOrEntry)) {
170
+ const [key, value] = keyOrNodeOrEntry;
171
+ if (key === undefined) {
172
+ return;
173
+ }
174
+ else if (key === null) {
175
+ needInsert = null;
176
+ }
177
+ else {
178
+ needInsert = this.createNode(key, value);
179
+ }
168
180
  }
169
181
  else {
170
182
  return;
@@ -185,35 +197,28 @@ class BinaryTree {
185
197
  return inserted;
186
198
  }
187
199
  /**
188
- * Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
200
+ * Time Complexity: O(k log n) - O(k * n)
189
201
  * Space Complexity: O(1)
202
+ * 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.
190
203
  */
191
204
  /**
192
- * Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
205
+ * Time Complexity: O(k log n) - O(k * n)
193
206
  * Space Complexity: O(1)
194
207
  *
195
- * The `addMany` function takes an array of keys or nodes and an optional array of values, and adds
196
- * each key-value pair to a data structure.
197
- * @param {(BTNKey | N |null | undefined)[]} keysOrNodes - An array of keys or nodes to be added to
198
- * the binary search tree. Each element can be of type `BTNKey` (a key value), `N` (a node), `null`,
199
- * or `undefined`.
200
- * @param {(V | undefined)[]} [values] - The `values` parameter is an optional array of values that
201
- * correspond to the keys or nodes being added. If provided, the values will be associated with the
202
- * keys or nodes during the add operation.
203
- * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
204
- */
205
- addMany(keysOrNodes, values) {
208
+ * The function `addMany` takes in an iterable of `BTNodeExemplar` objects, adds each object to the
209
+ * current instance, and returns an array of the inserted nodes.
210
+ * @param nodes - The `nodes` parameter is an iterable (such as an array or a set) of
211
+ * `BTNodeExemplar<V, N>` objects.
212
+ * @returns The function `addMany` returns an array of values, where each value is either of type
213
+ * `N`, `null`, or `undefined`.
214
+ */
215
+ addMany(nodes) {
206
216
  // TODO not sure addMany not be run multi times
207
- return keysOrNodes.map((keyOrNode, i) => {
208
- if (keyOrNode instanceof BinaryTreeNode) {
209
- return this.add(keyOrNode.key, keyOrNode.value);
210
- }
211
- if (keyOrNode === null) {
212
- return this.add(null);
213
- }
214
- const value = values === null || values === void 0 ? void 0 : values[i];
215
- return this.add(keyOrNode, value);
216
- });
217
+ const inserted = [];
218
+ for (const kne of nodes) {
219
+ inserted.push(this.add(kne));
220
+ }
221
+ return inserted;
217
222
  }
218
223
  /**
219
224
  * Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
@@ -223,22 +228,14 @@ class BinaryTree {
223
228
  * Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
224
229
  * Space Complexity: O(1)
225
230
  *
226
- * The `refill` function clears the binary tree and adds multiple nodes with the given IDs or nodes and optional data.
227
- * @param {(BTNKey | N)[]} keysOrNodes - The `keysOrNodes` parameter is an array that can contain either
228
- * `BTNKey` or `N` values.
229
- * @param {N[] | Array<V>} [values] - The `data` parameter is an optional array of values that will be assigned to
230
- * the nodes being added. If provided, the length of the `data` array should be equal to the length of the `keysOrNodes`
231
- * array. Each value in the `data` array will be assigned to the
232
- * @returns The method is returning a boolean value.
231
+ * The `refill` function clears the current collection and adds new nodes, keys, or entries to it.
232
+ * @param nodesOrKeysOrEntries - The parameter `nodesOrKeysOrEntries` is an iterable object that can
233
+ * contain either `BTNodeExemplar` objects, keys, or entries.
233
234
  */
234
- refill(keysOrNodes, values) {
235
+ refill(nodesOrKeysOrEntries) {
235
236
  this.clear();
236
- return keysOrNodes.length === this.addMany(keysOrNodes, values).length;
237
+ this.addMany(nodesOrKeysOrEntries);
237
238
  }
238
- /**
239
- * Time Complexity: O(n)
240
- * Space Complexity: O(1)
241
- */
242
239
  /**
243
240
  * Time Complexity: O(n)
244
241
  * Space Complexity: O(1)
@@ -287,7 +284,7 @@ class BinaryTree {
287
284
  const leftSubTreeRightMost = this.getRightMost(curr.left);
288
285
  if (leftSubTreeRightMost) {
289
286
  const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
290
- orgCurrent = this._swap(curr, leftSubTreeRightMost);
287
+ orgCurrent = this._swapProperties(curr, leftSubTreeRightMost);
291
288
  if (parentOfLeftSubTreeMax) {
292
289
  if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
293
290
  parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
@@ -320,8 +317,8 @@ class BinaryTree {
320
317
  * @returns the depth of the `distNode` relative to the `beginRoot`.
321
318
  */
322
319
  getDepth(distNode, beginRoot = this.root) {
323
- distNode = this.ensureNotKey(distNode);
324
- beginRoot = this.ensureNotKey(beginRoot);
320
+ distNode = this.ensureNode(distNode);
321
+ beginRoot = this.ensureNode(beginRoot);
325
322
  let depth = 0;
326
323
  while (distNode === null || distNode === void 0 ? void 0 : distNode.parent) {
327
324
  if (distNode === beginRoot) {
@@ -334,8 +331,7 @@ class BinaryTree {
334
331
  }
335
332
  /**
336
333
  * Time Complexity: O(n)
337
- * Space Complexity: O(log n)
338
- * Best Case - O(log n) (when using recursive iterationType), Worst Case - O(n) (when using iterative iterationType)
334
+ * Space Complexity: O(1)
339
335
  */
340
336
  /**
341
337
  * Time Complexity: O(n)
@@ -351,8 +347,8 @@ class BinaryTree {
351
347
  * values:
352
348
  * @returns the height of the binary tree.
353
349
  */
354
- getHeight(beginRoot = this.root, iterationType = this.options.iterationType) {
355
- beginRoot = this.ensureNotKey(beginRoot);
350
+ getHeight(beginRoot = this.root, iterationType = this.iterationType) {
351
+ beginRoot = this.ensureNode(beginRoot);
356
352
  if (!beginRoot)
357
353
  return -1;
358
354
  if (iterationType === types_1.IterationType.RECURSIVE) {
@@ -397,9 +393,9 @@ class BinaryTree {
397
393
  * to calculate the minimum height of a binary tree. It can have two possible values:
398
394
  * @returns The function `getMinHeight` returns the minimum height of a binary tree.
399
395
  */
400
- getMinHeight(beginRoot = this.root, iterationType = this.options.iterationType) {
396
+ getMinHeight(beginRoot = this.root, iterationType = this.iterationType) {
401
397
  var _a, _b, _c;
402
- beginRoot = this.ensureNotKey(beginRoot);
398
+ beginRoot = this.ensureNode(beginRoot);
403
399
  if (!beginRoot)
404
400
  return -1;
405
401
  if (iterationType === types_1.IterationType.RECURSIVE) {
@@ -445,6 +441,7 @@ class BinaryTree {
445
441
  /**
446
442
  * Time Complexity: O(n)
447
443
  * Space Complexity: O(log n)
444
+ * Best Case - O(log n) (when using recursive iterationType), Worst Case - O(n) (when using iterative iterationType)
448
445
  */
449
446
  /**
450
447
  * Time Complexity: O(n)
@@ -460,10 +457,6 @@ class BinaryTree {
460
457
  isPerfectlyBalanced(beginRoot = this.root) {
461
458
  return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
462
459
  }
463
- /**
464
- * Time Complexity: O(n)
465
- * Space Complexity: O(log n).
466
- */
467
460
  /**
468
461
  * Time Complexity: O(n)
469
462
  * Space Complexity: O(log n).
@@ -489,10 +482,10 @@ class BinaryTree {
489
482
  * traverse the binary tree. It can have two possible values:
490
483
  * @returns an array of nodes of type `N`.
491
484
  */
492
- getNodes(identifier, callback = this._defaultOneParamCallback, onlyOne = false, beginRoot = this.root, iterationType = this.options.iterationType) {
485
+ getNodes(identifier, callback = this._defaultOneParamCallback, onlyOne = false, beginRoot = this.root, iterationType = this.iterationType) {
493
486
  if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
494
487
  callback = (node => node);
495
- beginRoot = this.ensureNotKey(beginRoot);
488
+ beginRoot = this.ensureNode(beginRoot);
496
489
  if (!beginRoot)
497
490
  return [];
498
491
  const ans = [];
@@ -527,10 +520,6 @@ class BinaryTree {
527
520
  }
528
521
  return ans;
529
522
  }
530
- /**
531
- * Time Complexity: O(n)
532
- * Space Complexity: O(log n).
533
- */
534
523
  /**
535
524
  * Time Complexity: O(n)
536
525
  *
@@ -551,15 +540,11 @@ class BinaryTree {
551
540
  * be performed in a pre-order, in-order, or post-order manner.
552
541
  * @returns a boolean value.
553
542
  */
554
- has(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.options.iterationType) {
543
+ has(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
555
544
  if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
556
545
  callback = (node => node);
557
546
  return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
558
547
  }
559
- /**
560
- * Time Complexity: O(n)
561
- * Space Complexity: O(log n)
562
- */
563
548
  /**
564
549
  * Time Complexity: O(n)
565
550
  * Space Complexity: O(log n)
@@ -581,7 +566,7 @@ class BinaryTree {
581
566
  * nodes are visited during the search.
582
567
  * @returns a value of type `N | null | undefined`.
583
568
  */
584
- getNode(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.options.iterationType) {
569
+ getNode(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
585
570
  var _a;
586
571
  if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
587
572
  callback = (node => node);
@@ -635,7 +620,11 @@ class BinaryTree {
635
620
  }
636
621
  }
637
622
  /**
638
- * The function `ensureNotKey` returns the node corresponding to the given key if it is a valid node
623
+ * Time Complexity: O(n)
624
+ * Space Complexity: O(log n)
625
+ */
626
+ /**
627
+ * The function `ensureNode` returns the node corresponding to the given key if it is a valid node
639
628
  * key, otherwise it returns the key itself.
640
629
  * @param {BTNKey | N | null | undefined} key - The `key` parameter can be of type `BTNKey`, `N`,
641
630
  * `null`, or `undefined`. It represents a key used to identify a node in a binary tree.
@@ -645,13 +634,9 @@ class BinaryTree {
645
634
  * @returns either the node corresponding to the given key if it is a valid node key, or the key
646
635
  * itself if it is not a valid node key.
647
636
  */
648
- ensureNotKey(key, iterationType = types_1.IterationType.ITERATIVE) {
637
+ ensureNode(key, iterationType = types_1.IterationType.ITERATIVE) {
649
638
  return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key;
650
639
  }
651
- /**
652
- * Time Complexity: O(n)
653
- * Space Complexity: O(log n)
654
- */
655
640
  /**
656
641
  * Time Complexity: O(n)
657
642
  * Space Complexity: O(log n)
@@ -674,12 +659,16 @@ class BinaryTree {
674
659
  * @returns The value of the node with the given identifier is being returned. If the node is not
675
660
  * found, `undefined` is returned.
676
661
  */
677
- get(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.options.iterationType) {
662
+ get(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
678
663
  var _a, _b;
679
664
  if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
680
665
  callback = (node => node);
681
666
  return (_b = (_a = this.getNode(identifier, callback, beginRoot, iterationType)) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : undefined;
682
667
  }
668
+ /**
669
+ * Time Complexity: O(n)
670
+ * Space Complexity: O(log n)
671
+ */
683
672
  /**
684
673
  * Clear the binary tree, removing all nodes.
685
674
  */
@@ -694,10 +683,6 @@ class BinaryTree {
694
683
  isEmpty() {
695
684
  return this.size === 0;
696
685
  }
697
- /**
698
- * Time Complexity: O(log n)
699
- * Space Complexity: O(log n)
700
- */
701
686
  /**
702
687
  * Time Complexity: O(log n)
703
688
  * Space Complexity: O(log n)
@@ -715,7 +700,7 @@ class BinaryTree {
715
700
  getPathToRoot(beginRoot, isReverse = true) {
716
701
  // TODO to support get path through passing key
717
702
  const result = [];
718
- beginRoot = this.ensureNotKey(beginRoot);
703
+ beginRoot = this.ensureNode(beginRoot);
719
704
  if (!beginRoot)
720
705
  return result;
721
706
  while (beginRoot.parent) {
@@ -729,7 +714,7 @@ class BinaryTree {
729
714
  }
730
715
  /**
731
716
  * Time Complexity: O(log n)
732
- * Space Complexity: O(1)
717
+ * Space Complexity: O(log n)
733
718
  */
734
719
  /**
735
720
  * Time Complexity: O(log n)
@@ -745,8 +730,8 @@ class BinaryTree {
745
730
  * @returns The function `getLeftMost` returns the leftmost node (`N`) in the binary tree. If there
746
731
  * is no leftmost node, it returns `null` or `undefined` depending on the input.
747
732
  */
748
- getLeftMost(beginRoot = this.root, iterationType = this.options.iterationType) {
749
- beginRoot = this.ensureNotKey(beginRoot);
733
+ getLeftMost(beginRoot = this.root, iterationType = this.iterationType) {
734
+ beginRoot = this.ensureNode(beginRoot);
750
735
  if (!beginRoot)
751
736
  return beginRoot;
752
737
  if (iterationType === types_1.IterationType.RECURSIVE) {
@@ -786,9 +771,9 @@ class BinaryTree {
786
771
  * @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If there
787
772
  * is no rightmost node, it returns `null` or `undefined`, depending on the input.
788
773
  */
789
- getRightMost(beginRoot = this.root, iterationType = this.options.iterationType) {
774
+ getRightMost(beginRoot = this.root, iterationType = this.iterationType) {
790
775
  // TODO support get right most by passing key in
791
- beginRoot = this.ensureNotKey(beginRoot);
776
+ beginRoot = this.ensureNode(beginRoot);
792
777
  if (!beginRoot)
793
778
  return beginRoot;
794
779
  if (iterationType === types_1.IterationType.RECURSIVE) {
@@ -810,7 +795,7 @@ class BinaryTree {
810
795
  }
811
796
  }
812
797
  /**
813
- * Time Complexity: O(n)
798
+ * Time Complexity: O(log n)
814
799
  * Space Complexity: O(1)
815
800
  */
816
801
  /**
@@ -825,9 +810,9 @@ class BinaryTree {
825
810
  * possible values:
826
811
  * @returns a boolean value.
827
812
  */
828
- isSubtreeBST(beginRoot, iterationType = this.options.iterationType) {
813
+ isSubtreeBST(beginRoot, iterationType = this.iterationType) {
829
814
  // TODO there is a bug
830
- beginRoot = this.ensureNotKey(beginRoot);
815
+ beginRoot = this.ensureNode(beginRoot);
831
816
  if (!beginRoot)
832
817
  return true;
833
818
  if (iterationType === types_1.IterationType.RECURSIVE) {
@@ -872,15 +857,11 @@ class BinaryTree {
872
857
  * expected to be
873
858
  * @returns a boolean value.
874
859
  */
875
- isBST(iterationType = this.options.iterationType) {
860
+ isBST(iterationType = this.iterationType) {
876
861
  if (this.root === null)
877
862
  return true;
878
863
  return this.isSubtreeBST(this.root, iterationType);
879
864
  }
880
- /**
881
- * Time complexity: O(n)
882
- * Space complexity: O(log n)
883
- */
884
865
  /**
885
866
  * Time complexity: O(n)
886
867
  * Space complexity: O(log n)
@@ -903,8 +884,8 @@ class BinaryTree {
903
884
  * the `callback` function on each node in the subtree. The type of the array elements is determined
904
885
  * by the return type of the `callback` function.
905
886
  */
906
- subTreeTraverse(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.options.iterationType, includeNull = false) {
907
- beginRoot = this.ensureNotKey(beginRoot);
887
+ subTreeTraverse(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
888
+ beginRoot = this.ensureNode(beginRoot);
908
889
  const ans = [];
909
890
  if (!beginRoot)
910
891
  return ans;
@@ -943,6 +924,10 @@ class BinaryTree {
943
924
  }
944
925
  return ans;
945
926
  }
927
+ /**
928
+ * Time complexity: O(n)
929
+ * Space complexity: O(log n)
930
+ */
946
931
  /**
947
932
  * The function checks if a given node is a real node by verifying if it is an instance of
948
933
  * BinaryTreeNode and its key is not NaN.
@@ -977,10 +962,6 @@ class BinaryTree {
977
962
  isNodeKey(potentialKey) {
978
963
  return typeof potentialKey === 'number';
979
964
  }
980
- /**
981
- * Time complexity: O(n)
982
- * Space complexity: O(n)
983
- */
984
965
  /**
985
966
  * Time complexity: O(n)
986
967
  * Space complexity: O(n)
@@ -1005,7 +986,7 @@ class BinaryTree {
1005
986
  * @returns an array of values that are the return values of the callback function.
1006
987
  */
1007
988
  dfs(callback = this._defaultOneParamCallback, pattern = 'in', beginRoot = this.root, iterationType = types_1.IterationType.ITERATIVE, includeNull = false) {
1008
- beginRoot = this.ensureNotKey(beginRoot);
989
+ beginRoot = this.ensureNode(beginRoot);
1009
990
  if (!beginRoot)
1010
991
  return [];
1011
992
  const ans = [];
@@ -1110,10 +1091,6 @@ class BinaryTree {
1110
1091
  }
1111
1092
  return ans;
1112
1093
  }
1113
- /**
1114
- * Time complexity: O(n)
1115
- * Space complexity: O(n)
1116
- */
1117
1094
  /**
1118
1095
  * Time complexity: O(n)
1119
1096
  * Space complexity: O(n)
@@ -1135,8 +1112,8 @@ class BinaryTree {
1135
1112
  * @returns an array of values that are the result of invoking the callback function on each node in
1136
1113
  * the breadth-first traversal of a binary tree.
1137
1114
  */
1138
- bfs(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.options.iterationType, includeNull = false) {
1139
- beginRoot = this.ensureNotKey(beginRoot);
1115
+ bfs(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
1116
+ beginRoot = this.ensureNode(beginRoot);
1140
1117
  if (!beginRoot)
1141
1118
  return [];
1142
1119
  const ans = [];
@@ -1187,10 +1164,6 @@ class BinaryTree {
1187
1164
  }
1188
1165
  return ans;
1189
1166
  }
1190
- /**
1191
- * Time complexity: O(n)
1192
- * Space complexity: O(n)
1193
- */
1194
1167
  /**
1195
1168
  * Time complexity: O(n)
1196
1169
  * Space complexity: O(n)
@@ -1212,8 +1185,8 @@ class BinaryTree {
1212
1185
  * be excluded
1213
1186
  * @returns The function `listLevels` returns a two-dimensional array of type `ReturnType<C>[][]`.
1214
1187
  */
1215
- listLevels(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.options.iterationType, includeNull = false) {
1216
- beginRoot = this.ensureNotKey(beginRoot);
1188
+ listLevels(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
1189
+ beginRoot = this.ensureNode(beginRoot);
1217
1190
  const levelsNodes = [];
1218
1191
  if (!beginRoot)
1219
1192
  return levelsNodes;
@@ -1268,7 +1241,7 @@ class BinaryTree {
1268
1241
  * @returns The function `getPredecessor` returns a value of type `N | undefined`.
1269
1242
  */
1270
1243
  getPredecessor(node) {
1271
- node = this.ensureNotKey(node);
1244
+ node = this.ensureNode(node);
1272
1245
  if (!this.isRealNode(node))
1273
1246
  return undefined;
1274
1247
  if (node.left) {
@@ -1291,7 +1264,7 @@ class BinaryTree {
1291
1264
  * after the given node in the inorder traversal of the binary tree.
1292
1265
  */
1293
1266
  getSuccessor(x) {
1294
- x = this.ensureNotKey(x);
1267
+ x = this.ensureNode(x);
1295
1268
  if (!x)
1296
1269
  return undefined;
1297
1270
  if (x.right) {
@@ -1304,10 +1277,6 @@ class BinaryTree {
1304
1277
  }
1305
1278
  return y;
1306
1279
  }
1307
- /**
1308
- * Time complexity: O(n)
1309
- * Space complexity: O(1)
1310
- */
1311
1280
  /**
1312
1281
  * Time complexity: O(n)
1313
1282
  * Space complexity: O(1)
@@ -1327,7 +1296,7 @@ class BinaryTree {
1327
1296
  * by the return type of the `callback` function.
1328
1297
  */
1329
1298
  morris(callback = this._defaultOneParamCallback, pattern = 'in', beginRoot = this.root) {
1330
- beginRoot = this.ensureNotKey(beginRoot);
1299
+ beginRoot = this.ensureNode(beginRoot);
1331
1300
  if (beginRoot === null)
1332
1301
  return [];
1333
1302
  const ans = [];
@@ -1411,6 +1380,10 @@ class BinaryTree {
1411
1380
  }
1412
1381
  return ans;
1413
1382
  }
1383
+ /**
1384
+ * Time complexity: O(n)
1385
+ * Space complexity: O(1)
1386
+ */
1414
1387
  /**
1415
1388
  * The `forEach` function iterates over each entry in a tree and calls a callback function with the
1416
1389
  * entry and the tree as arguments.
@@ -1434,19 +1407,11 @@ class BinaryTree {
1434
1407
  const newTree = this.createTree();
1435
1408
  for (const [key, value] of this) {
1436
1409
  if (predicate([key, value], this)) {
1437
- newTree.add(key, value);
1410
+ newTree.add([key, value]);
1438
1411
  }
1439
1412
  }
1440
1413
  return newTree;
1441
1414
  }
1442
- // TODO Type error, need to return a TREE<NV> that is a value type only for callback function.
1443
- // map<NV>(callback: (entry: [BTNKey, V | undefined], tree: this) => NV) {
1444
- // const newTree = this.createTree();
1445
- // for (const [key, value] of this) {
1446
- // newTree.add(key, callback([key, value], this));
1447
- // }
1448
- // return newTree;
1449
- // }
1450
1415
  /**
1451
1416
  * The `map` function creates a new tree by applying a callback function to each entry in the current
1452
1417
  * tree.
@@ -1456,10 +1421,18 @@ class BinaryTree {
1456
1421
  map(callback) {
1457
1422
  const newTree = this.createTree();
1458
1423
  for (const [key, value] of this) {
1459
- newTree.add(key, callback([key, value], this));
1424
+ newTree.add([key, callback([key, value], this)]);
1460
1425
  }
1461
1426
  return newTree;
1462
1427
  }
1428
+ // TODO Type error, need to return a TREE<NV> that is a value type only for callback function.
1429
+ // map<NV>(callback: (entry: [BTNKey, V | undefined], tree: this) => NV) {
1430
+ // const newTree = this.createTree();
1431
+ // for (const [key, value] of this) {
1432
+ // newTree.add(key, callback([key, value], this));
1433
+ // }
1434
+ // return newTree;
1435
+ // }
1463
1436
  /**
1464
1437
  * The `reduce` function iterates over the entries of a tree and applies a callback function to each
1465
1438
  * entry, accumulating a single value.
@@ -1491,7 +1464,7 @@ class BinaryTree {
1491
1464
  *[Symbol.iterator](node = this.root) {
1492
1465
  if (!node)
1493
1466
  return;
1494
- if (this.options.iterationType === types_1.IterationType.ITERATIVE) {
1467
+ if (this.iterationType === types_1.IterationType.ITERATIVE) {
1495
1468
  const stack = [];
1496
1469
  let current = node;
1497
1470
  while (current || stack.length > 0) {
@@ -1525,7 +1498,7 @@ class BinaryTree {
1525
1498
  */
1526
1499
  print(beginRoot = this.root, options) {
1527
1500
  const opts = Object.assign({ isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false }, options);
1528
- beginRoot = this.ensureNotKey(beginRoot);
1501
+ beginRoot = this.ensureNode(beginRoot);
1529
1502
  if (!beginRoot)
1530
1503
  return;
1531
1504
  if (opts.isShowUndefined)
@@ -1594,9 +1567,9 @@ class BinaryTree {
1594
1567
  * @param {N} destNode - The destination node to swap.
1595
1568
  * @returns {N} - The destination node after the swap.
1596
1569
  */
1597
- _swap(srcNode, destNode) {
1598
- srcNode = this.ensureNotKey(srcNode);
1599
- destNode = this.ensureNotKey(destNode);
1570
+ _swapProperties(srcNode, destNode) {
1571
+ srcNode = this.ensureNode(srcNode);
1572
+ destNode = this.ensureNode(destNode);
1600
1573
  if (srcNode && destNode) {
1601
1574
  const { key, value } = destNode;
1602
1575
  const tempNode = this.createNode(key, value);
@@ -1610,6 +1583,31 @@ class BinaryTree {
1610
1583
  }
1611
1584
  return undefined;
1612
1585
  }
1586
+ /**
1587
+ * The function replaces an old node with a new node in a binary tree.
1588
+ * @param {N} oldNode - The oldNode parameter represents the node that needs to be replaced in the
1589
+ * tree.
1590
+ * @param {N} newNode - The `newNode` parameter is the node that will replace the `oldNode` in the
1591
+ * tree.
1592
+ * @returns The method is returning the newNode.
1593
+ */
1594
+ _replaceNode(oldNode, newNode) {
1595
+ if (oldNode.parent) {
1596
+ if (oldNode.parent.left === oldNode) {
1597
+ oldNode.parent.left = newNode;
1598
+ }
1599
+ else if (oldNode.parent.right === oldNode) {
1600
+ oldNode.parent.right = newNode;
1601
+ }
1602
+ }
1603
+ newNode.left = oldNode.left;
1604
+ newNode.right = oldNode.right;
1605
+ newNode.parent = oldNode.parent;
1606
+ if (this.root === oldNode) {
1607
+ this._root = newNode;
1608
+ }
1609
+ return newNode;
1610
+ }
1613
1611
  /**
1614
1612
  * The function `_addTo` adds a new node to a binary tree if there is an available position.
1615
1613
  * @param {N | null | undefined} newNode - The `newNode` parameter represents the node that you want to add to