data-structure-typed 1.50.0 → 1.50.2

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 (156) hide show
  1. package/CHANGELOG.md +2 -1
  2. package/README.md +204 -212
  3. package/benchmark/report.html +37 -1
  4. package/benchmark/report.json +370 -22
  5. package/dist/cjs/data-structures/base/iterable-base.d.ts +114 -9
  6. package/dist/cjs/data-structures/base/iterable-base.js +143 -7
  7. package/dist/cjs/data-structures/base/iterable-base.js.map +1 -1
  8. package/dist/cjs/data-structures/binary-tree/avl-tree.d.ts +43 -46
  9. package/dist/cjs/data-structures/binary-tree/avl-tree.js +68 -71
  10. package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
  11. package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +244 -199
  12. package/dist/cjs/data-structures/binary-tree/binary-tree.js +484 -376
  13. package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
  14. package/dist/cjs/data-structures/binary-tree/bst.d.ts +54 -74
  15. package/dist/cjs/data-structures/binary-tree/bst.js +30 -71
  16. package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
  17. package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +78 -60
  18. package/dist/cjs/data-structures/binary-tree/rb-tree.js +84 -89
  19. package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
  20. package/dist/cjs/data-structures/binary-tree/tree-multimap.d.ts +37 -56
  21. package/dist/cjs/data-structures/binary-tree/tree-multimap.js +64 -85
  22. package/dist/cjs/data-structures/binary-tree/tree-multimap.js.map +1 -1
  23. package/dist/cjs/data-structures/graph/abstract-graph.d.ts +1 -0
  24. package/dist/cjs/data-structures/graph/abstract-graph.js +3 -0
  25. package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
  26. package/dist/cjs/data-structures/graph/directed-graph.d.ts +14 -0
  27. package/dist/cjs/data-structures/graph/directed-graph.js +26 -0
  28. package/dist/cjs/data-structures/graph/directed-graph.js.map +1 -1
  29. package/dist/cjs/data-structures/graph/map-graph.d.ts +8 -0
  30. package/dist/cjs/data-structures/graph/map-graph.js +14 -0
  31. package/dist/cjs/data-structures/graph/map-graph.js.map +1 -1
  32. package/dist/cjs/data-structures/graph/undirected-graph.d.ts +16 -0
  33. package/dist/cjs/data-structures/graph/undirected-graph.js +25 -0
  34. package/dist/cjs/data-structures/graph/undirected-graph.js.map +1 -1
  35. package/dist/cjs/data-structures/hash/hash-map.d.ts +121 -15
  36. package/dist/cjs/data-structures/hash/hash-map.js +160 -25
  37. package/dist/cjs/data-structures/hash/hash-map.js.map +1 -1
  38. package/dist/cjs/data-structures/heap/heap.d.ts +66 -6
  39. package/dist/cjs/data-structures/heap/heap.js +66 -6
  40. package/dist/cjs/data-structures/heap/heap.js.map +1 -1
  41. package/dist/cjs/data-structures/linked-list/doubly-linked-list.d.ts +67 -50
  42. package/dist/cjs/data-structures/linked-list/doubly-linked-list.js +70 -64
  43. package/dist/cjs/data-structures/linked-list/doubly-linked-list.js.map +1 -1
  44. package/dist/cjs/data-structures/linked-list/singly-linked-list.d.ts +128 -103
  45. package/dist/cjs/data-structures/linked-list/singly-linked-list.js +130 -112
  46. package/dist/cjs/data-structures/linked-list/singly-linked-list.js.map +1 -1
  47. package/dist/cjs/data-structures/linked-list/skip-linked-list.d.ts +63 -36
  48. package/dist/cjs/data-structures/linked-list/skip-linked-list.js +63 -36
  49. package/dist/cjs/data-structures/linked-list/skip-linked-list.js.map +1 -1
  50. package/dist/cjs/data-structures/matrix/matrix.d.ts +35 -4
  51. package/dist/cjs/data-structures/matrix/matrix.js +50 -11
  52. package/dist/cjs/data-structures/matrix/matrix.js.map +1 -1
  53. package/dist/cjs/data-structures/queue/deque.d.ts +49 -19
  54. package/dist/cjs/data-structures/queue/deque.js +101 -47
  55. package/dist/cjs/data-structures/queue/deque.js.map +1 -1
  56. package/dist/cjs/data-structures/queue/queue.d.ts +39 -5
  57. package/dist/cjs/data-structures/queue/queue.js +47 -5
  58. package/dist/cjs/data-structures/queue/queue.js.map +1 -1
  59. package/dist/cjs/data-structures/stack/stack.d.ts +16 -0
  60. package/dist/cjs/data-structures/stack/stack.js +22 -0
  61. package/dist/cjs/data-structures/stack/stack.js.map +1 -1
  62. package/dist/cjs/data-structures/trie/trie.d.ts +38 -1
  63. package/dist/cjs/data-structures/trie/trie.js +41 -0
  64. package/dist/cjs/data-structures/trie/trie.js.map +1 -1
  65. package/dist/cjs/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
  66. package/dist/cjs/types/data-structures/hash/hash-map.d.ts +4 -3
  67. package/dist/cjs/types/utils/utils.d.ts +1 -0
  68. package/dist/mjs/data-structures/base/iterable-base.d.ts +114 -9
  69. package/dist/mjs/data-structures/base/iterable-base.js +143 -7
  70. package/dist/mjs/data-structures/binary-tree/avl-tree.d.ts +43 -46
  71. package/dist/mjs/data-structures/binary-tree/avl-tree.js +68 -71
  72. package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +244 -199
  73. package/dist/mjs/data-structures/binary-tree/binary-tree.js +483 -375
  74. package/dist/mjs/data-structures/binary-tree/bst.d.ts +54 -74
  75. package/dist/mjs/data-structures/binary-tree/bst.js +30 -71
  76. package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +78 -60
  77. package/dist/mjs/data-structures/binary-tree/rb-tree.js +84 -89
  78. package/dist/mjs/data-structures/binary-tree/tree-multimap.d.ts +37 -56
  79. package/dist/mjs/data-structures/binary-tree/tree-multimap.js +64 -85
  80. package/dist/mjs/data-structures/graph/abstract-graph.d.ts +1 -0
  81. package/dist/mjs/data-structures/graph/abstract-graph.js +3 -0
  82. package/dist/mjs/data-structures/graph/directed-graph.d.ts +14 -0
  83. package/dist/mjs/data-structures/graph/directed-graph.js +26 -0
  84. package/dist/mjs/data-structures/graph/map-graph.d.ts +8 -0
  85. package/dist/mjs/data-structures/graph/map-graph.js +14 -0
  86. package/dist/mjs/data-structures/graph/undirected-graph.d.ts +16 -0
  87. package/dist/mjs/data-structures/graph/undirected-graph.js +25 -0
  88. package/dist/mjs/data-structures/hash/hash-map.d.ts +121 -15
  89. package/dist/mjs/data-structures/hash/hash-map.js +160 -25
  90. package/dist/mjs/data-structures/heap/heap.d.ts +66 -6
  91. package/dist/mjs/data-structures/heap/heap.js +66 -6
  92. package/dist/mjs/data-structures/linked-list/doubly-linked-list.d.ts +67 -50
  93. package/dist/mjs/data-structures/linked-list/doubly-linked-list.js +70 -64
  94. package/dist/mjs/data-structures/linked-list/singly-linked-list.d.ts +128 -103
  95. package/dist/mjs/data-structures/linked-list/singly-linked-list.js +130 -112
  96. package/dist/mjs/data-structures/linked-list/skip-linked-list.d.ts +63 -36
  97. package/dist/mjs/data-structures/linked-list/skip-linked-list.js +63 -36
  98. package/dist/mjs/data-structures/matrix/matrix.d.ts +35 -4
  99. package/dist/mjs/data-structures/matrix/matrix.js +50 -11
  100. package/dist/mjs/data-structures/queue/deque.d.ts +49 -19
  101. package/dist/mjs/data-structures/queue/deque.js +101 -47
  102. package/dist/mjs/data-structures/queue/queue.d.ts +39 -5
  103. package/dist/mjs/data-structures/queue/queue.js +47 -5
  104. package/dist/mjs/data-structures/stack/stack.d.ts +16 -0
  105. package/dist/mjs/data-structures/stack/stack.js +22 -0
  106. package/dist/mjs/data-structures/trie/trie.d.ts +38 -1
  107. package/dist/mjs/data-structures/trie/trie.js +41 -0
  108. package/dist/mjs/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
  109. package/dist/mjs/types/data-structures/hash/hash-map.d.ts +4 -3
  110. package/dist/mjs/types/utils/utils.d.ts +1 -0
  111. package/dist/umd/data-structure-typed.js +1730 -1042
  112. package/dist/umd/data-structure-typed.min.js +3 -3
  113. package/dist/umd/data-structure-typed.min.js.map +1 -1
  114. package/package.json +16 -40
  115. package/src/data-structures/base/iterable-base.ts +172 -19
  116. package/src/data-structures/binary-tree/avl-tree.ts +97 -97
  117. package/src/data-structures/binary-tree/binary-tree.ts +674 -671
  118. package/src/data-structures/binary-tree/bst.ts +89 -131
  119. package/src/data-structures/binary-tree/rb-tree.ts +127 -155
  120. package/src/data-structures/binary-tree/tree-multimap.ts +96 -112
  121. package/src/data-structures/graph/abstract-graph.ts +4 -0
  122. package/src/data-structures/graph/directed-graph.ts +30 -0
  123. package/src/data-structures/graph/map-graph.ts +15 -0
  124. package/src/data-structures/graph/undirected-graph.ts +28 -0
  125. package/src/data-structures/hash/hash-map.ts +175 -34
  126. package/src/data-structures/heap/heap.ts +66 -6
  127. package/src/data-structures/linked-list/doubly-linked-list.ts +72 -66
  128. package/src/data-structures/linked-list/singly-linked-list.ts +132 -114
  129. package/src/data-structures/linked-list/skip-linked-list.ts +63 -37
  130. package/src/data-structures/matrix/matrix.ts +52 -12
  131. package/src/data-structures/queue/deque.ts +108 -49
  132. package/src/data-structures/queue/queue.ts +51 -5
  133. package/src/data-structures/stack/stack.ts +24 -0
  134. package/src/data-structures/trie/trie.ts +45 -1
  135. package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
  136. package/src/types/data-structures/hash/hash-map.ts +4 -3
  137. package/src/types/utils/utils.ts +2 -0
  138. package/test/performance/data-structures/graph/directed-graph.test.ts +3 -3
  139. package/test/performance/data-structures/queue/deque.test.ts +26 -25
  140. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +37 -0
  141. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +46 -17
  142. package/test/unit/data-structures/binary-tree/bst.test.ts +65 -1
  143. package/test/unit/data-structures/binary-tree/rb-tree.test.ts +38 -1
  144. package/test/unit/data-structures/binary-tree/tree-multimap.test.ts +37 -32
  145. package/test/unit/data-structures/graph/abstract-graph.test.ts +8 -0
  146. package/test/unit/data-structures/graph/directed-graph.test.ts +249 -0
  147. package/test/unit/data-structures/hash/hash-map.test.ts +376 -353
  148. package/test/unit/data-structures/heap/heap.test.ts +18 -1
  149. package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +24 -5
  150. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +20 -2
  151. package/test/unit/data-structures/linked-list/skip-list.test.ts +1 -1
  152. package/test/unit/data-structures/queue/deque.test.ts +71 -10
  153. package/test/unit/data-structures/queue/queue.test.ts +23 -6
  154. package/test/unit/data-structures/stack/stack.test.ts +17 -0
  155. package/test/unit/data-structures/trie/trie.test.ts +17 -0
  156. package/test/unit/unrestricted-interconversion.test.ts +143 -10
@@ -12,20 +12,38 @@ import { IterableEntryBase } from '../base';
12
12
  /**
13
13
  * Represents a node in a binary tree.
14
14
  * @template V - The type of data stored in the node.
15
- * @template N - The type of the family relationship in the binary tree.
15
+ * @template NODE - The type of the family relationship in the binary tree.
16
16
  */
17
17
  export class BinaryTreeNode {
18
18
  key;
19
19
  value;
20
20
  parent;
21
+ /**
22
+ * The constructor function initializes an object with a key and an optional value.
23
+ * @param {K} key - The "key" parameter is of type K, which represents the type of the key for the
24
+ * constructor. It is used to set the value of the "key" property of the object being created.
25
+ * @param {V} [value] - The "value" parameter is an optional parameter of type V. It represents the
26
+ * value associated with the key in the constructor.
27
+ */
21
28
  constructor(key, value) {
22
29
  this.key = key;
23
30
  this.value = value;
24
31
  }
25
32
  _left;
33
+ /**
34
+ * The function returns the value of the `_left` property, which can be of type `NODE`, `null`, or
35
+ * `undefined`.
36
+ * @returns The left node of the current node is being returned. It can be either a NODE object,
37
+ * null, or undefined.
38
+ */
26
39
  get left() {
27
40
  return this._left;
28
41
  }
42
+ /**
43
+ * The function sets the left child of a node and updates its parent reference.
44
+ * @param {NODE | null | undefined} v - The parameter `v` can be of type `NODE`, `null`, or
45
+ * `undefined`.
46
+ */
29
47
  set left(v) {
30
48
  if (v) {
31
49
  v.parent = this;
@@ -33,9 +51,19 @@ export class BinaryTreeNode {
33
51
  this._left = v;
34
52
  }
35
53
  _right;
54
+ /**
55
+ * The function returns the right node of a binary tree or null if it doesn't exist.
56
+ * @returns The method is returning the value of the `_right` property, which can be a `NODE` object,
57
+ * `null`, or `undefined`.
58
+ */
36
59
  get right() {
37
60
  return this._right;
38
61
  }
62
+ /**
63
+ * The function sets the right child of a node and updates its parent.
64
+ * @param {NODE | null | undefined} v - The parameter `v` can be of type `NODE`, `null`, or
65
+ * `undefined`.
66
+ */
39
67
  set right(v) {
40
68
  if (v) {
41
69
  v.parent = this;
@@ -92,14 +120,27 @@ export class BinaryTree extends IterableEntryBase {
92
120
  this.addMany(keysOrNodesOrEntries);
93
121
  }
94
122
  _extractor = (key) => Number(key);
123
+ /**
124
+ * The function returns the value of the `_extractor` property.
125
+ * @returns The `_extractor` property is being returned.
126
+ */
95
127
  get extractor() {
96
128
  return this._extractor;
97
129
  }
98
130
  _root;
131
+ /**
132
+ * The function returns the root node, which can be of type NODE, null, or undefined.
133
+ * @returns The method is returning the value of the `_root` property, which can be of type `NODE`,
134
+ * `null`, or `undefined`.
135
+ */
99
136
  get root() {
100
137
  return this._root;
101
138
  }
102
139
  _size;
140
+ /**
141
+ * The function returns the size of an object.
142
+ * @returns The size of the object, which is a number.
143
+ */
103
144
  get size() {
104
145
  return this._size;
105
146
  }
@@ -107,7 +148,7 @@ export class BinaryTree extends IterableEntryBase {
107
148
  * Creates a new instance of BinaryTreeNode with the given key and value.
108
149
  * @param {K} key - The key for the new node.
109
150
  * @param {V} value - The value for the new node.
110
- * @returns {N} - The newly created BinaryTreeNode.
151
+ * @returns {NODE} - The newly created BinaryTreeNode.
111
152
  */
112
153
  createNode(key, value) {
113
154
  return new BinaryTreeNode(key, value);
@@ -123,14 +164,14 @@ export class BinaryTree extends IterableEntryBase {
123
164
  return new BinaryTree([], { iterationType: this.iterationType, ...options });
124
165
  }
125
166
  /**
126
- * The function `exemplarToNode` converts an keyOrNodeOrEntry object into a node object.
127
- * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter is of type `KeyOrNodeOrEntry<K, V, N>`.
167
+ * The function `keyValueOrEntryToNode` converts an keyOrNodeOrEntry object into a node object.
168
+ * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter is of type `KeyOrNodeOrEntry<K, V, NODE>`.
128
169
  * @param {V} [value] - The `value` parameter is an optional value that can be passed to the
129
- * `exemplarToNode` function. It represents the value associated with the keyOrNodeOrEntry node. If no value
170
+ * `keyValueOrEntryToNode` function. It represents the value associated with the keyOrNodeOrEntry node. If no value
130
171
  * is provided, it will be `undefined`.
131
- * @returns a value of type N (node), or null, or undefined.
172
+ * @returns a value of type NODE (node), or null, or undefined.
132
173
  */
133
- exemplarToNode(keyOrNodeOrEntry, value) {
174
+ keyValueOrEntryToNode(keyOrNodeOrEntry, value) {
134
175
  if (keyOrNodeOrEntry === undefined)
135
176
  return;
136
177
  let node;
@@ -170,7 +211,7 @@ export class BinaryTree extends IterableEntryBase {
170
211
  *
171
212
  * The function `ensureNode` returns the node corresponding to the given key if it is a valid node
172
213
  * key, otherwise it returns the key itself.
173
- * @param {K | N | null | undefined} keyOrNodeOrEntry - The `key` parameter can be of type `K`, `N`,
214
+ * @param {K | NODE | null | undefined} keyOrNodeOrEntry - The `key` parameter can be of type `K`, `NODE`,
174
215
  * `null`, or `undefined`. It represents a key used to identify a node in a binary tree.
175
216
  * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
176
217
  * type of iteration to be used when searching for a node by key. It has a default value of
@@ -199,25 +240,21 @@ export class BinaryTree extends IterableEntryBase {
199
240
  }
200
241
  /**
201
242
  * The function "isNode" checks if an keyOrNodeOrEntry is an instance of the BinaryTreeNode class.
202
- * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter is a variable of type `KeyOrNodeOrEntry<K, V,N>`.
203
- * @returns a boolean value indicating whether the keyOrNodeOrEntry is an instance of the class N.
243
+ * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter is a variable of type `KeyOrNodeOrEntry<K, V,NODE>`.
244
+ * @returns a boolean value indicating whether the keyOrNodeOrEntry is an instance of the class NODE.
204
245
  */
205
246
  isNode(keyOrNodeOrEntry) {
206
247
  return keyOrNodeOrEntry instanceof BinaryTreeNode;
207
248
  }
208
249
  /**
209
250
  * The function checks if a given value is an entry in a binary tree node.
210
- * @param keyOrNodeOrEntry - KeyOrNodeOrEntry<K, V,N> - A generic type representing a node in a binary tree. It has
211
- * two type parameters V and N, representing the value and node type respectively.
251
+ * @param keyOrNodeOrEntry - KeyOrNodeOrEntry<K, V,NODE> - A generic type representing a node in a binary tree. It has
252
+ * two type parameters V and NODE, representing the value and node type respectively.
212
253
  * @returns a boolean value.
213
254
  */
214
255
  isEntry(keyOrNodeOrEntry) {
215
256
  return Array.isArray(keyOrNodeOrEntry) && keyOrNodeOrEntry.length === 2;
216
257
  }
217
- /**
218
- * Time complexity: O(n)
219
- * Space complexity: O(log n)
220
- */
221
258
  /**
222
259
  * The function checks if a given node is a real node by verifying if it is an instance of
223
260
  * BinaryTreeNode and its key is not NaN.
@@ -244,21 +281,21 @@ export class BinaryTree extends IterableEntryBase {
244
281
  return this.isRealNode(node) || node === null;
245
282
  }
246
283
  /**
247
- * Time Complexity O(log n) - O(n)
284
+ * Time Complexity O(n)
248
285
  * Space Complexity O(1)
249
286
  */
250
287
  /**
251
- * Time Complexity O(log n) - O(n)
288
+ * Time Complexity O(n)
252
289
  * Space Complexity O(1)
253
290
  *
254
291
  * The `add` function adds a new node to a binary tree, either by creating a new node or replacing an
255
292
  * existing node with the same key.
256
293
  * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be one of the following:
257
294
  * @param {V} [value] - The value to be inserted into the binary tree.
258
- * @returns The function `add` returns either a node (`N`), `null`, or `undefined`.
295
+ * @returns The function `add` returns either a node (`NODE`), `null`, or `undefined`.
259
296
  */
260
297
  add(keyOrNodeOrEntry, value) {
261
- const newNode = this.exemplarToNode(keyOrNodeOrEntry, value);
298
+ const newNode = this.keyValueOrEntryToNode(keyOrNodeOrEntry, value);
262
299
  if (newNode === undefined)
263
300
  return false;
264
301
  // If the tree is empty, directly set the new node as the root node
@@ -304,19 +341,19 @@ export class BinaryTree extends IterableEntryBase {
304
341
  return false; // If the insertion position cannot be found, return undefined
305
342
  }
306
343
  /**
307
- * Time Complexity: O(k log n) - O(k * n)
344
+ * Time Complexity: O(k * n)
308
345
  * Space Complexity: O(1)
309
346
  * 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.
310
347
  */
311
348
  /**
312
- * Time Complexity: O(k log n) - O(k * n)
349
+ * Time Complexity: O(k * n)
313
350
  * Space Complexity: O(1)
314
351
  *
315
352
  * The `addMany` function takes in a collection of keysOrNodesOrEntries and an optional collection of values, and
316
353
  * adds each node with its corresponding value to the data structure.
317
354
  * @param keysOrNodesOrEntries - An iterable collection of KeyOrNodeOrEntry objects.
318
355
  * @param [values] - An optional iterable of values that will be assigned to each node being added.
319
- * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
356
+ * @returns The function `addMany` returns an array of `NODE`, `null`, or `undefined` values.
320
357
  */
321
358
  addMany(keysOrNodesOrEntries, values) {
322
359
  // TODO not sure addMany not be run multi times
@@ -348,7 +385,7 @@ export class BinaryTree extends IterableEntryBase {
348
385
  *
349
386
  * The `refill` function clears the current data and adds new key-value pairs to the data structure.
350
387
  * @param keysOrNodesOrEntries - An iterable containing keys, nodes, or entries. These can be of type
351
- * KeyOrNodeOrEntry<K, V, N>.
388
+ * KeyOrNodeOrEntry<K, V, NODE>.
352
389
  * @param [values] - The `values` parameter is an optional iterable that contains the values to be
353
390
  * associated with the keys or nodes or entries in the `keysOrNodesOrEntries` parameter. If provided,
354
391
  * the values will be associated with the corresponding keys or nodes or entries in the
@@ -359,6 +396,11 @@ export class BinaryTree extends IterableEntryBase {
359
396
  this.addMany(keysOrNodesOrEntries, values);
360
397
  }
361
398
  /**
399
+ * Time Complexity: O(n)
400
+ * Space Complexity: O(1)
401
+ * /
402
+
403
+ /**
362
404
  * Time Complexity: O(n)
363
405
  * Space Complexity: O(1)
364
406
  *
@@ -371,7 +413,7 @@ export class BinaryTree extends IterableEntryBase {
371
413
  * @param {C} callback - The `callback` parameter is a function that is used to determine the
372
414
  * identifier of the node to be deleted. It is optional and has a default value of
373
415
  * `this._defaultOneParamCallback`. The `callback` function should return the identifier of the node.
374
- * @returns an array of `BinaryTreeDeleteResult<N>`.
416
+ * @returns an array of `BinaryTreeDeleteResult<NODE>`.
375
417
  */
376
418
  delete(identifier, callback = this._defaultOneParamCallback) {
377
419
  const deletedResult = [];
@@ -382,205 +424,51 @@ export class BinaryTree extends IterableEntryBase {
382
424
  const curr = this.getNode(identifier, callback);
383
425
  if (!curr)
384
426
  return deletedResult;
385
- const parent = curr?.parent ? curr.parent : null;
386
- let needBalanced = undefined;
427
+ const parent = curr?.parent;
428
+ let needBalanced;
387
429
  let orgCurrent = curr;
388
- if (!curr.left) {
389
- if (!parent) {
390
- // Handle the case when there's only one root node
391
- this._setRoot(null);
392
- }
393
- else {
394
- const { familyPosition: fp } = curr;
395
- if (fp === FamilyPosition.LEFT || fp === FamilyPosition.ROOT_LEFT) {
396
- parent.left = curr.right;
397
- }
398
- else if (fp === FamilyPosition.RIGHT || fp === FamilyPosition.ROOT_RIGHT) {
399
- parent.right = curr.right;
400
- }
401
- needBalanced = parent;
402
- }
430
+ if (!curr.left && !curr.right && !parent) {
431
+ this._setRoot(undefined);
403
432
  }
404
- else {
405
- if (curr.left) {
406
- const leftSubTreeRightMost = this.getRightMost(curr.left);
407
- if (leftSubTreeRightMost) {
408
- const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
409
- orgCurrent = this._swapProperties(curr, leftSubTreeRightMost);
410
- if (parentOfLeftSubTreeMax) {
411
- if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
412
- parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
413
- else
414
- parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left;
415
- needBalanced = parentOfLeftSubTreeMax;
416
- }
433
+ else if (curr.left) {
434
+ const leftSubTreeRightMost = this.getRightMost(curr.left);
435
+ if (leftSubTreeRightMost) {
436
+ const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
437
+ orgCurrent = this._swapProperties(curr, leftSubTreeRightMost);
438
+ if (parentOfLeftSubTreeMax) {
439
+ if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
440
+ parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
441
+ else
442
+ parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left;
443
+ needBalanced = parentOfLeftSubTreeMax;
417
444
  }
418
445
  }
419
446
  }
420
- this._size = this.size - 1;
421
- deletedResult.push({ deleted: orgCurrent, needBalanced });
422
- return deletedResult;
423
- }
424
- /**
425
- * Time Complexity: O(n)
426
- * Space Complexity: O(1)
427
- */
428
- /**
429
- * Time Complexity: O(n)
430
- * Space Complexity: O(1)
431
- *
432
- * The function calculates the depth of a given node in a binary tree.
433
- * @param {K | N | null | undefined} dist - The `dist` parameter represents the node in
434
- * the binary tree whose depth we want to find. It can be of type `K`, `N`, `null`, or
435
- * `undefined`.
436
- * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
437
- * from which we want to calculate the depth. It can be either a `K` (binary tree node key) or
438
- * `N` (binary tree node) or `null` or `undefined`. If no value is provided for `beginRoot
439
- * @returns the depth of the `dist` relative to the `beginRoot`.
440
- */
441
- getDepth(dist, beginRoot = this.root) {
442
- dist = this.ensureNode(dist);
443
- beginRoot = this.ensureNode(beginRoot);
444
- let depth = 0;
445
- while (dist?.parent) {
446
- if (dist === beginRoot) {
447
- return depth;
447
+ else if (parent) {
448
+ const { familyPosition: fp } = curr;
449
+ if (fp === FamilyPosition.LEFT || fp === FamilyPosition.ROOT_LEFT) {
450
+ parent.left = curr.right;
448
451
  }
449
- depth++;
450
- dist = dist.parent;
451
- }
452
- return depth;
453
- }
454
- /**
455
- * Time Complexity: O(n)
456
- * Space Complexity: O(1)
457
- */
458
- /**
459
- * Time Complexity: O(n)
460
- * Space Complexity: O(log n)
461
- *
462
- * The function `getHeight` calculates the maximum height of a binary tree using either recursive or
463
- * iterative traversal.
464
- * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
465
- * starting node of the binary tree from which we want to calculate the height. It can be of type
466
- * `K`, `N`, `null`, or `undefined`. If not provided, it defaults to `this.root`.
467
- * @param iterationType - The `iterationType` parameter is used to determine whether to calculate the
468
- * height of the tree using a recursive approach or an iterative approach. It can have two possible
469
- * values:
470
- * @returns the height of the binary tree.
471
- */
472
- getHeight(beginRoot = this.root, iterationType = this.iterationType) {
473
- beginRoot = this.ensureNode(beginRoot);
474
- if (!beginRoot)
475
- return -1;
476
- if (iterationType === IterationType.RECURSIVE) {
477
- const _getMaxHeight = (cur) => {
478
- if (!cur)
479
- return -1;
480
- const leftHeight = _getMaxHeight(cur.left);
481
- const rightHeight = _getMaxHeight(cur.right);
482
- return Math.max(leftHeight, rightHeight) + 1;
483
- };
484
- return _getMaxHeight(beginRoot);
485
- }
486
- else {
487
- const stack = [{ node: beginRoot, depth: 0 }];
488
- let maxHeight = 0;
489
- while (stack.length > 0) {
490
- const { node, depth } = stack.pop();
491
- if (node.left)
492
- stack.push({ node: node.left, depth: depth + 1 });
493
- if (node.right)
494
- stack.push({ node: node.right, depth: depth + 1 });
495
- maxHeight = Math.max(maxHeight, depth);
452
+ else if (fp === FamilyPosition.RIGHT || fp === FamilyPosition.ROOT_RIGHT) {
453
+ parent.right = curr.right;
496
454
  }
497
- return maxHeight;
498
- }
499
- }
500
- /**
501
- * Time Complexity: O(n)
502
- * Space Complexity: O(log n)
503
- * Best Case - O(log n) (when using recursive iterationType), Worst Case - O(n) (when using iterative iterationType)
504
- */
505
- /**
506
- * Time Complexity: O(n)
507
- * Space Complexity: O(log n)
508
- *
509
- * The `getMinHeight` function calculates the minimum height of a binary tree using either a
510
- * recursive or iterative approach.
511
- * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
512
- * starting node of the binary tree from which we want to calculate the minimum height. It can be of
513
- * type `K`, `N`, `null`, or `undefined`. If no value is provided, it defaults to `this.root`.
514
- * @param iterationType - The `iterationType` parameter is used to determine the method of iteration
515
- * to calculate the minimum height of a binary tree. It can have two possible values:
516
- * @returns The function `getMinHeight` returns the minimum height of a binary tree.
517
- */
518
- getMinHeight(beginRoot = this.root, iterationType = this.iterationType) {
519
- beginRoot = this.ensureNode(beginRoot);
520
- if (!beginRoot)
521
- return -1;
522
- if (iterationType === IterationType.RECURSIVE) {
523
- const _getMinHeight = (cur) => {
524
- if (!cur)
525
- return 0;
526
- if (!cur.left && !cur.right)
527
- return 0;
528
- const leftMinHeight = _getMinHeight(cur.left);
529
- const rightMinHeight = _getMinHeight(cur.right);
530
- return Math.min(leftMinHeight, rightMinHeight) + 1;
531
- };
532
- return _getMinHeight(beginRoot);
455
+ needBalanced = parent;
533
456
  }
534
457
  else {
535
- const stack = [];
536
- let node = beginRoot, last = null;
537
- const depths = new Map();
538
- while (stack.length > 0 || node) {
539
- if (node) {
540
- stack.push(node);
541
- node = node.left;
542
- }
543
- else {
544
- node = stack[stack.length - 1];
545
- if (!node.right || last === node.right) {
546
- node = stack.pop();
547
- if (node) {
548
- const leftMinHeight = node.left ? depths.get(node.left) ?? -1 : -1;
549
- const rightMinHeight = node.right ? depths.get(node.right) ?? -1 : -1;
550
- depths.set(node, 1 + Math.min(leftMinHeight, rightMinHeight));
551
- last = node;
552
- node = null;
553
- }
554
- }
555
- else
556
- node = node.right;
557
- }
558
- }
559
- return depths.get(beginRoot) ?? -1;
458
+ this._setRoot(curr.right);
459
+ curr.right = undefined;
560
460
  }
461
+ this._size = this.size - 1;
462
+ deletedResult.push({ deleted: orgCurrent, needBalanced });
463
+ return deletedResult;
561
464
  }
562
465
  /**
563
466
  * Time Complexity: O(n)
564
- * Space Complexity: O(log n)
565
- * Best Case - O(log n) (when using recursive iterationType), Worst Case - O(n) (when using iterative iterationType)
467
+ * Space Complexity: O(k + log n)
566
468
  */
567
469
  /**
568
470
  * Time Complexity: O(n)
569
- * Space Complexity: O(log n)
570
- *
571
- * The function checks if a binary tree is perfectly balanced by comparing the minimum height and the
572
- * height of the tree.
573
- * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
574
- * for calculating the height and minimum height of a binary tree. It can be either a `K` (a key
575
- * value of a binary tree node), `N` (a node of a binary tree), `null`, or `undefined`. If
576
- * @returns a boolean value.
577
- */
578
- isPerfectlyBalanced(beginRoot = this.root) {
579
- return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
580
- }
581
- /**
582
- * Time Complexity: O(n)
583
- * Space Complexity: O(log n).
471
+ * Space Complexity: O(k + log n).
584
472
  *
585
473
  * The function `getNodes` retrieves nodes from a binary tree based on a given identifier and
586
474
  * callback function.
@@ -588,7 +476,7 @@ export class BinaryTree extends IterableEntryBase {
588
476
  * that you want to search for in the binary tree. It can be of any type that is returned by the
589
477
  * callback function `C`. It can also be `null` or `undefined` if you don't want to search for a
590
478
  * specific value.
591
- * @param {C} callback - The `callback` parameter is a function that takes a node of type `N` as
479
+ * @param {C} callback - The `callback` parameter is a function that takes a node of type `NODE` as
592
480
  * input and returns a value of type `C`. It is used to determine if a node matches the given
593
481
  * identifier. If no callback is provided, the `_defaultOneParamCallback` function is used as the
594
482
  * default
@@ -596,12 +484,12 @@ export class BinaryTree extends IterableEntryBase {
596
484
  * matches the identifier. If set to true, the function will stop iterating once it finds a matching
597
485
  * node and return that node. If set to false (default), the function will continue iterating and
598
486
  * return all nodes that match the identifier.
599
- * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
487
+ * @param {K | NODE | null | undefined} beginRoot - The `beginRoot` parameter represents the
600
488
  * starting node for the traversal. It can be either a key, a node object, or `null`/`undefined`. If
601
489
  * it is `null` or `undefined`, an empty array will be returned.
602
490
  * @param iterationType - The `iterationType` parameter determines the type of iteration used to
603
491
  * traverse the binary tree. It can have two possible values:
604
- * @returns an array of nodes of type `N`.
492
+ * @returns an array of nodes of type `NODE`.
605
493
  */
606
494
  getNodes(identifier, callback = this._defaultOneParamCallback, onlyOne = false, beginRoot = this.root, iterationType = this.iterationType) {
607
495
  if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
@@ -644,29 +532,7 @@ export class BinaryTree extends IterableEntryBase {
644
532
  /**
645
533
  * Time Complexity: O(n)
646
534
  * Space Complexity: O(log n).
647
- *
648
- * The function checks if a Binary Tree Node with a specific identifier exists in the tree.
649
- * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
650
- * that you want to search for in the binary tree. It can be of any type that is returned by the
651
- * callback function `C`. It can also be `null` or `undefined` if you don't want to specify a
652
- * specific identifier.
653
- * @param {C} callback - The `callback` parameter is a function that will be called for each node in
654
- * the binary tree. It is used to filter the nodes based on certain conditions. The `callback`
655
- * function should return a boolean value indicating whether the node should be included in the
656
- * result or not.
657
- * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
658
- * for the search in the binary tree. It can be specified as a `K` (a unique identifier for a
659
- * node in the binary tree), a node object (`N`), or `null`/`undefined` to start the search from
660
- * @param iterationType - The `iterationType` parameter is a variable that determines the type of
661
- * iteration to be performed on the binary tree. It is used to specify whether the iteration should
662
- * be performed in a pre-order, in-order, or post-order manner.
663
- * @returns a boolean value.
664
535
  */
665
- has(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
666
- if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
667
- callback = (node => node);
668
- return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
669
- }
670
536
  /**
671
537
  * Time Complexity: O(n)
672
538
  * Space Complexity: O(log n)
@@ -679,14 +545,14 @@ export class BinaryTree extends IterableEntryBase {
679
545
  * identifier.
680
546
  * @param {C} callback - The `callback` parameter is a function that will be called for each node in
681
547
  * the binary tree. It is used to determine if a node matches the given identifier. The `callback`
682
- * function should take a single parameter of type `N` (the type of the nodes in the binary tree) and
683
- * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
548
+ * function should take a single parameter of type `NODE` (the type of the nodes in the binary tree) and
549
+ * @param {K | NODE | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
684
550
  * for searching the binary tree. It can be either a key value, a node object, or `null`/`undefined`.
685
551
  * If `null` or `undefined` is passed, the search will start from the root of the binary tree.
686
552
  * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
687
553
  * be performed when searching for nodes in the binary tree. It determines the order in which the
688
554
  * nodes are visited during the search.
689
- * @returns a value of type `N | null | undefined`.
555
+ * @returns a value of type `NODE | null | undefined`.
690
556
  */
691
557
  getNode(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
692
558
  if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
@@ -708,7 +574,7 @@ export class BinaryTree extends IterableEntryBase {
708
574
  * @param iterationType - The `iterationType` parameter is used to determine whether the search for
709
575
  * the node with the given key should be performed iteratively or recursively. It has two possible
710
576
  * values:
711
- * @returns The function `getNodeByKey` returns a node (`N`) if a node with the specified key is
577
+ * @returns The function `getNodeByKey` returns a node (`NODE`) if a node with the specified key is
712
578
  * found in the binary tree. If no node is found, it returns `undefined`.
713
579
  */
714
580
  getNodeByKey(key, iterationType = IterationType.ITERATIVE) {
@@ -740,6 +606,10 @@ export class BinaryTree extends IterableEntryBase {
740
606
  }
741
607
  }
742
608
  }
609
+ /**
610
+ * Time Complexity: O(n)
611
+ * Space Complexity: O(log n)
612
+ */
743
613
  /**
744
614
  * Time Complexity: O(n)
745
615
  * Space Complexity: O(log n)
@@ -753,9 +623,9 @@ export class BinaryTree extends IterableEntryBase {
753
623
  * the binary tree. It is used to determine whether a node matches the given identifier. The callback
754
624
  * function should return a value that can be compared to the identifier to determine if it is a
755
625
  * match.
756
- * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
626
+ * @param {K | NODE | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
757
627
  * for the search in the binary tree. It can be specified as a `K` (a unique identifier for a
758
- * node), a node object of type `N`, or `null`/`undefined` to start the search from the root of
628
+ * node), a node object of type `NODE`, or `null`/`undefined` to start the search from the root of
759
629
  * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
760
630
  * be performed when searching for a node in the binary tree. It is an optional parameter with a
761
631
  * default value specified by `this.iterationType`.
@@ -768,46 +638,294 @@ export class BinaryTree extends IterableEntryBase {
768
638
  return this.getNode(identifier, callback, beginRoot, iterationType)?.value ?? undefined;
769
639
  }
770
640
  /**
771
- * Time Complexity: O(1)
641
+ * Time Complexity: O(n)
642
+ * Space Complexity: O(log n).
643
+ */
644
+ /**
645
+ * Time Complexity: O(n)
646
+ * Space Complexity: O(log n).
647
+ *
648
+ * The function checks if a Binary Tree Node with a specific identifier exists in the tree.
649
+ * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
650
+ * that you want to search for in the binary tree. It can be of any type that is returned by the
651
+ * callback function `C`. It can also be `null` or `undefined` if you don't want to specify a
652
+ * specific identifier.
653
+ * @param {C} callback - The `callback` parameter is a function that will be called for each node in
654
+ * the binary tree. It is used to filter the nodes based on certain conditions. The `callback`
655
+ * function should return a boolean value indicating whether the node should be included in the
656
+ * result or not.
657
+ * @param {K | NODE | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
658
+ * for the search in the binary tree. It can be specified as a `K` (a unique identifier for a
659
+ * node in the binary tree), a node object (`NODE`), or `null`/`undefined` to start the search from
660
+ * @param iterationType - The `iterationType` parameter is a variable that determines the type of
661
+ * iteration to be performed on the binary tree. It is used to specify whether the iteration should
662
+ * be performed in a pre-order, in-order, or post-order manner.
663
+ * @returns a boolean value.
664
+ */
665
+ has(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
666
+ if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
667
+ callback = (node => node);
668
+ return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
669
+ }
670
+ /**
671
+ * Time Complexity: O(1)
672
+ * Space Complexity: O(1)
673
+ */
674
+ /**
675
+ * Time Complexity: O(1)
676
+ * Space Complexity: O(1)
677
+ *
678
+ * Clear the binary tree, removing all nodes.
679
+ */
680
+ clear() {
681
+ this._setRoot(undefined);
682
+ this._size = 0;
683
+ }
684
+ /**
685
+ * Time Complexity: O(1)
686
+ * Space Complexity: O(1)
687
+ */
688
+ /**
689
+ * Time Complexity: O(1)
690
+ * Space Complexity: O(1)
691
+ *
692
+ * Check if the binary tree is empty.
693
+ * @returns {boolean} - True if the binary tree is empty, false otherwise.
694
+ */
695
+ isEmpty() {
696
+ return this.size === 0;
697
+ }
698
+ /**
699
+ * Time Complexity: O(n)
700
+ * Space Complexity: O(log n)
701
+ */
702
+ /**
703
+ * Time Complexity: O(n)
704
+ * Space Complexity: O(log n)
705
+ *
706
+ * The function checks if a binary tree is perfectly balanced by comparing the minimum height and the
707
+ * height of the tree.
708
+ * @param {K | NODE | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
709
+ * for calculating the height and minimum height of a binary tree. It can be either a `K` (a key
710
+ * value of a binary tree node), `NODE` (a node of a binary tree), `null`, or `undefined`. If
711
+ * @returns a boolean value.
712
+ */
713
+ isPerfectlyBalanced(beginRoot = this.root) {
714
+ return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
715
+ }
716
+ /**
717
+ * Time Complexity: O(n)
718
+ * Space Complexity: O(1)
719
+ */
720
+ /**
721
+ * Time Complexity: O(n)
722
+ * Space Complexity: O(1)
723
+ *
724
+ * The function `isSubtreeBST` checks if a given binary tree is a valid binary search tree.
725
+ * @param {K | NODE | null | undefined} beginRoot - The `beginRoot` parameter represents the root
726
+ * node of the binary search tree (BST) that you want to check if it is a subtree of another BST.
727
+ * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
728
+ * type of iteration to use when checking if a subtree is a binary search tree (BST). It can have two
729
+ * possible values:
730
+ * @returns a boolean value.
731
+ */
732
+ isBST(beginRoot = this.root, iterationType = this.iterationType) {
733
+ // TODO there is a bug
734
+ beginRoot = this.ensureNode(beginRoot);
735
+ if (!beginRoot)
736
+ return true;
737
+ if (iterationType === IterationType.RECURSIVE) {
738
+ const dfs = (cur, min, max) => {
739
+ if (!cur)
740
+ return true;
741
+ const numKey = this.extractor(cur.key);
742
+ if (numKey <= min || numKey >= max)
743
+ return false;
744
+ return dfs(cur.left, min, numKey) && dfs(cur.right, numKey, max);
745
+ };
746
+ const isStandardBST = dfs(beginRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
747
+ const isInverseBST = dfs(beginRoot, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER);
748
+ return isStandardBST || isInverseBST;
749
+ }
750
+ else {
751
+ const checkBST = (checkMax = false) => {
752
+ const stack = [];
753
+ let prev = checkMax ? Number.MAX_SAFE_INTEGER : Number.MIN_SAFE_INTEGER;
754
+ // @ts-ignore
755
+ let curr = beginRoot;
756
+ while (curr || stack.length > 0) {
757
+ while (curr) {
758
+ stack.push(curr);
759
+ curr = curr.left;
760
+ }
761
+ curr = stack.pop();
762
+ const numKey = this.extractor(curr.key);
763
+ if (!curr || (!checkMax && prev >= numKey) || (checkMax && prev <= numKey))
764
+ return false;
765
+ prev = numKey;
766
+ curr = curr.right;
767
+ }
768
+ return true;
769
+ };
770
+ const isStandardBST = checkBST(false), isInverseBST = checkBST(true);
771
+ return isStandardBST || isInverseBST;
772
+ }
773
+ }
774
+ /**
775
+ * Time Complexity: O(n)
776
+ * Space Complexity: O(1)
777
+ */
778
+ /**
779
+ * Time Complexity: O(n)
780
+ * Space Complexity: O(1)
781
+ *
782
+ * The function calculates the depth of a given node in a binary tree.
783
+ * @param {K | NODE | null | undefined} dist - The `dist` parameter represents the node in
784
+ * the binary tree whose depth we want to find. It can be of type `K`, `NODE`, `null`, or
785
+ * `undefined`.
786
+ * @param {K | NODE | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
787
+ * from which we want to calculate the depth. It can be either a `K` (binary tree node key) or
788
+ * `NODE` (binary tree node) or `null` or `undefined`. If no value is provided for `beginRoot
789
+ * @returns the depth of the `dist` relative to the `beginRoot`.
790
+ */
791
+ getDepth(dist, beginRoot = this.root) {
792
+ dist = this.ensureNode(dist);
793
+ beginRoot = this.ensureNode(beginRoot);
794
+ let depth = 0;
795
+ while (dist?.parent) {
796
+ if (dist === beginRoot) {
797
+ return depth;
798
+ }
799
+ depth++;
800
+ dist = dist.parent;
801
+ }
802
+ return depth;
803
+ }
804
+ /**
805
+ * Time Complexity: O(n)
772
806
  * Space Complexity: O(1)
773
807
  */
774
808
  /**
775
- * Time Complexity: O(1)
776
- * Space Complexity: O(1)
809
+ * Time Complexity: O(n)
810
+ * Space Complexity: O(log n)
777
811
  *
778
- * Clear the binary tree, removing all nodes.
812
+ * The function `getHeight` calculates the maximum height of a binary tree using either recursive or
813
+ * iterative traversal.
814
+ * @param {K | NODE | null | undefined} beginRoot - The `beginRoot` parameter represents the
815
+ * starting node of the binary tree from which we want to calculate the height. It can be of type
816
+ * `K`, `NODE`, `null`, or `undefined`. If not provided, it defaults to `this.root`.
817
+ * @param iterationType - The `iterationType` parameter is used to determine whether to calculate the
818
+ * height of the tree using a recursive approach or an iterative approach. It can have two possible
819
+ * values:
820
+ * @returns the height of the binary tree.
779
821
  */
780
- clear() {
781
- this._setRoot(undefined);
782
- this._size = 0;
822
+ getHeight(beginRoot = this.root, iterationType = this.iterationType) {
823
+ beginRoot = this.ensureNode(beginRoot);
824
+ if (!beginRoot)
825
+ return -1;
826
+ if (iterationType === IterationType.RECURSIVE) {
827
+ const _getMaxHeight = (cur) => {
828
+ if (!cur)
829
+ return -1;
830
+ const leftHeight = _getMaxHeight(cur.left);
831
+ const rightHeight = _getMaxHeight(cur.right);
832
+ return Math.max(leftHeight, rightHeight) + 1;
833
+ };
834
+ return _getMaxHeight(beginRoot);
835
+ }
836
+ else {
837
+ const stack = [{ node: beginRoot, depth: 0 }];
838
+ let maxHeight = 0;
839
+ while (stack.length > 0) {
840
+ const { node, depth } = stack.pop();
841
+ if (node.left)
842
+ stack.push({ node: node.left, depth: depth + 1 });
843
+ if (node.right)
844
+ stack.push({ node: node.right, depth: depth + 1 });
845
+ maxHeight = Math.max(maxHeight, depth);
846
+ }
847
+ return maxHeight;
848
+ }
783
849
  }
784
850
  /**
785
- * Time Complexity: O(1)
786
- * Space Complexity: O(1)
851
+ * Time Complexity: O(n)
852
+ * Space Complexity: O(log n)
787
853
  */
788
854
  /**
789
- * Time Complexity: O(1)
790
- * Space Complexity: O(1)
855
+ * Time Complexity: O(n)
856
+ * Space Complexity: O(log n)
791
857
  *
792
- * Check if the binary tree is empty.
793
- * @returns {boolean} - True if the binary tree is empty, false otherwise.
858
+ * The `getMinHeight` function calculates the minimum height of a binary tree using either a
859
+ * recursive or iterative approach.
860
+ * @param {K | NODE | null | undefined} beginRoot - The `beginRoot` parameter represents the
861
+ * starting node of the binary tree from which we want to calculate the minimum height. It can be of
862
+ * type `K`, `NODE`, `null`, or `undefined`. If no value is provided, it defaults to `this.root`.
863
+ * @param iterationType - The `iterationType` parameter is used to determine the method of iteration
864
+ * to calculate the minimum height of a binary tree. It can have two possible values:
865
+ * @returns The function `getMinHeight` returns the minimum height of a binary tree.
794
866
  */
795
- isEmpty() {
796
- return this.size === 0;
867
+ getMinHeight(beginRoot = this.root, iterationType = this.iterationType) {
868
+ beginRoot = this.ensureNode(beginRoot);
869
+ if (!beginRoot)
870
+ return -1;
871
+ if (iterationType === IterationType.RECURSIVE) {
872
+ const _getMinHeight = (cur) => {
873
+ if (!cur)
874
+ return 0;
875
+ if (!cur.left && !cur.right)
876
+ return 0;
877
+ const leftMinHeight = _getMinHeight(cur.left);
878
+ const rightMinHeight = _getMinHeight(cur.right);
879
+ return Math.min(leftMinHeight, rightMinHeight) + 1;
880
+ };
881
+ return _getMinHeight(beginRoot);
882
+ }
883
+ else {
884
+ const stack = [];
885
+ let node = beginRoot, last = null;
886
+ const depths = new Map();
887
+ while (stack.length > 0 || node) {
888
+ if (node) {
889
+ stack.push(node);
890
+ node = node.left;
891
+ }
892
+ else {
893
+ node = stack[stack.length - 1];
894
+ if (!node.right || last === node.right) {
895
+ node = stack.pop();
896
+ if (node) {
897
+ const leftMinHeight = node.left ? depths.get(node.left) ?? -1 : -1;
898
+ const rightMinHeight = node.right ? depths.get(node.right) ?? -1 : -1;
899
+ depths.set(node, 1 + Math.min(leftMinHeight, rightMinHeight));
900
+ last = node;
901
+ node = null;
902
+ }
903
+ }
904
+ else
905
+ node = node.right;
906
+ }
907
+ }
908
+ return depths.get(beginRoot) ?? -1;
909
+ }
797
910
  }
798
911
  /**
912
+ * Time Complexity: O(log n)
913
+ * Space Complexity: O(log n)
914
+ * /
915
+
916
+ /**
799
917
  * Time Complexity: O(log n)
800
918
  * Space Complexity: O(log n)
801
919
  *
802
920
  * The function `getPathToRoot` returns an array of nodes from a given node to the root of a tree
803
921
  * structure, with the option to reverse the order of the nodes.
804
- * @param {K | N | null | undefined} beginNode - The `beginRoot` parameter represents the
805
- * starting node from which you want to find the path to the root. It can be of type `K`, `N`,
922
+ * @param {K | NODE | null | undefined} beginNode - The `beginRoot` parameter represents the
923
+ * starting node from which you want to find the path to the root. It can be of type `K`, `NODE`,
806
924
  * `null`, or `undefined`.
807
925
  * @param [isReverse=true] - The `isReverse` parameter is a boolean flag that determines whether the
808
926
  * resulting path should be reversed or not. If `isReverse` is set to `true`, the path will be
809
927
  * reversed before returning it. If `isReverse` is set to `false`, the path will be returned as is
810
- * @returns The function `getPathToRoot` returns an array of nodes (`N[]`).
928
+ * @returns The function `getPathToRoot` returns an array of nodes (`NODE[]`).
811
929
  */
812
930
  getPathToRoot(beginNode, isReverse = true) {
813
931
  // TODO to support get path through passing key
@@ -834,12 +952,12 @@ export class BinaryTree extends IterableEntryBase {
834
952
  *
835
953
  * The function `getLeftMost` returns the leftmost node in a binary tree, either recursively or
836
954
  * iteratively.
837
- * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
838
- * for finding the leftmost node in a binary tree. It can be either a `K` (a key value), `N` (a
955
+ * @param {K | NODE | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
956
+ * for finding the leftmost node in a binary tree. It can be either a `K` (a key value), `NODE` (a
839
957
  * node), `null`, or `undefined`. If not provided, it defaults to `this.root`,
840
958
  * @param iterationType - The `iterationType` parameter is used to determine the type of iteration to
841
959
  * be performed when finding the leftmost node in a binary tree. It can have two possible values:
842
- * @returns The function `getLeftMost` returns the leftmost node (`N`) in the binary tree. If there
960
+ * @returns The function `getLeftMost` returns the leftmost node (`NODE`) in the binary tree. If there
843
961
  * is no leftmost node, it returns `null` or `undefined` depending on the input.
844
962
  */
845
963
  getLeftMost(beginRoot = this.root, iterationType = this.iterationType) {
@@ -874,13 +992,13 @@ export class BinaryTree extends IterableEntryBase {
874
992
  *
875
993
  * The function `getRightMost` returns the rightmost node in a binary tree, either recursively or
876
994
  * iteratively.
877
- * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
878
- * starting node from which we want to find the rightmost node. It can be of type `K`, `N`,
995
+ * @param {K | NODE | null | undefined} beginRoot - The `beginRoot` parameter represents the
996
+ * starting node from which we want to find the rightmost node. It can be of type `K`, `NODE`,
879
997
  * `null`, or `undefined`. If not provided, it defaults to `this.root`, which is a property of the
880
998
  * current object.
881
999
  * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
882
1000
  * type of iteration to use when finding the rightmost node. It can have one of two values:
883
- * @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If there
1001
+ * @returns The function `getRightMost` returns the rightmost node (`NODE`) in a binary tree. If there
884
1002
  * is no rightmost node, it returns `null` or `undefined`, depending on the input.
885
1003
  */
886
1004
  getRightMost(beginRoot = this.root, iterationType = this.iterationType) {
@@ -911,60 +1029,61 @@ export class BinaryTree extends IterableEntryBase {
911
1029
  * Space Complexity: O(1)
912
1030
  */
913
1031
  /**
914
- * Time Complexity: O(n)
1032
+ * Time Complexity: O(log n)
915
1033
  * Space Complexity: O(1)
916
1034
  *
917
- * The function `isSubtreeBST` checks if a given binary tree is a valid binary search tree.
918
- * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the root
919
- * node of the binary search tree (BST) that you want to check if it is a subtree of another BST.
920
- * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
921
- * type of iteration to use when checking if a subtree is a binary search tree (BST). It can have two
922
- * possible values:
923
- * @returns a boolean value.
1035
+ * The function returns the predecessor of a given node in a tree.
1036
+ * @param {NODE} node - The parameter `node` is of type `RedBlackTreeNode`, which represents a node in a
1037
+ * tree.
1038
+ * @returns the predecessor of the given 'node'.
924
1039
  */
925
- isBST(beginRoot = this.root, iterationType = this.iterationType) {
926
- // TODO there is a bug
927
- beginRoot = this.ensureNode(beginRoot);
928
- if (!beginRoot)
929
- return true;
930
- if (iterationType === IterationType.RECURSIVE) {
931
- const dfs = (cur, min, max) => {
932
- if (!cur)
933
- return true;
934
- const numKey = this.extractor(cur.key);
935
- if (numKey <= min || numKey >= max)
936
- return false;
937
- return dfs(cur.left, min, numKey) && dfs(cur.right, numKey, max);
938
- };
939
- const isStandardBST = dfs(beginRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
940
- const isInverseBST = dfs(beginRoot, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER);
941
- return isStandardBST || isInverseBST;
1040
+ getPredecessor(node) {
1041
+ if (this.isRealNode(node.left)) {
1042
+ let predecessor = node.left;
1043
+ while (!this.isRealNode(predecessor) || (this.isRealNode(predecessor.right) && predecessor.right !== node)) {
1044
+ if (this.isRealNode(predecessor)) {
1045
+ predecessor = predecessor.right;
1046
+ }
1047
+ }
1048
+ return predecessor;
942
1049
  }
943
1050
  else {
944
- const checkBST = (checkMax = false) => {
945
- const stack = [];
946
- let prev = checkMax ? Number.MAX_SAFE_INTEGER : Number.MIN_SAFE_INTEGER;
947
- // @ts-ignore
948
- let curr = beginRoot;
949
- while (curr || stack.length > 0) {
950
- while (curr) {
951
- stack.push(curr);
952
- curr = curr.left;
953
- }
954
- curr = stack.pop();
955
- const numKey = this.extractor(curr.key);
956
- if (!curr || (!checkMax && prev >= numKey) || (checkMax && prev <= numKey))
957
- return false;
958
- prev = numKey;
959
- curr = curr.right;
960
- }
961
- return true;
962
- };
963
- const isStandardBST = checkBST(false), isInverseBST = checkBST(true);
964
- return isStandardBST || isInverseBST;
1051
+ return node;
1052
+ }
1053
+ }
1054
+ /**
1055
+ * Time Complexity: O(log n)
1056
+ * Space Complexity: O(1)
1057
+ */
1058
+ /**
1059
+ * Time Complexity: O(log n)
1060
+ * Space Complexity: O(1)
1061
+ *
1062
+ * The function `getSuccessor` returns the next node in a binary tree given a current node.
1063
+ * @param {K | NODE | null} [x] - The parameter `x` can be of type `K`, `NODE`, or `null`.
1064
+ * @returns the successor of the given node or key. The successor is the node that comes immediately
1065
+ * after the given node in the inorder traversal of the binary tree.
1066
+ */
1067
+ getSuccessor(x) {
1068
+ x = this.ensureNode(x);
1069
+ if (!this.isRealNode(x))
1070
+ return undefined;
1071
+ if (this.isRealNode(x.right)) {
1072
+ return this.getLeftMost(x.right);
1073
+ }
1074
+ let y = x.parent;
1075
+ while (this.isRealNode(y) && x === y.right) {
1076
+ x = y;
1077
+ y = y.parent;
965
1078
  }
1079
+ return y;
966
1080
  }
967
1081
  /**
1082
+ * Time complexity: O(n)
1083
+ * Space complexity: O(n)
1084
+ * /
1085
+
1086
+ /**
968
1087
  * Time complexity: O(n)
969
1088
  * Space complexity: O(n)
970
1089
  *
@@ -972,11 +1091,11 @@ export class BinaryTree extends IterableEntryBase {
972
1091
  * specified pattern and iteration type, and returns an array of values obtained from applying a
973
1092
  * callback function to each visited node.
974
1093
  * @param {C} callback - The `callback` parameter is a function that will be called for each node in
975
- * the tree during the depth-first search. It takes a single parameter, which can be of type `N`,
1094
+ * the tree during the depth-first search. It takes a single parameter, which can be of type `NODE`,
976
1095
  * `null`, or `undefined`, and returns a value of any type. The default value for this parameter is
977
1096
  * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter determines the order in which the
978
1097
  * nodes are traversed during the depth-first search. It can have one of the following values:
979
- * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
1098
+ * @param {K | NODE | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
980
1099
  * for the depth-first search traversal. It can be specified as a key, a node object, or
981
1100
  * `null`/`undefined`. If not provided, the `beginRoot` will default to the root node of the tree.
982
1101
  * @param {IterationType} iterationType - The `iterationType` parameter determines the type of
@@ -1093,6 +1212,10 @@ export class BinaryTree extends IterableEntryBase {
1093
1212
  }
1094
1213
  return ans;
1095
1214
  }
1215
+ /**
1216
+ * Time complexity: O(n)
1217
+ * Space complexity: O(n)
1218
+ */
1096
1219
  /**
1097
1220
  * Time complexity: O(n)
1098
1221
  * Space complexity: O(n)
@@ -1102,7 +1225,7 @@ export class BinaryTree extends IterableEntryBase {
1102
1225
  * @param {C} callback - The `callback` parameter is a function that will be called for each node in
1103
1226
  * the breadth-first search traversal. It takes a single parameter, which is the current node being
1104
1227
  * visited, and returns a value of any type.
1105
- * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
1228
+ * @param {K | NODE | null | undefined} beginRoot - The `beginRoot` parameter represents the
1106
1229
  * starting node for the breadth-first search traversal. It can be specified as a key, a node object,
1107
1230
  * or `null`/`undefined` to indicate the root of the tree. If not provided, the `root` property of
1108
1231
  * the class is used as
@@ -1166,6 +1289,10 @@ export class BinaryTree extends IterableEntryBase {
1166
1289
  }
1167
1290
  return ans;
1168
1291
  }
1292
+ /**
1293
+ * Time complexity: O(n)
1294
+ * Space complexity: O(n)
1295
+ */
1169
1296
  /**
1170
1297
  * Time complexity: O(n)
1171
1298
  * Space complexity: O(n)
@@ -1174,10 +1301,10 @@ export class BinaryTree extends IterableEntryBase {
1174
1301
  * a binary tree and contains the values returned by a callback function applied to the nodes at that
1175
1302
  * level.
1176
1303
  * @param {C} callback - The `callback` parameter is a function that will be called for each node in
1177
- * the tree. It takes a single parameter, which can be of type `N`, `null`, or `undefined`, and
1304
+ * the tree. It takes a single parameter, which can be of type `NODE`, `null`, or `undefined`, and
1178
1305
  * returns a value of any type.
1179
- * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
1180
- * starting node for traversing the tree. It can be either a node object (`N`), a key value
1306
+ * @param {K | NODE | null | undefined} beginRoot - The `beginRoot` parameter represents the
1307
+ * starting node for traversing the tree. It can be either a node object (`NODE`), a key value
1181
1308
  * (`K`), `null`, or `undefined`. If not provided, it defaults to the root node of the tree.
1182
1309
  * @param iterationType - The `iterationType` parameter determines the type of iteration to be
1183
1310
  * performed on the tree. It can have two possible values:
@@ -1236,53 +1363,6 @@ export class BinaryTree extends IterableEntryBase {
1236
1363
  }
1237
1364
  return levelsNodes;
1238
1365
  }
1239
- /**
1240
- * Time Complexity: O(log n)
1241
- * Space Complexity: O(1)
1242
- */
1243
- /**
1244
- * Time Complexity: O(log n)
1245
- * Space Complexity: O(1)
1246
- *
1247
- * The function returns the predecessor of a given node in a tree.
1248
- * @param {N} node - The parameter `node` is of type `RedBlackTreeNode`, which represents a node in a
1249
- * tree.
1250
- * @returns the predecessor of the given 'node'.
1251
- */
1252
- getPredecessor(node) {
1253
- if (this.isRealNode(node.left)) {
1254
- let predecessor = node.left;
1255
- while (!this.isRealNode(predecessor) || (this.isRealNode(predecessor.right) && predecessor.right !== node)) {
1256
- if (this.isRealNode(predecessor)) {
1257
- predecessor = predecessor.right;
1258
- }
1259
- }
1260
- return predecessor;
1261
- }
1262
- else {
1263
- return node;
1264
- }
1265
- }
1266
- /**
1267
- * The function `getSuccessor` returns the next node in a binary tree given a current node.
1268
- * @param {K | N | null} [x] - The parameter `x` can be of type `K`, `N`, or `null`.
1269
- * @returns the successor of the given node or key. The successor is the node that comes immediately
1270
- * after the given node in the inorder traversal of the binary tree.
1271
- */
1272
- getSuccessor(x) {
1273
- x = this.ensureNode(x);
1274
- if (!this.isRealNode(x))
1275
- return undefined;
1276
- if (this.isRealNode(x.right)) {
1277
- return this.getLeftMost(x.right);
1278
- }
1279
- let y = x.parent;
1280
- while (this.isRealNode(y) && x === y.right) {
1281
- x = y;
1282
- y = y.parent;
1283
- }
1284
- return y;
1285
- }
1286
1366
  /**
1287
1367
  * Time complexity: O(n)
1288
1368
  * Space complexity: O(n)
@@ -1294,12 +1374,12 @@ export class BinaryTree extends IterableEntryBase {
1294
1374
  * The `morris` function performs a depth-first traversal on a binary tree using the Morris traversal
1295
1375
  * algorithm.
1296
1376
  * @param {C} callback - The `callback` parameter is a function that will be called for each node in
1297
- * the tree. It takes a single parameter of type `N` (the type of the nodes in the tree) and returns
1377
+ * the tree. It takes a single parameter of type `NODE` (the type of the nodes in the tree) and returns
1298
1378
  * a value of any type.
1299
1379
  * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter in the `morris` function
1300
1380
  * determines the order in which the nodes of a binary tree are traversed. It can have one of the
1301
1381
  * following values:
1302
- * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
1382
+ * @param {K | NODE | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
1303
1383
  * for the traversal. It can be specified as a key, a node object, or `null`/`undefined` to indicate
1304
1384
  * the root of the tree. If no value is provided, the default value is the root of the tree.
1305
1385
  * @returns The function `morris` returns an array of values that are the result of invoking the
@@ -1405,7 +1485,12 @@ export class BinaryTree extends IterableEntryBase {
1405
1485
  */
1406
1486
  clone() {
1407
1487
  const cloned = this.createTree();
1408
- this.bfs(node => cloned.add([node.key, node.value]));
1488
+ this.bfs(node => {
1489
+ if (node === null)
1490
+ cloned.add(null);
1491
+ else
1492
+ cloned.add([node.key, node.value]);
1493
+ }, this.root, this.iterationType, true);
1409
1494
  return cloned;
1410
1495
  }
1411
1496
  /**
@@ -1482,7 +1567,7 @@ export class BinaryTree extends IterableEntryBase {
1482
1567
  * Space Complexity: O(n)
1483
1568
  *
1484
1569
  * The `print` function is used to display a binary tree structure in a visually appealing way.
1485
- * @param {K | N | null | undefined} [beginRoot=this.root] - The `root` parameter is of type `K | N | null |
1570
+ * @param {K | NODE | null | undefined} [beginRoot=this.root] - The `root` parameter is of type `K | NODE | null |
1486
1571
  * undefined`. It represents the root node of a binary tree. The root node can have one of the
1487
1572
  * following types:
1488
1573
  * @param {BinaryTreePrintOptions} [options={ isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false}] - Options object that controls printing behavior. You can specify whether to display undefined, null, or sentinel nodes.
@@ -1496,7 +1581,7 @@ export class BinaryTree extends IterableEntryBase {
1496
1581
  console.log(`U for undefined
1497
1582
  `);
1498
1583
  if (opts.isShowNull)
1499
- console.log(`N for null
1584
+ console.log(`NODE for null
1500
1585
  `);
1501
1586
  if (opts.isShowRedBlackNIL)
1502
1587
  console.log(`S for Sentinel Node
@@ -1509,6 +1594,15 @@ export class BinaryTree extends IterableEntryBase {
1509
1594
  };
1510
1595
  display(beginRoot);
1511
1596
  }
1597
+ /**
1598
+ * The function `_getIterator` is a protected generator function that returns an iterator for the
1599
+ * key-value pairs in a binary search tree.
1600
+ * @param node - The `node` parameter represents the current node in the binary search tree. It is an
1601
+ * optional parameter with a default value of `this.root`, which means if no node is provided, the
1602
+ * root node of the tree will be used as the starting point for iteration.
1603
+ * @returns The function `_getIterator` returns an `IterableIterator` of key-value pairs `[K, V |
1604
+ * undefined]`.
1605
+ */
1512
1606
  *_getIterator(node = this.root) {
1513
1607
  if (!node)
1514
1608
  return;
@@ -1537,6 +1631,20 @@ export class BinaryTree extends IterableEntryBase {
1537
1631
  }
1538
1632
  }
1539
1633
  }
1634
+ /**
1635
+ * The `_displayAux` function is responsible for generating the display layout of a binary tree node,
1636
+ * taking into account various options such as whether to show null, undefined, or NaN nodes.
1637
+ * @param {NODE | null | undefined} node - The `node` parameter represents a node in a binary tree.
1638
+ * It can be of type `NODE`, `null`, or `undefined`.
1639
+ * @param {BinaryTreePrintOptions} options - The `options` parameter is an object that contains the
1640
+ * following properties:
1641
+ * @returns The function `_displayAux` returns a `NodeDisplayLayout` which is an array containing the
1642
+ * following elements:
1643
+ * 1. `mergedLines`: An array of strings representing the lines of the node display.
1644
+ * 2. `totalWidth`: The total width of the node display.
1645
+ * 3. `totalHeight`: The total height of the node display.
1646
+ * 4. `middleIndex`: The index of the middle character
1647
+ */
1540
1648
  _displayAux(node, options) {
1541
1649
  const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
1542
1650
  const emptyDisplayLayout = [['─'], 1, 0, 0];
@@ -1557,7 +1665,7 @@ export class BinaryTree extends IterableEntryBase {
1557
1665
  }
1558
1666
  else {
1559
1667
  // For cases where none of the conditions are met, null, undefined, and NaN nodes are not displayed
1560
- const line = node === undefined ? 'U' : 'N', width = line.length;
1668
+ const line = node === undefined ? 'U' : 'NODE', width = line.length;
1561
1669
  return _buildNodeDisplay(line, width, [[''], 1, 0, 0], [[''], 1, 0, 0]);
1562
1670
  }
1563
1671
  function _buildNodeDisplay(line, width, left, right) {
@@ -1592,9 +1700,9 @@ export class BinaryTree extends IterableEntryBase {
1592
1700
  _defaultOneParamCallback = (node) => (node ? node.key : undefined);
1593
1701
  /**
1594
1702
  * Swap the data of two nodes in the binary tree.
1595
- * @param {N} srcNode - The source node to swap.
1596
- * @param {N} destNode - The destination node to swap.
1597
- * @returns {N} - The destination node after the swap.
1703
+ * @param {NODE} srcNode - The source node to swap.
1704
+ * @param {NODE} destNode - The destination node to swap.
1705
+ * @returns {NODE} - The destination node after the swap.
1598
1706
  */
1599
1707
  _swapProperties(srcNode, destNode) {
1600
1708
  srcNode = this.ensureNode(srcNode);
@@ -1614,9 +1722,9 @@ export class BinaryTree extends IterableEntryBase {
1614
1722
  }
1615
1723
  /**
1616
1724
  * The function replaces an old node with a new node in a binary tree.
1617
- * @param {N} oldNode - The oldNode parameter represents the node that needs to be replaced in the
1725
+ * @param {NODE} oldNode - The oldNode parameter represents the node that needs to be replaced in the
1618
1726
  * tree.
1619
- * @param {N} newNode - The `newNode` parameter is the node that will replace the `oldNode` in the
1727
+ * @param {NODE} newNode - The `newNode` parameter is the node that will replace the `oldNode` in the
1620
1728
  * tree.
1621
1729
  * @returns The method is returning the newNode.
1622
1730
  */
@@ -1640,8 +1748,8 @@ export class BinaryTree extends IterableEntryBase {
1640
1748
  /**
1641
1749
  * The function sets the root property of an object to a given value, and if the value is not null,
1642
1750
  * it also sets the parent property of the value to undefined.
1643
- * @param {N | null | undefined} v - The parameter `v` is of type `N | null | undefined`, which means it can either be of
1644
- * type `N` or `null`.
1751
+ * @param {NODE | null | undefined} v - The parameter `v` is of type `NODE | null | undefined`, which means it can either be of
1752
+ * type `NODE` or `null`.
1645
1753
  */
1646
1754
  _setRoot(v) {
1647
1755
  if (v) {