stack-typed 2.0.5 → 2.1.0

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 (101) hide show
  1. package/dist/data-structures/base/iterable-element-base.d.ts +186 -83
  2. package/dist/data-structures/base/iterable-element-base.js +149 -107
  3. package/dist/data-structures/base/iterable-entry-base.d.ts +95 -119
  4. package/dist/data-structures/base/iterable-entry-base.js +59 -116
  5. package/dist/data-structures/base/linear-base.d.ts +250 -192
  6. package/dist/data-structures/base/linear-base.js +137 -274
  7. package/dist/data-structures/binary-tree/avl-tree-counter.d.ts +126 -158
  8. package/dist/data-structures/binary-tree/avl-tree-counter.js +171 -205
  9. package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +100 -69
  10. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +135 -87
  11. package/dist/data-structures/binary-tree/avl-tree.d.ts +138 -149
  12. package/dist/data-structures/binary-tree/avl-tree.js +208 -195
  13. package/dist/data-structures/binary-tree/binary-tree.d.ts +476 -632
  14. package/dist/data-structures/binary-tree/binary-tree.js +598 -869
  15. package/dist/data-structures/binary-tree/bst.d.ts +258 -306
  16. package/dist/data-structures/binary-tree/bst.js +505 -481
  17. package/dist/data-structures/binary-tree/red-black-tree.d.ts +107 -179
  18. package/dist/data-structures/binary-tree/red-black-tree.js +114 -209
  19. package/dist/data-structures/binary-tree/tree-counter.d.ts +132 -154
  20. package/dist/data-structures/binary-tree/tree-counter.js +172 -203
  21. package/dist/data-structures/binary-tree/tree-multi-map.d.ts +72 -69
  22. package/dist/data-structures/binary-tree/tree-multi-map.js +105 -85
  23. package/dist/data-structures/graph/abstract-graph.d.ts +238 -233
  24. package/dist/data-structures/graph/abstract-graph.js +267 -237
  25. package/dist/data-structures/graph/directed-graph.d.ts +108 -224
  26. package/dist/data-structures/graph/directed-graph.js +146 -233
  27. package/dist/data-structures/graph/map-graph.d.ts +49 -55
  28. package/dist/data-structures/graph/map-graph.js +56 -59
  29. package/dist/data-structures/graph/undirected-graph.d.ts +103 -146
  30. package/dist/data-structures/graph/undirected-graph.js +129 -149
  31. package/dist/data-structures/hash/hash-map.d.ts +164 -338
  32. package/dist/data-structures/hash/hash-map.js +270 -457
  33. package/dist/data-structures/heap/heap.d.ts +214 -289
  34. package/dist/data-structures/heap/heap.js +340 -349
  35. package/dist/data-structures/heap/max-heap.d.ts +11 -47
  36. package/dist/data-structures/heap/max-heap.js +11 -66
  37. package/dist/data-structures/heap/min-heap.d.ts +12 -47
  38. package/dist/data-structures/heap/min-heap.js +11 -66
  39. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +231 -347
  40. package/dist/data-structures/linked-list/doubly-linked-list.js +368 -494
  41. package/dist/data-structures/linked-list/singly-linked-list.d.ts +261 -310
  42. package/dist/data-structures/linked-list/singly-linked-list.js +447 -466
  43. package/dist/data-structures/linked-list/skip-linked-list.d.ts +0 -107
  44. package/dist/data-structures/linked-list/skip-linked-list.js +0 -100
  45. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +12 -56
  46. package/dist/data-structures/priority-queue/max-priority-queue.js +11 -78
  47. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +11 -57
  48. package/dist/data-structures/priority-queue/min-priority-queue.js +10 -79
  49. package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -61
  50. package/dist/data-structures/priority-queue/priority-queue.js +8 -83
  51. package/dist/data-structures/queue/deque.d.ts +227 -254
  52. package/dist/data-structures/queue/deque.js +309 -348
  53. package/dist/data-structures/queue/queue.d.ts +180 -201
  54. package/dist/data-structures/queue/queue.js +265 -248
  55. package/dist/data-structures/stack/stack.d.ts +124 -102
  56. package/dist/data-structures/stack/stack.js +181 -125
  57. package/dist/data-structures/trie/trie.d.ts +164 -165
  58. package/dist/data-structures/trie/trie.js +189 -172
  59. package/dist/interfaces/binary-tree.d.ts +56 -6
  60. package/dist/interfaces/graph.d.ts +16 -0
  61. package/dist/types/data-structures/base/base.d.ts +1 -1
  62. package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -0
  63. package/dist/types/utils/utils.d.ts +1 -0
  64. package/dist/utils/utils.d.ts +1 -1
  65. package/dist/utils/utils.js +2 -1
  66. package/package.json +2 -2
  67. package/src/data-structures/base/iterable-element-base.ts +238 -115
  68. package/src/data-structures/base/iterable-entry-base.ts +96 -120
  69. package/src/data-structures/base/linear-base.ts +271 -277
  70. package/src/data-structures/binary-tree/avl-tree-counter.ts +198 -216
  71. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +192 -101
  72. package/src/data-structures/binary-tree/avl-tree.ts +239 -206
  73. package/src/data-structures/binary-tree/binary-tree.ts +664 -893
  74. package/src/data-structures/binary-tree/bst.ts +568 -570
  75. package/src/data-structures/binary-tree/red-black-tree.ts +161 -222
  76. package/src/data-structures/binary-tree/tree-counter.ts +199 -218
  77. package/src/data-structures/binary-tree/tree-multi-map.ts +131 -97
  78. package/src/data-structures/graph/abstract-graph.ts +339 -264
  79. package/src/data-structures/graph/directed-graph.ts +146 -236
  80. package/src/data-structures/graph/map-graph.ts +63 -60
  81. package/src/data-structures/graph/undirected-graph.ts +129 -152
  82. package/src/data-structures/hash/hash-map.ts +274 -496
  83. package/src/data-structures/heap/heap.ts +389 -402
  84. package/src/data-structures/heap/max-heap.ts +12 -76
  85. package/src/data-structures/heap/min-heap.ts +13 -76
  86. package/src/data-structures/linked-list/doubly-linked-list.ts +426 -530
  87. package/src/data-structures/linked-list/singly-linked-list.ts +495 -517
  88. package/src/data-structures/linked-list/skip-linked-list.ts +1 -108
  89. package/src/data-structures/priority-queue/max-priority-queue.ts +12 -87
  90. package/src/data-structures/priority-queue/min-priority-queue.ts +11 -88
  91. package/src/data-structures/priority-queue/priority-queue.ts +3 -92
  92. package/src/data-structures/queue/deque.ts +381 -357
  93. package/src/data-structures/queue/queue.ts +310 -264
  94. package/src/data-structures/stack/stack.ts +217 -131
  95. package/src/data-structures/trie/trie.ts +240 -175
  96. package/src/interfaces/binary-tree.ts +240 -6
  97. package/src/interfaces/graph.ts +37 -0
  98. package/src/types/data-structures/base/base.ts +5 -5
  99. package/src/types/data-structures/graph/abstract-graph.ts +5 -0
  100. package/src/types/utils/utils.ts +2 -0
  101. package/src/utils/utils.ts +9 -14
@@ -13,18 +13,16 @@ const queue_1 = require("../queue");
13
13
  const base_1 = require("../base");
14
14
  const common_1 = require("../../common");
15
15
  /**
16
- * Represents a node in a binary tree.
17
- * @template V - The type of data stored in the node.
18
- * @template BinaryTreeNode<K, V> - The type of the family relationship in the binary tree.
16
+ * @template K - The type of the key.
17
+ * @template V - The type of the value.
19
18
  */
20
19
  class BinaryTreeNode {
21
20
  /**
22
- * The constructor function initializes an object with a key and an optional value in TypeScript.
23
- * @param {K} key - The `key` parameter in the constructor function is used to store the key value
24
- * for the key-value pair.
25
- * @param {V} [value] - The `value` parameter in the constructor is optional, meaning it does not
26
- * have to be provided when creating an instance of the class. If a `value` is not provided, it will
27
- * default to `undefined`.
21
+ * Creates an instance of BinaryTreeNode.
22
+ * @remarks Time O(1), Space O(1)
23
+ *
24
+ * @param key - The key of the node.
25
+ * @param [value] - The value associated with the key.
28
26
  */
29
27
  constructor(key, value) {
30
28
  this.parent = undefined;
@@ -36,42 +34,108 @@ class BinaryTreeNode {
36
34
  this.key = key;
37
35
  this.value = value;
38
36
  }
37
+ /**
38
+ * Gets the left child of the node.
39
+ * @remarks Time O(1), Space O(1)
40
+ *
41
+ * @returns The left child.
42
+ */
39
43
  get left() {
40
44
  return this._left;
41
45
  }
46
+ /**
47
+ * Sets the left child of the node and updates its parent reference.
48
+ * @remarks Time O(1), Space O(1)
49
+ *
50
+ * @param v - The node to set as the left child.
51
+ */
42
52
  set left(v) {
43
53
  if (v) {
44
54
  v.parent = this;
45
55
  }
46
56
  this._left = v;
47
57
  }
58
+ /**
59
+ * Gets the right child of the node.
60
+ * @remarks Time O(1), Space O(1)
61
+ *
62
+ * @returns The right child.
63
+ */
48
64
  get right() {
49
65
  return this._right;
50
66
  }
67
+ /**
68
+ * Sets the right child of the node and updates its parent reference.
69
+ * @remarks Time O(1), Space O(1)
70
+ *
71
+ * @param v - The node to set as the right child.
72
+ */
51
73
  set right(v) {
52
74
  if (v) {
53
75
  v.parent = this;
54
76
  }
55
77
  this._right = v;
56
78
  }
79
+ /**
80
+ * Gets the height of the node (used in self-balancing trees).
81
+ * @remarks Time O(1), Space O(1)
82
+ *
83
+ * @returns The height.
84
+ */
57
85
  get height() {
58
86
  return this._height;
59
87
  }
88
+ /**
89
+ * Sets the height of the node.
90
+ * @remarks Time O(1), Space O(1)
91
+ *
92
+ * @param value - The new height.
93
+ */
60
94
  set height(value) {
61
95
  this._height = value;
62
96
  }
97
+ /**
98
+ * Gets the color of the node (used in Red-Black trees).
99
+ * @remarks Time O(1), Space O(1)
100
+ *
101
+ * @returns The node's color.
102
+ */
63
103
  get color() {
64
104
  return this._color;
65
105
  }
106
+ /**
107
+ * Sets the color of the node.
108
+ * @remarks Time O(1), Space O(1)
109
+ *
110
+ * @param value - The new color.
111
+ */
66
112
  set color(value) {
67
113
  this._color = value;
68
114
  }
115
+ /**
116
+ * Gets the count of nodes in the subtree rooted at this node (used in order-statistic trees).
117
+ * @remarks Time O(1), Space O(1)
118
+ *
119
+ * @returns The subtree node count.
120
+ */
69
121
  get count() {
70
122
  return this._count;
71
123
  }
124
+ /**
125
+ * Sets the count of nodes in the subtree.
126
+ * @remarks Time O(1), Space O(1)
127
+ *
128
+ * @param value - The new count.
129
+ */
72
130
  set count(value) {
73
131
  this._count = value;
74
132
  }
133
+ /**
134
+ * Gets the position of the node relative to its parent.
135
+ * @remarks Time O(1), Space O(1)
136
+ *
137
+ * @returns The family position (e.g., 'ROOT', 'LEFT', 'RIGHT').
138
+ */
75
139
  get familyPosition() {
76
140
  if (!this.parent) {
77
141
  return this.left || this.right ? 'ROOT' : 'ISOLATED';
@@ -87,6 +151,15 @@ class BinaryTreeNode {
87
151
  }
88
152
  exports.BinaryTreeNode = BinaryTreeNode;
89
153
  /**
154
+ * A general Binary Tree implementation.
155
+ *
156
+ * @remarks
157
+ * This class implements a basic Binary Tree, not a Binary Search Tree.
158
+ * The `add` operation inserts nodes level-by-level (BFS) into the first available slot.
159
+ *
160
+ * @template K - The type of the key.
161
+ * @template V - The type of the value.
162
+ * @template R - The type of the raw data object (if using `toEntryFn`).
90
163
  * 1. Two Children Maximum: Each node has at most two children.
91
164
  * 2. Left and Right Children: Nodes have distinct left and right children.
92
165
  * 3. Depth and Height: Depth is the number of edges from the root to a node; height is the maximum depth in the tree.
@@ -157,13 +230,11 @@ exports.BinaryTreeNode = BinaryTreeNode;
157
230
  */
158
231
  class BinaryTree extends base_1.IterableEntryBase {
159
232
  /**
160
- * This TypeScript constructor function initializes a binary tree with optional options and adds
161
- * elements based on the provided input.
162
- * @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the constructor is an
163
- * iterable that can contain either objects of type `K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined ` or `R`. It
164
- * is used to initialize the binary tree with keys, nodes, entries, or raw data.
165
- * @param [options] - The `options` parameter in the constructor is an optional object that can
166
- * contain the following properties:
233
+ * Creates an instance of BinaryTree.
234
+ * @remarks Time O(N * M), where N is the number of items in `keysNodesEntriesOrRaws` and M is the tree size at insertion time (due to O(M) `add` operation). Space O(N) for storing the nodes.
235
+ *
236
+ * @param [keysNodesEntriesOrRaws=[]] - An iterable of items to add.
237
+ * @param [options] - Configuration options for the tree.
167
238
  */
168
239
  constructor(keysNodesEntriesOrRaws = [], options) {
169
240
  super();
@@ -173,6 +244,13 @@ class BinaryTree extends base_1.IterableEntryBase {
173
244
  this._store = new Map();
174
245
  this._size = 0;
175
246
  this._NIL = new BinaryTreeNode(NaN);
247
+ /**
248
+ * (Protected) Default callback function, returns the node's key.
249
+ * @remarks Time O(1)
250
+ *
251
+ * @param node - The node.
252
+ * @returns The node's key or undefined.
253
+ */
176
254
  this._DEFAULT_NODE_CALLBACK = (node) => (node ? node.key : undefined);
177
255
  if (options) {
178
256
  const { iterationType, toEntryFn, isMapMode, isDuplicate } = options;
@@ -190,70 +268,97 @@ class BinaryTree extends base_1.IterableEntryBase {
190
268
  if (keysNodesEntriesOrRaws)
191
269
  this.addMany(keysNodesEntriesOrRaws);
192
270
  }
271
+ /**
272
+ * Gets whether the tree is in Map mode.
273
+ * @remarks In Map mode (default), values are stored in an external Map, and nodes only hold keys. If false, values are stored directly on the nodes. Time O(1)
274
+ *
275
+ * @returns True if in Map mode, false otherwise.
276
+ */
193
277
  get isMapMode() {
194
278
  return this._isMapMode;
195
279
  }
280
+ /**
281
+ * Gets whether the tree allows duplicate keys.
282
+ * @remarks Time O(1)
283
+ *
284
+ * @returns True if duplicates are allowed, false otherwise.
285
+ */
196
286
  get isDuplicate() {
197
287
  return this._isDuplicate;
198
288
  }
289
+ /**
290
+ * Gets the external value store (used in Map mode).
291
+ * @remarks Time O(1)
292
+ *
293
+ * @returns The map storing key-value pairs.
294
+ */
199
295
  get store() {
200
296
  return this._store;
201
297
  }
298
+ /**
299
+ * Gets the root node of the tree.
300
+ * @remarks Time O(1)
301
+ *
302
+ * @returns The root node.
303
+ */
202
304
  get root() {
203
305
  return this._root;
204
306
  }
307
+ /**
308
+ * Gets the number of nodes in the tree.
309
+ * @remarks Time O(1)
310
+ *
311
+ * @returns The size of the tree.
312
+ */
205
313
  get size() {
206
314
  return this._size;
207
315
  }
316
+ /**
317
+ * Gets the sentinel NIL node (used in self-balancing trees like Red-Black Tree).
318
+ * @remarks Time O(1)
319
+ *
320
+ * @returns The NIL node.
321
+ */
208
322
  get NIL() {
209
323
  return this._NIL;
210
324
  }
325
+ /**
326
+ * Gets the function used to convert raw data objects (R) into [key, value] entries.
327
+ * @remarks Time O(1)
328
+ *
329
+ * @returns The conversion function.
330
+ */
211
331
  get toEntryFn() {
212
332
  return this._toEntryFn;
213
333
  }
214
334
  /**
215
- * Time Complexity: O(1)
216
- * Space Complexity: O(1)
335
+ * (Protected) Creates a new node.
336
+ * @remarks Time O(1), Space O(1)
217
337
  *
218
- * The function creates a new binary tree node with a specified key and optional value.
219
- * @param {K} key - The `key` parameter is the key of the node being created in the binary tree.
220
- * @param {V} [value] - The `value` parameter in the `createNode` function is optional, meaning it is
221
- * not required to be provided when calling the function. If a `value` is provided, it should be of
222
- * type `V`, which is the type of the value associated with the node.
223
- * @returns A new BinaryTreeNode instance with the provided key and value is being returned, casted
224
- * as BinaryTreeNode<K, V>.
338
+ * @param key - The key for the new node.
339
+ * @param [value] - The value for the new node (used if not in Map mode).
340
+ * @returns The newly created node.
225
341
  */
226
- createNode(key, value) {
342
+ _createNode(key, value) {
227
343
  return new BinaryTreeNode(key, this._isMapMode ? undefined : value);
228
344
  }
229
345
  /**
230
- * Time Complexity: O(1)
231
- * Space Complexity: O(1)
346
+ * Creates a new, empty tree of the same type and configuration.
347
+ * @remarks Time O(1) (excluding options cloning), Space O(1)
232
348
  *
233
- * The function creates a binary tree with the specified options.
234
- * @param [options] - The `options` parameter in the `createTree` function is an optional parameter
235
- * that allows you to provide partial configuration options for creating a binary tree. It is of type
236
- * `Partial<BinaryTreeOptions<K, V, R>>`, which means you can pass in an object containing a subset
237
- * of properties
238
- * @returns A new instance of a binary tree with the specified options is being returned.
349
+ * @param [options] - Optional overrides for the new tree's options.
350
+ * @returns A new, empty tree instance.
239
351
  */
240
352
  createTree(options) {
241
- return new BinaryTree([], Object.assign({ iterationType: this.iterationType, isMapMode: this._isMapMode, toEntryFn: this._toEntryFn }, options));
353
+ return this._createInstance(options);
242
354
  }
243
355
  /**
244
- * Time Complexity: O(n)
245
- * Space Complexity: O(log n)
356
+ * Ensures the input is a node. If it's a key or entry, it searches for the node.
357
+ * @remarks Time O(1) if a node is passed. O(N) if a key or entry is passed (due to `getNode` performing a full search). Space O(1) if iterative search, O(H) if recursive (where H is height, O(N) worst-case).
246
358
  *
247
- * The function `ensureNode` in TypeScript checks if a given input is a node, entry, key, or raw
248
- * value and returns the corresponding node or null.
249
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The `keyNodeOrEntry`
250
- * parameter in the `ensureNode` function can be of type `K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined ` or `R`. It
251
- * is used to determine whether the input is a key, node, entry, or raw data. The
252
- * @param {IterationType} iterationType - The `iterationType` parameter in the `ensureNode` function
253
- * is used to specify the type of iteration to be performed. It has a default value of
254
- * `this.iterationType` if not explicitly provided.
255
- * @returns The `ensureNode` function returns either a node, `null`, or `undefined` based on the
256
- * conditions specified in the code snippet.
359
+ * @param keyNodeOrEntry - The item to resolve to a node.
360
+ * @param [iterationType=this.iterationType] - The traversal method to use if searching.
361
+ * @returns The resolved node, or null/undefined if not found or input is null/undefined.
257
362
  */
258
363
  ensureNode(keyNodeOrEntry, iterationType = this.iterationType) {
259
364
  if (keyNodeOrEntry === null)
@@ -275,47 +380,31 @@ class BinaryTree extends base_1.IterableEntryBase {
275
380
  return this.getNode(keyNodeOrEntry, this._root, iterationType);
276
381
  }
277
382
  /**
278
- * Time Complexity: O(1)
279
- * Space Complexity: O(1)
383
+ * Checks if the given item is a `BinaryTreeNode` instance.
384
+ * @remarks Time O(1), Space O(1)
280
385
  *
281
- * The function isNode checks if the input is an instance of BinaryTreeNode.
282
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The parameter
283
- * `keyNodeOrEntry` can be either a key, a node, an entry, or raw data. The function is
284
- * checking if the input is an instance of a `BinaryTreeNode` and returning a boolean value
285
- * accordingly.
286
- * @returns The function `isNode` is checking if the input `keyNodeOrEntry` is an instance of
287
- * `BinaryTreeNode`. If it is, the function returns `true`, indicating that the input is a node. If
288
- * it is not an instance of `BinaryTreeNode`, the function returns `false`, indicating that the input
289
- * is not a node.
386
+ * @param keyNodeOrEntry - The item to check.
387
+ * @returns True if it's a node, false otherwise.
290
388
  */
291
389
  isNode(keyNodeOrEntry) {
292
390
  return keyNodeOrEntry instanceof BinaryTreeNode;
293
391
  }
294
392
  /**
295
- * Time Complexity: O(1)
296
- * Space Complexity: O(1)
393
+ * Checks if the given item is a raw data object (R) that needs conversion via `toEntryFn`.
394
+ * @remarks Time O(1), Space O(1)
297
395
  *
298
- * The function `isRaw` checks if the input parameter is of type `R` by verifying if it is an object.
299
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | R} keyNodeEntryOrRaw - K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined
300
- * @returns The function `isRaw` is checking if the `keyNodeEntryOrRaw` parameter is of type `R` by
301
- * checking if it is an object. If the parameter is an object, the function will return `true`,
302
- * indicating that it is of type `R`.
396
+ * @param keyNodeEntryOrRaw - The item to check.
397
+ * @returns True if it's a raw object, false otherwise.
303
398
  */
304
399
  isRaw(keyNodeEntryOrRaw) {
305
400
  return this._toEntryFn !== undefined && typeof keyNodeEntryOrRaw === 'object';
306
401
  }
307
402
  /**
308
- * Time Complexity: O(1)
309
- * Space Complexity: O(1)
403
+ * Checks if the given item is a "real" node (i.e., not null, undefined, or NIL).
404
+ * @remarks Time O(1), Space O(1)
310
405
  *
311
- * The function `isRealNode` checks if a given input is a valid node in a binary tree.
312
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The `keyNodeOrEntry`
313
- * parameter in the `isRealNode` function can be of type `K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined ` or `R`.
314
- * The function checks if the input parameter is a `BinaryTreeNode<K, V>` type by verifying if it is not equal
315
- * @returns The function `isRealNode` is checking if the input `keyNodeOrEntry` is a valid
316
- * node by comparing it to `this._NIL`, `null`, and `undefined`. If the input is not one of these
317
- * values, it then calls the `isNode` method to further determine if the input is a node. The
318
- * function will return a boolean value indicating whether the
406
+ * @param keyNodeOrEntry - The item to check.
407
+ * @returns True if it's a real node, false otherwise.
319
408
  */
320
409
  isRealNode(keyNodeOrEntry) {
321
410
  if (keyNodeOrEntry === this._NIL || keyNodeOrEntry === null || keyNodeOrEntry === undefined)
@@ -323,97 +412,66 @@ class BinaryTree extends base_1.IterableEntryBase {
323
412
  return this.isNode(keyNodeOrEntry);
324
413
  }
325
414
  /**
326
- * Time Complexity: O(1)
327
- * Space Complexity: O(1)
415
+ * Checks if the given item is either a "real" node or null.
416
+ * @remarks Time O(1), Space O(1)
328
417
  *
329
- * The function checks if a given input is a valid node or null.
330
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The parameter
331
- * `keyNodeOrEntry` in the `isRealNodeOrNull` function can be of type `BTNRep<K,
332
- * V, BinaryTreeNode<K, V>>` or `R`. It is a union type that can either be a key, a node, an entry, or
333
- * @returns The function `isRealNodeOrNull` is returning a boolean value. It checks if the input
334
- * `keyNodeOrEntry` is either `null` or a real node, and returns `true` if it is a node or
335
- * `null`, and `false` otherwise.
418
+ * @param keyNodeOrEntry - The item to check.
419
+ * @returns True if it's a real node or null, false otherwise.
336
420
  */
337
421
  isRealNodeOrNull(keyNodeOrEntry) {
338
422
  return keyNodeOrEntry === null || this.isRealNode(keyNodeOrEntry);
339
423
  }
340
424
  /**
341
- * Time Complexity: O(1)
342
- * Space Complexity: O(1)
425
+ * Checks if the given item is the sentinel NIL node.
426
+ * @remarks Time O(1), Space O(1)
343
427
  *
344
- * The function isNIL checks if a given key, node, entry, or raw value is equal to the _NIL value.
345
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - BTNRep<K, V,
346
- * BinaryTreeNode<K, V>>
347
- * @returns The function is checking if the `keyNodeOrEntry` parameter is equal to the `_NIL`
348
- * property of the current object and returning a boolean value based on that comparison.
428
+ * @param keyNodeOrEntry - The item to check.
429
+ * @returns True if it's the NIL node, false otherwise.
349
430
  */
350
431
  isNIL(keyNodeOrEntry) {
351
432
  return keyNodeOrEntry === this._NIL;
352
433
  }
353
434
  /**
354
- * Time Complexity: O(1)
355
- * Space Complexity: O(1)
435
+ * Checks if the given item is a `Range` object.
436
+ * @remarks Time O(1), Space O(1)
356
437
  *
357
- * The function `isRange` checks if the input parameter is an instance of the `Range` class.
358
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V>> | Range<K>} keyNodeEntryOrPredicate
359
- * - The `keyNodeEntryOrPredicate` parameter in the `isRange` function can be
360
- * of type `K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined `, `NodePredicate<BinaryTreeNode<K, V>>`, or
361
- * `Range<K>`. The function checks if the `keyNodeEntry
362
- * @returns The `isRange` function is checking if the `keyNodeEntryOrPredicate` parameter is an
363
- * instance of the `Range` class. If it is an instance of `Range`, the function will return `true`,
364
- * indicating that the parameter is a `Range<K>`. If it is not an instance of `Range`, the function
365
- * will return `false`.
438
+ * @param keyNodeEntryOrPredicate - The item to check.
439
+ * @returns True if it's a Range, false otherwise.
366
440
  */
367
441
  isRange(keyNodeEntryOrPredicate) {
368
442
  return keyNodeEntryOrPredicate instanceof common_1.Range;
369
443
  }
370
444
  /**
371
- * Time Complexity: O(1)
372
- * Space Complexity: O(1)
445
+ * Checks if a node is a leaf (has no real children).
446
+ * @remarks Time O(N) if a key/entry is passed (due to `ensureNode`). O(1) if a node is passed. Space O(1) or O(H) (from `ensureNode`).
373
447
  *
374
- * The function determines whether a given key, node, entry, or raw data is a leaf node in a binary
375
- * tree.
376
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The parameter
377
- * `keyNodeOrEntry` can be of type `K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined ` or `R`. It represents a
378
- * key, node, entry, or raw data in a binary tree structure. The function `isLeaf` checks whether the
379
- * provided
380
- * @returns The function `isLeaf` returns a boolean value indicating whether the input
381
- * `keyNodeOrEntry` is a leaf node in a binary tree.
448
+ * @param keyNodeOrEntry - The node to check.
449
+ * @returns True if the node is a leaf, false otherwise.
382
450
  */
383
451
  isLeaf(keyNodeOrEntry) {
384
452
  keyNodeOrEntry = this.ensureNode(keyNodeOrEntry);
385
453
  if (keyNodeOrEntry === undefined)
386
454
  return false;
387
455
  if (keyNodeOrEntry === null)
388
- return true;
456
+ return true; // A null spot is considered a leaf
389
457
  return !this.isRealNode(keyNodeOrEntry.left) && !this.isRealNode(keyNodeOrEntry.right);
390
458
  }
391
459
  /**
392
- * Time Complexity: O(1)
393
- * Space Complexity: O(1)
460
+ * Checks if the given item is a [key, value] entry pair.
461
+ * @remarks Time O(1), Space O(1)
394
462
  *
395
- * The function `isEntry` checks if the input is a BTNEntry object by verifying if it is an array
396
- * with a length of 2.
397
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The `keyNodeOrEntry`
398
- * parameter in the `isEntry` function can be of type `K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined ` or type `R`.
399
- * The function checks if the provided `keyNodeOrEntry` is of type `BTN
400
- * @returns The `isEntry` function is checking if the `keyNodeOrEntry` parameter is an array
401
- * with a length of 2. If it is, then it returns `true`, indicating that the parameter is of type
402
- * `BTNEntry<K, V>`. If the condition is not met, it returns `false`.
463
+ * @param keyNodeOrEntry - The item to check.
464
+ * @returns True if it's an entry, false otherwise.
403
465
  */
404
466
  isEntry(keyNodeOrEntry) {
405
467
  return Array.isArray(keyNodeOrEntry) && keyNodeOrEntry.length === 2;
406
468
  }
407
469
  /**
408
- * Time Complexity O(1)
409
- * Space Complexity O(1)
470
+ * Checks if the given key is valid (comparable or null).
471
+ * @remarks Time O(1), Space O(1)
410
472
  *
411
- * The function `isValidKey` checks if a given key is comparable.
412
- * @param {any} key - The `key` parameter is of type `any`, which means it can be any data type in
413
- * TypeScript.
414
- * @returns The function `isValidKey` is checking if the `key` parameter is `null` or if it is comparable.
415
- * If the `key` is `null`, the function returns `true`. Otherwise, it returns the result of the
416
- * `isComparable` function, which is not provided in the code snippet.
473
+ * @param key - The key to validate.
474
+ * @returns True if the key is valid, false otherwise.
417
475
  */
418
476
  isValidKey(key) {
419
477
  if (key === null)
@@ -421,27 +479,17 @@ class BinaryTree extends base_1.IterableEntryBase {
421
479
  return (0, utils_1.isComparable)(key);
422
480
  }
423
481
  /**
424
- * Time Complexity O(n)
425
- * Space Complexity O(1)
482
+ * Adds a new node to the tree.
483
+ * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation adds the node at the first available position in a level-order (BFS) traversal. This is NOT a Binary Search Tree insertion. Time O(N), where N is the number of nodes. It must traverse level-by-level to find an empty slot. Space O(N) in the worst case for the BFS queue (e.g., a full last level).
426
484
  *
427
- * The `add` function in TypeScript adds a new node to a binary tree while handling duplicate keys
428
- * and finding the correct insertion position.
429
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The `add` method you provided
430
- * seems to be for adding a new node to a binary tree structure. The `keyNodeOrEntry`
431
- * parameter in the method can accept different types of values:
432
- * @param {V} [value] - The `value` parameter in the `add` method represents the value associated
433
- * with the key that you want to add to the binary tree. When adding a key-value pair to the binary
434
- * tree, you provide the key and its corresponding value. The `add` method then creates a new node
435
- * with this
436
- * @returns The `add` method returns a boolean value. It returns `true` if the insertion of the new
437
- * node was successful, and `false` if the insertion position could not be found or if a duplicate
438
- * key was found and the node was replaced instead of inserted.
485
+ * @param keyNodeOrEntry - The key, node, or entry to add.
486
+ * @param [value] - The value, if providing just a key.
487
+ * @returns True if the addition was successful, false otherwise.
439
488
  */
440
489
  add(keyNodeOrEntry, value) {
441
490
  const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
442
491
  if (newNode === undefined)
443
492
  return false;
444
- // If the tree is empty, directly set the new node as the root node
445
493
  if (!this._root) {
446
494
  this._setRoot(newNode);
447
495
  if (this._isMapMode)
@@ -450,25 +498,22 @@ class BinaryTree extends base_1.IterableEntryBase {
450
498
  return true;
451
499
  }
452
500
  const queue = new queue_1.Queue([this._root]);
453
- let potentialParent; // Record the parent node of the potential insertion location
501
+ let potentialParent;
454
502
  while (queue.length > 0) {
455
503
  const cur = queue.shift();
456
504
  if (!cur)
457
505
  continue;
458
506
  if (!this._isDuplicate) {
459
- // Check for duplicate keys when newNode is not null
460
507
  if (newNode !== null && cur.key === newNode.key) {
461
508
  this._replaceNode(cur, newNode);
462
509
  if (this._isMapMode)
463
510
  this._setValue(cur.key, newValue);
464
- return true; // If duplicate keys are found, no insertion is performed
511
+ return true; // Replaced existing node
465
512
  }
466
513
  }
467
- // Record the first possible insertion location found
468
514
  if (potentialParent === undefined && (cur.left === undefined || cur.right === undefined)) {
469
515
  potentialParent = cur;
470
516
  }
471
- // Continue traversing the left and right subtrees
472
517
  if (cur.left !== null) {
473
518
  if (cur.left)
474
519
  queue.push(cur.left);
@@ -478,7 +523,6 @@ class BinaryTree extends base_1.IterableEntryBase {
478
523
  queue.push(cur.right);
479
524
  }
480
525
  }
481
- // At the end of the traversal, if the insertion position is found, insert
482
526
  if (potentialParent) {
483
527
  if (potentialParent.left === undefined) {
484
528
  potentialParent.left = newNode;
@@ -491,28 +535,17 @@ class BinaryTree extends base_1.IterableEntryBase {
491
535
  this._size++;
492
536
  return true;
493
537
  }
494
- return false; // If the insertion position cannot be found, return undefined
495
- }
496
- /**
497
- * Time Complexity: O(k * n)
498
- * Space Complexity: O(k)
499
- *
500
- * The `addMany` function takes in multiple keys or nodes or entries or raw values along with
501
- * optional values, and adds them to a data structure while returning an array indicating whether
502
- * each insertion was successful.
503
- * @param keysNodesEntriesOrRaws - `keysNodesEntriesOrRaws` is an iterable that can contain a
504
- * mix of keys, nodes, entries, or raw values. Each element in this iterable can be of type
505
- * `K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined ` or `R`.
506
- * @param [values] - The `values` parameter in the `addMany` function is an optional parameter that
507
- * accepts an iterable of values. These values correspond to the keys or nodes being added in the
508
- * `keysNodesEntriesOrRaws` parameter. If provided, the function will iterate over the values and
509
- * assign them
510
- * @returns The `addMany` method returns an array of boolean values indicating whether each key,
511
- * node, entry, or raw value was successfully added to the data structure. Each boolean value
512
- * corresponds to the success of adding the corresponding key or value in the input iterable.
538
+ return false; // Should not happen if tree is not full?
539
+ }
540
+ /**
541
+ * Adds multiple items to the tree.
542
+ * @remarks Time O(N * M), where N is the number of items to add and M is the size of the tree at insertion (due to O(M) `add` operation). Space O(M) (from `add`) + O(N) (for the `inserted` array).
543
+ *
544
+ * @param keysNodesEntriesOrRaws - An iterable of items to add.
545
+ * @param [values] - An optional parallel iterable of values.
546
+ * @returns An array of booleans indicating the success of each individual `add` operation.
513
547
  */
514
548
  addMany(keysNodesEntriesOrRaws, values) {
515
- // TODO not sure addMany not be run multi times
516
549
  const inserted = [];
517
550
  let valuesIterator;
518
551
  if (values) {
@@ -533,46 +566,31 @@ class BinaryTree extends base_1.IterableEntryBase {
533
566
  return inserted;
534
567
  }
535
568
  /**
536
- * Time Complexity: O(k * n)
537
- * Space Complexity: O(1)
569
+ * Merges another tree into this one by adding all its nodes.
570
+ * @remarks Time O(N * M), same as `addMany`, where N is the size of `anotherTree` and M is the size of this tree. Space O(M) (from `add`).
538
571
  *
539
- * The `merge` function in TypeScript merges another binary tree into the current tree by adding all
540
- * elements from the other tree.
541
- * @param anotherTree - BinaryTree<K, V, R, MK, MV, MR>
572
+ * @param anotherTree - The tree to merge.
542
573
  */
543
574
  merge(anotherTree) {
544
575
  this.addMany(anotherTree, []);
545
576
  }
546
577
  /**
547
- * Time Complexity: O(k * n)
548
- * Space Complexity: O(1)
578
+ * Clears the tree and refills it with new items.
579
+ * @remarks Time O(N) (for `clear`) + O(N * M) (for `addMany`) = O(N * M). Space O(M) (from `addMany`).
549
580
  *
550
- * The `refill` function clears the existing data structure and then adds new key-value pairs based
551
- * on the provided input.
552
- * @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the `refill`
553
- * method can accept an iterable containing a mix of `K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined ` objects or `R`
554
- * objects.
555
- * @param [values] - The `values` parameter in the `refill` method is an optional parameter that
556
- * accepts an iterable of values of type `V` or `undefined`.
581
+ * @param keysNodesEntriesOrRaws - An iterable of items to add.
582
+ * @param [values] - An optional parallel iterable of values.
557
583
  */
558
584
  refill(keysNodesEntriesOrRaws, values) {
559
585
  this.clear();
560
586
  this.addMany(keysNodesEntriesOrRaws, values);
561
587
  }
562
588
  /**
563
- * Time Complexity: O(n)
564
- * Space Complexity: O(1)
589
+ * Deletes a node from the tree.
590
+ * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation finds the node, and if it has two children, swaps it with the rightmost node of its left subtree (in-order predecessor) before deleting. Time O(N) in the worst case. O(N) to find the node (`getNode`) and O(H) (which is O(N) worst-case) to find the rightmost node. Space O(1) (if `getNode` is iterative, which it is).
565
591
  *
566
- * The function `delete` in TypeScript implements the deletion of a node in a binary tree and returns
567
- * the deleted node along with information for tree balancing.
568
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry
569
- * - The `delete` method you provided is used to delete a node from a binary tree based on the key,
570
- * node, entry or raw data. The method returns an array of
571
- * `BinaryTreeDeleteResult` objects containing information about the deleted node and whether
572
- * balancing is needed.
573
- * @returns The `delete` method returns an array of `BinaryTreeDeleteResult` objects. Each object in
574
- * the array contains information about the node that was deleted (`deleted`) and the node that may
575
- * need to be balanced (`needBalanced`).
592
+ * @param keyNodeOrEntry - The node to delete.
593
+ * @returns An array containing deletion results (for compatibility with self-balancing trees).
576
594
  */
577
595
  delete(keyNodeOrEntry) {
578
596
  const deletedResult = [];
@@ -585,14 +603,20 @@ class BinaryTree extends base_1.IterableEntryBase {
585
603
  let needBalanced;
586
604
  let orgCurrent = curr;
587
605
  if (!curr.left && !curr.right && !parent) {
606
+ // Deleting the root with no children
588
607
  this._setRoot(undefined);
589
608
  }
590
609
  else if (curr.left) {
610
+ // Node has a left child (or two children)
611
+ // Find the rightmost node in the left subtree
591
612
  const leftSubTreeRightMost = this.getRightMost(node => node, curr.left);
592
613
  if (leftSubTreeRightMost) {
593
614
  const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
615
+ // Swap properties
594
616
  orgCurrent = this._swapProperties(curr, leftSubTreeRightMost);
617
+ // `orgCurrent` is now the node to be physically deleted (which was the rightmost)
595
618
  if (parentOfLeftSubTreeMax) {
619
+ // Unlink the rightmost node
596
620
  if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
597
621
  parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
598
622
  else
@@ -602,6 +626,8 @@ class BinaryTree extends base_1.IterableEntryBase {
602
626
  }
603
627
  }
604
628
  else if (parent) {
629
+ // Node has no left child, but has a parent
630
+ // Promote the right child (which could be null)
605
631
  const { familyPosition: fp } = curr;
606
632
  if (fp === 'LEFT' || fp === 'ROOT_LEFT') {
607
633
  parent.left = curr.right;
@@ -612,6 +638,8 @@ class BinaryTree extends base_1.IterableEntryBase {
612
638
  needBalanced = parent;
613
639
  }
614
640
  else {
641
+ // Deleting the root, which has no left child
642
+ // Promote the right child as the new root
615
643
  this._setRoot(curr.right);
616
644
  curr.right = undefined;
617
645
  }
@@ -622,28 +650,16 @@ class BinaryTree extends base_1.IterableEntryBase {
622
650
  return deletedResult;
623
651
  }
624
652
  /**
625
- * Time Complexity: O(n)
626
- * Space Complexity: O(k + log n)
627
- *
628
- * The `search` function in TypeScript performs a depth-first or breadth-first search on a tree
629
- * structure based on a given predicate or key, with options to return multiple results or just one.
630
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate - The
631
- * `keyNodeEntryOrPredicate` parameter in the `search` function can accept three types of values:
632
- * @param [onlyOne=false] - The `onlyOne` parameter in the `search` function is a boolean flag that
633
- * determines whether the search should stop after finding the first matching node. If `onlyOne` is
634
- * set to `true`, the search will return as soon as a matching node is found. If `onlyOne` is
635
- * @param {C} callback - The `callback` parameter in the `search` function is a callback function
636
- * that will be called on each node that matches the search criteria. It is of type `C`, which
637
- * extends `NodeCallback<BinaryTreeNode<K, V> | null>`. The default value for `callback` is `this._DEFAULT_NODE_CALLBACK` if
638
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the `search` function is
639
- * used to specify the node from which the search operation should begin. It represents the starting
640
- * point in the binary tree where the search will be performed. If no specific `startNode` is
641
- * provided, the search operation will start from the root
642
- * @param {IterationType} iterationType - The `iterationType` parameter in the `search` function
643
- * specifies the type of iteration to be used when searching for nodes in a binary tree. It can have
644
- * two possible values:
645
- * @returns The `search` function returns an array of values that match the provided criteria based
646
- * on the search algorithm implemented within the function.
653
+ * Searches the tree for nodes matching a predicate.
654
+ * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). Performs a full DFS (pre-order) scan of the tree. Time O(N), as it may visit every node. Space O(H) for the call stack (recursive) or explicit stack (iterative), where H is the tree height (O(N) worst-case).
655
+ *
656
+ * @template C - The type of the callback function.
657
+ * @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
658
+ * @param [onlyOne=false] - If true, stops after finding the first match.
659
+ * @param [callback=this._DEFAULT_NODE_CALLBACK] - A function to call on matching nodes.
660
+ * @param [startNode=this._root] - The node to start the search from.
661
+ * @param [iterationType=this.iterationType] - Whether to use 'RECURSIVE' or 'ITERATIVE' search.
662
+ * @returns An array of results from the callback function for each matching node.
647
663
  */
648
664
  search(keyNodeEntryOrPredicate, onlyOne = false, callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType) {
649
665
  if (keyNodeEntryOrPredicate === undefined)
@@ -690,74 +706,29 @@ class BinaryTree extends base_1.IterableEntryBase {
690
706
  }
691
707
  return ans;
692
708
  }
693
- /**
694
- * Time Complexity: O(n)
695
- * Space Complexity: O(k + log n)
696
- *
697
- * The function `getNodes` retrieves nodes from a binary tree based on a key, node, entry, raw data,
698
- * or predicate, with options for recursive or iterative traversal.
699
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate
700
- * - The `getNodes` function you provided takes several parameters:
701
- * @param [onlyOne=false] - The `onlyOne` parameter in the `getNodes` function is a boolean flag that
702
- * determines whether to return only the first node that matches the criteria specified by the
703
- * `keyNodeEntryOrPredicate` parameter. If `onlyOne` is set to `true`, the function will
704
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the
705
- * `getNodes` function is used to specify the starting point for traversing the binary tree. It
706
- * represents the root node of the binary tree or the node from which the traversal should begin. If
707
- * not provided, the default value is set to `this._root
708
- * @param {IterationType} iterationType - The `iterationType` parameter in the `getNodes` function
709
- * determines the type of iteration to be performed when traversing the nodes of a binary tree. It
710
- * can have two possible values:
711
- * @returns The `getNodes` function returns an array of nodes that satisfy the provided condition
712
- * based on the input parameters and the iteration type specified.
713
- */
714
709
  getNodes(keyNodeEntryOrPredicate, onlyOne = false, startNode = this._root, iterationType = this.iterationType) {
715
710
  return this.search(keyNodeEntryOrPredicate, onlyOne, node => node, startNode, iterationType);
716
711
  }
717
712
  /**
718
- * Time Complexity: O(n)
719
- * Space Complexity: O(log n)
720
- *
721
- * The `getNode` function retrieves a node based on the provided key, node, entry, raw data, or
722
- * predicate.
723
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate
724
- * - The `keyNodeEntryOrPredicate` parameter in the `getNode` function can accept a key,
725
- * node, entry, raw data, or a predicate function.
726
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the
727
- * `getNode` function is used to specify the starting point for searching for a node in a binary
728
- * tree. If no specific starting point is provided, the default value is set to `this._root`, which
729
- * is typically the root node of the binary tree.
730
- * @param {IterationType} iterationType - The `iterationType` parameter in the `getNode` method is
731
- * used to specify the type of iteration to be performed when searching for a node. It has a default
732
- * value of `this.iterationType`, which means it will use the iteration type defined in the current
733
- * context if no specific value is provided
734
- * @returns The `getNode` function is returning the first node that matches the specified criteria,
735
- * or `null` if no matching node is found.
713
+ * Gets the first node matching a predicate.
714
+ * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). Time O(N) in the worst case (via `search`). Space O(H) or O(N) (via `search`).
715
+ *
716
+ * @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
717
+ * @param [startNode=this._root] - The node to start the search from.
718
+ * @param [iterationType=this.iterationType] - The traversal method.
719
+ * @returns The first matching node, or undefined if not found.
736
720
  */
737
721
  getNode(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
738
722
  return this.search(keyNodeEntryOrPredicate, true, node => node, startNode, iterationType)[0];
739
723
  }
740
724
  /**
741
- * Time Complexity: O(n)
742
- * Space Complexity: O(log n)
743
- *
744
- * This function overrides the `get` method to retrieve the value associated with a specified key,
745
- * node, entry, raw data, or predicate in a data structure.
746
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate
747
- * - The `keyNodeEntryOrPredicate` parameter in the `get` method can accept one of the
748
- * following types:
749
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the `get`
750
- * method is used to specify the starting point for searching for a key or node in the binary tree.
751
- * If no specific starting point is provided, the default starting point is the root of the binary
752
- * tree (`this._root`).
753
- * @param {IterationType} iterationType - The `iterationType` parameter in the `get` method is used
754
- * to specify the type of iteration to be performed when searching for a key in the binary tree. It
755
- * is an optional parameter with a default value of `this.iterationType`, which means it will use the
756
- * iteration type defined in the
757
- * @returns The `get` method is returning the value associated with the specified key, node, entry,
758
- * raw data, or predicate in the binary tree map. If the specified key or node is found in the tree,
759
- * the method returns the corresponding value. If the key or node is not found, it returns
760
- * `undefined`.
725
+ * Gets the value associated with a key.
726
+ * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). Time O(1) if in Map mode. O(N) if not in Map mode (uses `getNode`). Space O(1) if in Map mode. O(H) or O(N) otherwise.
727
+ *
728
+ * @param keyNodeEntryOrPredicate - The key, node, or entry to get the value for.
729
+ * @param [startNode=this._root] - The node to start searching from (if not in Map mode).
730
+ * @param [iterationType=this.iterationType] - The traversal method (if not in Map mode).
731
+ * @returns The associated value, or undefined.
761
732
  */
762
733
  get(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
763
734
  var _a;
@@ -769,35 +740,12 @@ class BinaryTree extends base_1.IterableEntryBase {
769
740
  }
770
741
  return (_a = this.getNode(keyNodeEntryOrPredicate, startNode, iterationType)) === null || _a === void 0 ? void 0 : _a.value;
771
742
  }
772
- /**
773
- * Time Complexity: O(n)
774
- * Space Complexity: O(log n)
775
- *
776
- * The `has` function in TypeScript checks if a specified key, node, entry, raw data, or predicate
777
- * exists in the data structure.
778
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate
779
- * - The `keyNodeEntryOrPredicate` parameter in the `override has` method can accept one of
780
- * the following types:
781
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the
782
- * `override` method is used to specify the starting point for the search operation within the data
783
- * structure. It defaults to `this._root` if not provided explicitly.
784
- * @param {IterationType} iterationType - The `iterationType` parameter in the `override has` method
785
- * is used to specify the type of iteration to be performed. It has a default value of
786
- * `this.iterationType`, which means it will use the iteration type defined in the current context if
787
- * no value is provided when calling the method.
788
- * @returns The `override has` method is returning a boolean value. It checks if there are any nodes
789
- * that match the provided key, node, entry, raw data, or predicate in the tree structure. If there
790
- * are matching nodes, it returns `true`, indicating that the tree contains the specified element.
791
- * Otherwise, it returns `false`.
792
- */
793
743
  has(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
794
744
  return this.search(keyNodeEntryOrPredicate, true, node => node, startNode, iterationType).length > 0;
795
745
  }
796
746
  /**
797
- * Time Complexity: O(1)
798
- * Space Complexity: O(1)
799
- *
800
- * The clear function removes nodes and values in map mode.
747
+ * Clears the tree of all nodes and values.
748
+ * @remarks Time O(N) if in Map mode (due to `_store.clear()`), O(1) otherwise. Space O(1)
801
749
  */
802
750
  clear() {
803
751
  this._clearNodes();
@@ -805,57 +753,35 @@ class BinaryTree extends base_1.IterableEntryBase {
805
753
  this._clearValues();
806
754
  }
807
755
  /**
808
- * Time Complexity: O(1)
809
- * Space Complexity: O(1)
756
+ * Checks if the tree is empty.
757
+ * @remarks Time O(1), Space O(1)
810
758
  *
811
- * The `isEmpty` function in TypeScript checks if a data structure has no elements and returns a
812
- * boolean value.
813
- * @returns The `isEmpty()` method is returning a boolean value, specifically `true` if the `_size`
814
- * property is equal to 0, indicating that the data structure is empty, and `false` otherwise.
759
+ * @returns True if the tree has no nodes, false otherwise.
815
760
  */
816
761
  isEmpty() {
817
762
  return this._size === 0;
818
763
  }
819
764
  /**
820
- * Time Complexity: O(n)
821
- * Space Complexity: O(log n)
765
+ * Checks if the tree is perfectly balanced.
766
+ * @remarks A tree is perfectly balanced if the difference between min and max height is at most 1. Time O(N), as it requires two full traversals (`getMinHeight` and `getHeight`). Space O(H) or O(N) (from height calculation).
822
767
  *
823
- * The function checks if a binary tree is perfectly balanced by comparing its minimum height with
824
- * its height.
825
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter is the starting
826
- * point for checking if the binary tree is perfectly balanced. It represents the root node of the
827
- * binary tree or a specific node from which the balance check should begin.
828
- * @returns The method `isPerfectlyBalanced` is returning a boolean value, which indicates whether
829
- * the tree starting from the `startNode` node is perfectly balanced or not. The return value is
830
- * determined by comparing the minimum height of the tree with the height of the tree. If the minimum
831
- * height plus 1 is greater than or equal to the height of the tree, then it is considered perfectly
832
- * balanced and
768
+ * @param [startNode=this._root] - The node to start checking from.
769
+ * @returns True if perfectly balanced, false otherwise.
833
770
  */
834
771
  isPerfectlyBalanced(startNode = this._root) {
835
772
  return this.getMinHeight(startNode) + 1 >= this.getHeight(startNode);
836
773
  }
837
774
  /**
838
- * Time Complexity: O(n)
839
- * Space Complexity: O(log n)
775
+ * Checks if the tree is a valid Binary Search Tree (BST).
776
+ * @remarks Time O(N), as it must visit every node. Space O(H) for the call stack (recursive) or explicit stack (iterative), where H is the tree height (O(N) worst-case).
840
777
  *
841
- * The function `isBST` in TypeScript checks if a binary search tree is valid using either recursive
842
- * or iterative methods.
843
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the `isBST`
844
- * function represents the starting point for checking whether a binary search tree (BST) is valid.
845
- * It can be a node in the BST or a reference to the root of the BST. If no specific node is
846
- * provided, the function will default to
847
- * @param {IterationType} iterationType - The `iterationType` parameter in the `isBST` function
848
- * determines whether the function should use a recursive approach or an iterative approach to check
849
- * if the binary search tree (BST) is valid.
850
- * @returns The `isBST` method is returning a boolean value, which indicates whether the binary
851
- * search tree (BST) represented by the given root node is a valid BST or not. The method checks if
852
- * the tree satisfies the BST property, where for every node, all nodes in its left subtree have keys
853
- * less than the node's key, and all nodes in its right subtree have keys greater than the node's
778
+ * @param [startNode=this._root] - The node to start checking from.
779
+ * @param [iterationType=this.iterationType] - The traversal method.
780
+ * @returns True if it's a valid BST, false otherwise.
854
781
  */
855
782
  isBST(startNode = this._root, iterationType = this.iterationType) {
856
- // TODO there is a bug
857
- startNode = this.ensureNode(startNode);
858
- if (!startNode)
783
+ const startNodeSired = this.ensureNode(startNode);
784
+ if (!startNodeSired)
859
785
  return true;
860
786
  if (iterationType === 'RECURSIVE') {
861
787
  const dfs = (cur, min, max) => {
@@ -866,16 +792,16 @@ class BinaryTree extends base_1.IterableEntryBase {
866
792
  return false;
867
793
  return dfs(cur.left, min, numKey) && dfs(cur.right, numKey, max);
868
794
  };
869
- const isStandardBST = dfs(startNode, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
870
- const isInverseBST = dfs(startNode, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER);
795
+ const isStandardBST = dfs(startNodeSired, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
796
+ const isInverseBST = dfs(startNodeSired, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER); // Check for reverse BST
871
797
  return isStandardBST || isInverseBST;
872
798
  }
873
799
  else {
800
+ // Iterative in-order traversal check
874
801
  const checkBST = (checkMax = false) => {
875
802
  const stack = [];
876
803
  let prev = checkMax ? Number.MAX_SAFE_INTEGER : Number.MIN_SAFE_INTEGER;
877
- // @ts-ignore
878
- let curr = startNode;
804
+ let curr = startNodeSired;
879
805
  while (this.isRealNode(curr) || stack.length > 0) {
880
806
  while (this.isRealNode(curr)) {
881
807
  stack.push(curr);
@@ -890,25 +816,18 @@ class BinaryTree extends base_1.IterableEntryBase {
890
816
  }
891
817
  return true;
892
818
  };
893
- const isStandardBST = checkBST(false), isInverseBST = checkBST(true);
819
+ const isStandardBST = checkBST(false);
820
+ const isInverseBST = checkBST(true);
894
821
  return isStandardBST || isInverseBST;
895
822
  }
896
823
  }
897
824
  /**
898
- * Time Complexity: O(n)
899
- * Space Complexity: O(log n)
825
+ * Gets the depth of a node (distance from `startNode`).
826
+ * @remarks Time O(H), where H is the depth of the `dist` node relative to `startNode`. O(N) worst-case. Space O(1).
900
827
  *
901
- * The `getDepth` function calculates the depth between two nodes in a binary tree.
902
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } dist - The `dist` parameter in the `getDepth`
903
- * function represents the node or entry in a binary tree map, or a reference to a node in the tree.
904
- * It is the target node for which you want to calculate the depth from the `startNode` node.
905
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the
906
- * `getDepth` function represents the starting point from which you want to calculate the depth of a
907
- * given node or entry in a binary tree. If no specific starting point is provided, the default value
908
- * for `startNode` is set to the root of the binary
909
- * @returns The `getDepth` method returns the depth of a given node `dist` relative to the
910
- * `startNode` node in a binary tree. If the `dist` node is not found in the path to the `startNode`
911
- * node, it returns the depth of the `dist` node from the root of the tree.
828
+ * @param dist - The node to find the depth of.
829
+ * @param [startNode=this._root] - The node to measure depth from (defaults to root).
830
+ * @returns The depth (0 if `dist` is `startNode`).
912
831
  */
913
832
  getDepth(dist, startNode = this._root) {
914
833
  let distEnsured = this.ensureNode(dist);
@@ -924,21 +843,12 @@ class BinaryTree extends base_1.IterableEntryBase {
924
843
  return depth;
925
844
  }
926
845
  /**
927
- * Time Complexity: O(n)
928
- * Space Complexity: O(log n)
846
+ * Gets the maximum height of the tree (longest path from startNode to a leaf).
847
+ * @remarks Time O(N), as it must visit every node. Space O(H) for recursive stack (O(N) worst-case) or O(N) for iterative stack (storing node + depth).
929
848
  *
930
- * The `getHeight` function calculates the maximum height of a binary tree using either a recursive
931
- * or iterative approach in TypeScript.
932
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter is the starting
933
- * point from which the height of the binary tree will be calculated. It can be a node in the binary
934
- * tree or a reference to the root of the tree. If not provided, it defaults to the root of the
935
- * binary tree data structure.
936
- * @param {IterationType} iterationType - The `iterationType` parameter is used to determine the type
937
- * of iteration to be performed while calculating the height of the binary tree. It can have two
938
- * possible values:
939
- * @returns The `getHeight` method returns the height of the binary tree starting from the specified
940
- * root node. The height is calculated based on the maximum depth of the tree, considering either a
941
- * recursive approach or an iterative approach depending on the `iterationType` parameter.
849
+ * @param [startNode=this._root] - The node to start measuring from.
850
+ * @param [iterationType=this.iterationType] - The traversal method.
851
+ * @returns The height ( -1 for an empty tree, 0 for a single-node tree).
942
852
  */
943
853
  getHeight(startNode = this._root, iterationType = this.iterationType) {
944
854
  startNode = this.ensureNode(startNode);
@@ -955,6 +865,7 @@ class BinaryTree extends base_1.IterableEntryBase {
955
865
  return _getMaxHeight(startNode);
956
866
  }
957
867
  else {
868
+ // Iterative (using DFS)
958
869
  const stack = [{ node: startNode, depth: 0 }];
959
870
  let maxHeight = 0;
960
871
  while (stack.length > 0) {
@@ -969,22 +880,12 @@ class BinaryTree extends base_1.IterableEntryBase {
969
880
  }
970
881
  }
971
882
  /**
972
- * Time Complexity: O(n)
973
- * Space Complexity: O(log n)
883
+ * Gets the minimum height of the tree (shortest path from startNode to a leaf).
884
+ * @remarks Time O(N), as it must visit every node. Space O(H) for recursive stack (O(N) worst-case) or O(N) for iterative (due to `depths` Map).
974
885
  *
975
- * The `getMinHeight` function calculates the minimum height of a binary tree using either a
976
- * recursive or iterative approach in TypeScript.
977
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the
978
- * `getMinHeight` function represents the starting node from which the minimum height of the binary
979
- * tree will be calculated. It is either a node in the binary tree or a reference to the root of the
980
- * tree. If not provided, the default value is the root
981
- * @param {IterationType} iterationType - The `iterationType` parameter in the `getMinHeight` method
982
- * specifies the type of iteration to use when calculating the minimum height of a binary tree. It
983
- * can have two possible values:
984
- * @returns The `getMinHeight` method returns the minimum height of the binary tree starting from the
985
- * specified root node. The height is calculated based on the shortest path from the root node to a
986
- * leaf node in the tree. The method uses either a recursive approach or an iterative approach (using
987
- * a stack) based on the `iterationType` parameter.
886
+ * @param [startNode=this._root] - The node to start measuring from.
887
+ * @param [iterationType=this.iterationType] - The traversal method.
888
+ * @returns The minimum height (-1 for empty, 0 for single node).
988
889
  */
989
890
  getMinHeight(startNode = this._root, iterationType = this.iterationType) {
990
891
  startNode = this.ensureNode(startNode);
@@ -995,7 +896,7 @@ class BinaryTree extends base_1.IterableEntryBase {
995
896
  if (!this.isRealNode(cur))
996
897
  return 0;
997
898
  if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right))
998
- return 0;
899
+ return 0; // Leaf node
999
900
  const leftMinHeight = _getMinHeight(cur.left);
1000
901
  const rightMinHeight = _getMinHeight(cur.right);
1001
902
  return Math.min(leftMinHeight, rightMinHeight) + 1;
@@ -1003,6 +904,7 @@ class BinaryTree extends base_1.IterableEntryBase {
1003
904
  return _getMinHeight(startNode);
1004
905
  }
1005
906
  else {
907
+ // Iterative (using post-order DFS)
1006
908
  const stack = [];
1007
909
  let node = startNode, last = null;
1008
910
  const depths = new Map();
@@ -1031,24 +933,14 @@ class BinaryTree extends base_1.IterableEntryBase {
1031
933
  }
1032
934
  }
1033
935
  /**
1034
- * Time Complexity: O(log n)
1035
- * Space Complexity: O(log n)
1036
- *
1037
- * The function `getPathToRoot` in TypeScript retrieves the path from a given node to the root of a
1038
- * tree structure, applying a specified callback function along the way.
1039
- * @param {C} callback - The `callback` parameter is a function that is used to process each node in
1040
- * the path to the root. It is expected to be a function that takes a node as an argument and returns
1041
- * a value based on that node. The return type of the callback function is determined by the generic
1042
- * type `C
1043
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } beginNode - The `beginNode` parameter in the
1044
- * `getPathToRoot` function can be either a key, a node, an entry, or any other value of type `R`.
1045
- * @param [isReverse=true] - The `isReverse` parameter in the `getPathToRoot` function determines
1046
- * whether the resulting path from the given `beginNode` to the root should be in reverse order or
1047
- * not. If `isReverse` is set to `true`, the path will be reversed before being returned. If `is
1048
- * @returns The function `getPathToRoot` returns an array of the return values of the callback
1049
- * function `callback` applied to each node in the path from the `beginNode` to the root node. The
1050
- * array is either in reverse order or in the original order based on the value of the `isReverse`
1051
- * parameter.
936
+ * Gets the path from a given node up to the root.
937
+ * @remarks Time O(H), where H is the depth of the `beginNode`. O(N) worst-case. Space O(H) for the result array.
938
+ *
939
+ * @template C - The type of the callback function.
940
+ * @param beginNode - The node to start the path from.
941
+ * @param [callback=this._DEFAULT_NODE_CALLBACK] - A function to call on each node in the path.
942
+ * @param [isReverse=false] - If true, returns the path from root-to-node.
943
+ * @returns An array of callback results.
1052
944
  */
1053
945
  getPathToRoot(beginNode, callback = this._DEFAULT_NODE_CALLBACK, isReverse = false) {
1054
946
  const result = [];
@@ -1056,40 +948,28 @@ class BinaryTree extends base_1.IterableEntryBase {
1056
948
  if (!beginNodeEnsured)
1057
949
  return result;
1058
950
  while (beginNodeEnsured.parent) {
1059
- // Array.push + Array.reverse is more efficient than Array.unshift
1060
951
  result.push(callback(beginNodeEnsured));
1061
952
  beginNodeEnsured = beginNodeEnsured.parent;
1062
953
  }
1063
- result.push(callback(beginNodeEnsured));
954
+ result.push(callback(beginNodeEnsured)); // Add the root
1064
955
  return isReverse ? result.reverse() : result;
1065
956
  }
1066
957
  /**
1067
- * Time Complexity: O(log n)
1068
- * Space Complexity: O(log n)
1069
- *
1070
- * The function `getLeftMost` retrieves the leftmost node in a binary tree using either recursive or
1071
- * tail-recursive iteration.
1072
- * @param {C} callback - The `callback` parameter is a function that will be called with the leftmost
1073
- * node of a binary tree or with `undefined` if the tree is empty. It is provided with a default
1074
- * value of `_DEFAULT_NODE_CALLBACK` if not specified.
1075
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the
1076
- * `getLeftMost` function represents the starting point for finding the leftmost node in a binary
1077
- * tree. It can be either a key, a node, or an entry in the binary tree structure. If no specific
1078
- * starting point is provided, the function will default
1079
- * @param {IterationType} iterationType - The `iterationType` parameter in the `getLeftMost` function
1080
- * specifies the type of iteration to be used when traversing the binary tree nodes. It can have two
1081
- * possible values:
1082
- * @returns The `getLeftMost` function returns the result of the callback function `C` applied to the
1083
- * leftmost node in the binary tree starting from the `startNode` node. If the `startNode` node is
1084
- * `NIL`, it returns the result of the callback function applied to `undefined`. If the `startNode`
1085
- * node is not a real node, it returns the result of the callback
958
+ * Finds the leftmost node in a subtree (the node with the smallest key in a BST).
959
+ * @remarks Time O(H), where H is the height of the left spine. O(N) worst-case. Space O(H) for recursive/trampoline stack.
960
+ *
961
+ * @template C - The type of the callback function.
962
+ * @param [callback=this._DEFAULT_NODE_CALLBACK] - A function to call on the leftmost node.
963
+ * @param [startNode=this._root] - The subtree root to search from.
964
+ * @param [iterationType=this.iterationType] - The traversal method.
965
+ * @returns The callback result for the leftmost node.
1086
966
  */
1087
967
  getLeftMost(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType) {
1088
968
  if (this.isNIL(startNode))
1089
969
  return callback(undefined);
1090
970
  startNode = this.ensureNode(startNode);
1091
971
  if (!this.isRealNode(startNode))
1092
- return callback(startNode);
972
+ return callback(undefined);
1093
973
  if (iterationType === 'RECURSIVE') {
1094
974
  const dfs = (cur) => {
1095
975
  const { left } = cur;
@@ -1100,7 +980,7 @@ class BinaryTree extends base_1.IterableEntryBase {
1100
980
  return callback(dfs(startNode));
1101
981
  }
1102
982
  else {
1103
- // Indirect implementation of iteration using tail recursion optimization
983
+ // Iterative (trampolined to prevent stack overflow, though 'ITERATIVE' usually means a loop)
1104
984
  const dfs = (0, utils_1.makeTrampoline)((cur) => {
1105
985
  const { left } = cur;
1106
986
  if (!this.isRealNode(left))
@@ -1111,33 +991,21 @@ class BinaryTree extends base_1.IterableEntryBase {
1111
991
  }
1112
992
  }
1113
993
  /**
1114
- * Time Complexity: O(log n)
1115
- * Space Complexity: O(log n)
1116
- *
1117
- * The function `getRightMost` retrieves the rightmost node in a binary tree using either recursive
1118
- * or iterative traversal methods.
1119
- * @param {C} callback - The `callback` parameter is a function that will be called with the result
1120
- * of finding the rightmost node in a binary tree. It is of type `NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>`,
1121
- * which means it is a callback function that can accept either an optional binary tree node or null
1122
- * as
1123
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the
1124
- * `getRightMost` function represents the starting point for finding the rightmost node in a binary
1125
- * tree. It can be either a key, a node, or an entry in the binary tree structure. If no specific
1126
- * starting point is provided, the function will default
1127
- * @param {IterationType} iterationType - The `iterationType` parameter in the `getRightMost`
1128
- * function specifies the type of iteration to be used when traversing the binary tree nodes. It can
1129
- * have two possible values:
1130
- * @returns The `getRightMost` function returns the result of the callback function `C`, which is
1131
- * passed as a parameter to the function. The callback function is called with the rightmost node in
1132
- * the binary tree structure, determined based on the specified iteration type ('RECURSIVE' or
1133
- * other).
994
+ * Finds the rightmost node in a subtree (the node with the largest key in a BST).
995
+ * @remarks Time O(H), where H is the height of the right spine. O(N) worst-case. Space O(H) for recursive/trampoline stack.
996
+ *
997
+ * @template C - The type of the callback function.
998
+ * @param [callback=this._DEFAULT_NODE_CALLBACK] - A function to call on the rightmost node.
999
+ * @param [startNode=this._root] - The subtree root to search from.
1000
+ * @param [iterationType=this.iterationType] - The traversal method.
1001
+ * @returns The callback result for the rightmost node.
1134
1002
  */
1135
1003
  getRightMost(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType) {
1136
1004
  if (this.isNIL(startNode))
1137
1005
  return callback(undefined);
1138
1006
  startNode = this.ensureNode(startNode);
1139
1007
  if (!startNode)
1140
- return callback(startNode);
1008
+ return callback(undefined);
1141
1009
  if (iterationType === 'RECURSIVE') {
1142
1010
  const dfs = (cur) => {
1143
1011
  const { right } = cur;
@@ -1148,7 +1016,6 @@ class BinaryTree extends base_1.IterableEntryBase {
1148
1016
  return callback(dfs(startNode));
1149
1017
  }
1150
1018
  else {
1151
- // Indirect implementation of iteration using tail recursion optimization
1152
1019
  const dfs = (0, utils_1.makeTrampoline)((cur) => {
1153
1020
  const { right } = cur;
1154
1021
  if (!this.isRealNode(right))
@@ -1159,17 +1026,11 @@ class BinaryTree extends base_1.IterableEntryBase {
1159
1026
  }
1160
1027
  }
1161
1028
  /**
1162
- * Time Complexity: O(log n)
1163
- * Space Complexity: O(log n)
1029
+ * Gets the Morris traversal predecessor (rightmost node in the left subtree, or node itself).
1030
+ * @remarks This is primarily a helper for Morris traversal. Time O(H), where H is the height of the left subtree. O(N) worst-case. Space O(1).
1164
1031
  *
1165
- * The function `getPredecessor` in TypeScript returns the predecessor node of a given node in a
1166
- * binary tree.
1167
- * @param {BinaryTreeNode<K, V>} node - The `getPredecessor` function you provided seems to be attempting to find the
1168
- * predecessor of a given node in a binary tree. However, there seems to be a logical issue in the
1169
- * while loop condition that might cause an infinite loop.
1170
- * @returns The `getPredecessor` function returns the predecessor node of the input `BinaryTreeNode<K, V>` parameter.
1171
- * If the left child of the input node exists, it traverses to the rightmost node of the left subtree
1172
- * to find the predecessor. If the left child does not exist, it returns the input node itself.
1032
+ * @param node - The node to find the predecessor for.
1033
+ * @returns The Morris predecessor.
1173
1034
  */
1174
1035
  getPredecessor(node) {
1175
1036
  if (this.isRealNode(node.left)) {
@@ -1186,17 +1047,11 @@ class BinaryTree extends base_1.IterableEntryBase {
1186
1047
  }
1187
1048
  }
1188
1049
  /**
1189
- * Time Complexity: O(log n)
1190
- * Space Complexity: O(log n)
1050
+ * Gets the in-order successor of a node in a BST.
1051
+ * @remarks Time O(H), where H is the tree height. O(N) worst-case. Space O(H) (due to `getLeftMost` stack).
1191
1052
  *
1192
- * The function `getSuccessor` in TypeScript returns the next node in an in-order traversal of a
1193
- * binary tree.
1194
- * @param {K | BinaryTreeNode<K, V> | null} [x] - The `getSuccessor` function takes a parameter `x`, which can be of
1195
- * type `K`, `BinaryTreeNode<K, V>`, or `null`.
1196
- * @returns The `getSuccessor` function returns the successor node of the input node `x`. If `x` has
1197
- * a right child, the function returns the leftmost node in the right subtree of `x`. If `x` does not
1198
- * have a right child, the function traverses up the parent nodes until it finds a node that is not
1199
- * the right child of its parent, and returns that node
1053
+ * @param [x] - The node to find the successor of.
1054
+ * @returns The successor node, or null/undefined if none exists.
1200
1055
  */
1201
1056
  getSuccessor(x) {
1202
1057
  x = this.ensureNode(x);
@@ -1213,32 +1068,17 @@ class BinaryTree extends base_1.IterableEntryBase {
1213
1068
  return y;
1214
1069
  }
1215
1070
  /**
1216
- * Time complexity: O(n)
1217
- * Space complexity: O(n)
1218
- *
1219
- * The function performs a depth-first search on a binary tree structure based on the specified
1220
- * parameters.
1221
- * @param {C} callback - The `callback` parameter is a function that will be called for each node
1222
- * visited during the depth-first search. It should accept a `BinaryTreeNode` as an argument and
1223
- * return an optional node or null. The default value for this parameter is `_DEFAULT_NODE_CALLBACK`.
1224
- * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `dfs` function specifies
1225
- * the order in which the nodes are visited during a depth-first search traversal. The possible
1226
- * values for the `pattern` parameter are:
1227
- * @param {boolean} [onlyOne=false] - The `onlyOne` parameter in the `dfs` function is a boolean flag
1228
- * that determines whether the depth-first search should stop after finding the first matching node
1229
- * or continue searching for all matching nodes. If `onlyOne` is set to `true`, the search will stop
1230
- * after finding the first matching node
1231
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined}
1232
- * startNode - The `startNode` parameter in the `dfs` function can be one of the following types:
1233
- * @param {IterationType} iterationType - The `iterationType` parameter in the `dfs` function
1234
- * specifies the type of iteration to be performed during the Depth-First Search traversal. It is
1235
- * used to determine the order in which nodes are visited during the traversal. The possible values
1236
- * for `iterationType` are typically defined as an enum or a
1237
- * @param [includeNull=false] - The `includeNull` parameter in the `dfs` function determines whether
1238
- * null nodes should be included in the depth-first search traversal. If `includeNull` is set to
1239
- * `true`, null nodes will be included in the traversal process. If it is set to `false`, null nodes
1240
- * will be skipped
1241
- * @returns The `dfs` method is returning an array of the return type of the callback function `C`.
1071
+ * Performs a Depth-First Search (DFS) traversal.
1072
+ * @remarks Time O(N), visits every node. Space O(H) for the call/explicit stack. O(N) worst-case.
1073
+ *
1074
+ * @template C - The type of the callback function.
1075
+ * @param [callback=this._DEFAULT_NODE_CALLBACK] - Function to call on each node.
1076
+ * @param [pattern='IN'] - The traversal order ('IN', 'PRE', 'POST').
1077
+ * @param [onlyOne=false] - If true, stops after the first callback.
1078
+ * @param [startNode=this._root] - The node to start from.
1079
+ * @param [iterationType=this.iterationType] - The traversal method.
1080
+ * @param [includeNull=false] - If true, includes null nodes in the traversal.
1081
+ * @returns An array of callback results.
1242
1082
  */
1243
1083
  dfs(callback = this._DEFAULT_NODE_CALLBACK, pattern = 'IN', onlyOne = false, startNode = this._root, iterationType = this.iterationType, includeNull = false) {
1244
1084
  startNode = this.ensureNode(startNode);
@@ -1247,27 +1087,15 @@ class BinaryTree extends base_1.IterableEntryBase {
1247
1087
  return this._dfs(callback, pattern, onlyOne, startNode, iterationType, includeNull);
1248
1088
  }
1249
1089
  /**
1250
- * Time complexity: O(n)
1251
- * Space complexity: O(n)
1252
- *
1253
- * The `bfs` function performs a breadth-first search traversal on a binary tree or binary search
1254
- * tree, executing a specified callback function on each node visited.
1255
- * @param {C} callback - The `callback` parameter in the `bfs` function is a function that will be
1256
- * called on each node visited during the breadth-first search traversal. It is a generic type `C`
1257
- * that extends the `NodeCallback` type, which takes a parameter of type `BinaryTreeNode<K, V>` or `null`.
1258
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the `bfs`
1259
- * function represents the starting point for the breadth-first search traversal in a binary tree. It
1260
- * can be specified as a key, node, or entry in the binary tree structure. If not provided, the
1261
- * default value is the root node of the binary
1262
- * @param {IterationType} iterationType - The `iterationType` parameter in the `bfs` function
1263
- * determines the type of iteration to be performed on the binary tree nodes. It can have two
1264
- * possible values:
1265
- * @param [includeNull=false] - The `includeNull` parameter in the `bfs` function determines whether
1266
- * to include `null` values in the breadth-first search traversal of a binary tree. If `includeNull`
1267
- * is set to `true`, the traversal will include `null` values for nodes that do not have children
1268
- * (left
1269
- * @returns The `bfs` function returns an array of values that are the result of applying the
1270
- * provided callback function to each node in the binary tree in a breadth-first search manner.
1090
+ * Performs a Breadth-First Search (BFS) or Level-Order traversal.
1091
+ * @remarks Time O(N), visits every node. Space O(N) in the worst case for the queue (e.g., a full last level).
1092
+ *
1093
+ * @template C - The type of the callback function.
1094
+ * @param [callback=this._DEFAULT_NODE_CALLBACK] - Function to call on each node.
1095
+ * @param [startNode=this._root] - The node to start from.
1096
+ * @param [iterationType=this.iterationType] - The traversal method ('RECURSIVE' BFS is less common but supported here).
1097
+ * @param [includeNull=false] - If true, includes null nodes in the traversal.
1098
+ * @returns An array of callback results.
1271
1099
  */
1272
1100
  bfs(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType, includeNull = false) {
1273
1101
  startNode = this.ensureNode(startNode);
@@ -1275,6 +1103,7 @@ class BinaryTree extends base_1.IterableEntryBase {
1275
1103
  return [];
1276
1104
  const ans = [];
1277
1105
  if (iterationType === 'RECURSIVE') {
1106
+ // This is a "recursive" BFS, which is atypical. It uses a queue but calls itself.
1278
1107
  const queue = new queue_1.Queue([
1279
1108
  startNode
1280
1109
  ]);
@@ -1300,9 +1129,10 @@ class BinaryTree extends base_1.IterableEntryBase {
1300
1129
  dfs(0);
1301
1130
  }
1302
1131
  else {
1132
+ // Standard iterative BFS
1303
1133
  const queue = new queue_1.Queue([startNode]);
1304
1134
  while (queue.length > 0) {
1305
- const levelSize = queue.length;
1135
+ const levelSize = queue.length; // Not strictly needed here, but good for level-by-level
1306
1136
  for (let i = 0; i < levelSize; i++) {
1307
1137
  const current = queue.shift();
1308
1138
  ans.push(callback(current));
@@ -1324,22 +1154,14 @@ class BinaryTree extends base_1.IterableEntryBase {
1324
1154
  return ans;
1325
1155
  }
1326
1156
  /**
1327
- * Time complexity: O(n)
1328
- * Space complexity: O(n)
1157
+ * Finds all leaf nodes in the tree.
1158
+ * @remarks Time O(N), visits every node. Space O(H) for recursive stack or O(N) for iterative queue.
1329
1159
  *
1330
- * The `leaves` function in TypeScript returns an array of values from leaf nodes in a binary tree
1331
- * structure based on a specified callback and iteration type.
1332
- * @param {C} callback - The `callback` parameter is a function that will be called on each leaf node
1333
- * in the binary tree. It is optional and defaults to a default callback function if not provided.
1334
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the `leaves`
1335
- * method is used to specify the starting point for finding and processing the leaves of a binary
1336
- * tree. It can be provided as either a key, a node, or an entry in the binary tree structure. If not
1337
- * explicitly provided, the default value
1338
- * @param {IterationType} iterationType - The `iterationType` parameter in the `leaves` method
1339
- * specifies the type of iteration to be performed when collecting the leaves of a binary tree. It
1340
- * can have two possible values:
1341
- * @returns The `leaves` method returns an array of values that are the result of applying the
1342
- * provided callback function to each leaf node in the binary tree.
1160
+ * @template C - The type of the callback function.
1161
+ * @param [callback=this._DEFAULT_NODE_CALLBACK] - Function to call on each leaf node.
1162
+ * @param [startNode=this._root] - The node to start from.
1163
+ * @param [iterationType=this.iterationType] - The traversal method.
1164
+ * @returns An array of callback results.
1343
1165
  */
1344
1166
  leaves(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType) {
1345
1167
  startNode = this.ensureNode(startNode);
@@ -1347,6 +1169,7 @@ class BinaryTree extends base_1.IterableEntryBase {
1347
1169
  if (!this.isRealNode(startNode))
1348
1170
  return [];
1349
1171
  if (iterationType === 'RECURSIVE') {
1172
+ // DFS-based
1350
1173
  const dfs = (cur) => {
1351
1174
  if (this.isLeaf(cur)) {
1352
1175
  leaves.push(callback(cur));
@@ -1361,6 +1184,7 @@ class BinaryTree extends base_1.IterableEntryBase {
1361
1184
  dfs(startNode);
1362
1185
  }
1363
1186
  else {
1187
+ // BFS-based
1364
1188
  const queue = new queue_1.Queue([startNode]);
1365
1189
  while (queue.length > 0) {
1366
1190
  const cur = queue.shift();
@@ -1378,28 +1202,15 @@ class BinaryTree extends base_1.IterableEntryBase {
1378
1202
  return leaves;
1379
1203
  }
1380
1204
  /**
1381
- * Time complexity: O(n)
1382
- * Space complexity: O(n)
1383
- *
1384
- * The `listLevels` function in TypeScript generates a list of nodes at each level of a binary tree,
1385
- * using either recursive or iterative traversal based on the specified iteration type.
1386
- * @param {C} callback - The `callback` parameter is a function that will be applied to each node in
1387
- * the binary tree during the traversal. It is used to process each node and determine what
1388
- * information to include in the output for each level of the tree.
1389
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the
1390
- * `listLevels` function represents the starting point for traversing the binary tree. It can be
1391
- * either a key, a node, or an entry in the binary tree. If not provided, the default value is the
1392
- * root of the binary tree.
1393
- * @param {IterationType} iterationType - The `iterationType` parameter in the `listLevels` function
1394
- * determines the type of iteration to be performed on the binary tree nodes. It can have two
1395
- * possible values:
1396
- * @param [includeNull=false] - The `includeNull` parameter in the `listLevels` method determines
1397
- * whether or not to include null nodes in the traversal of the binary tree. If `includeNull` is set
1398
- * to `true`, the traversal will include null nodes in the levels of the tree. If set to `false`,
1399
- * null
1400
- * @returns The `listLevels` method returns an array of arrays, where each inner array represents a
1401
- * level in a binary tree. Each inner array contains the return value of the provided callback
1402
- * function applied to the nodes at that level.
1205
+ * Returns a 2D array of nodes, grouped by level.
1206
+ * @remarks Time O(N), visits every node. Space O(N) for the result array and the queue/stack.
1207
+ *
1208
+ * @template C - The type of the callback function.
1209
+ * @param [callback=this._DEFAULT_NODE_CALLBACK] - Function to call on each node.
1210
+ * @param [startNode=this._root] - The node to start from.
1211
+ * @param [iterationType=this.iterationType] - The traversal method.
1212
+ * @param [includeNull=false] - If true, includes null nodes.
1213
+ * @returns A 2D array of callback results.
1403
1214
  */
1404
1215
  listLevels(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType, includeNull = false) {
1405
1216
  startNode = this.ensureNode(startNode);
@@ -1407,6 +1218,7 @@ class BinaryTree extends base_1.IterableEntryBase {
1407
1218
  if (!startNode)
1408
1219
  return levelsNodes;
1409
1220
  if (iterationType === 'RECURSIVE') {
1221
+ // Pre-order DFS based level listing
1410
1222
  const _recursive = (node, level) => {
1411
1223
  if (!levelsNodes[level])
1412
1224
  levelsNodes[level] = [];
@@ -1427,6 +1239,7 @@ class BinaryTree extends base_1.IterableEntryBase {
1427
1239
  _recursive(startNode, 0);
1428
1240
  }
1429
1241
  else {
1242
+ // Iterative DFS based level listing
1430
1243
  const stack = [[startNode, 0]];
1431
1244
  while (stack.length > 0) {
1432
1245
  const head = stack.pop();
@@ -1451,24 +1264,14 @@ class BinaryTree extends base_1.IterableEntryBase {
1451
1264
  return levelsNodes;
1452
1265
  }
1453
1266
  /**
1454
- * Time complexity: O(n)
1455
- * Space complexity: O(n)
1456
- *
1457
- * The `morris` function in TypeScript performs a Depth-First Search traversal on a binary tree using
1458
- * Morris Traversal algorithm with different order patterns.
1459
- * @param {C} callback - The `callback` parameter in the `morris` function is a function that will be
1460
- * called on each node in the binary tree during the traversal. It is of type `C`, which extends the
1461
- * `NodeCallback<BinaryTreeNode<K, V> | null>` type. The default value for `callback` is `this._DEFAULT
1462
- * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `morris` function specifies
1463
- * the type of Depth-First Search (DFS) order pattern to traverse the binary tree. The possible
1464
- * values for the `pattern` parameter are:
1465
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the `morris`
1466
- * function is the starting point for the Morris traversal algorithm. It represents the root node of
1467
- * the binary tree or the node from which the traversal should begin. It can be provided as either a
1468
- * key, a node, an entry, or a reference
1469
- * @returns The `morris` function is returning an array of values that are the result of applying the
1470
- * provided callback function to each node in the binary tree in the specified order pattern (IN,
1471
- * PRE, or POST).
1267
+ * Performs a Morris (threaded) traversal.
1268
+ * @remarks This traversal uses O(1) extra space (excluding the result array) by temporarily modifying the tree's right child pointers. Time O(N), as each node is visited a constant number of times. Space O(1) (excluding the `ans` array).
1269
+ *
1270
+ * @template C - The type of the callback function.
1271
+ * @param [callback=this._DEFAULT_NODE_CALLBACK] - Function to call on each node.
1272
+ * @param [pattern='IN'] - The traversal order ('IN', 'PRE', 'POST').
1273
+ * @param [startNode=this._root] - The node to start from.
1274
+ * @returns An array of callback results.
1472
1275
  */
1473
1276
  morris(callback = this._DEFAULT_NODE_CALLBACK, pattern = 'IN', startNode = this._root) {
1474
1277
  startNode = this.ensureNode(startNode);
@@ -1476,6 +1279,7 @@ class BinaryTree extends base_1.IterableEntryBase {
1476
1279
  return [];
1477
1280
  const ans = [];
1478
1281
  let cur = startNode;
1282
+ // Helper to reverse a linked list (formed by right pointers)
1479
1283
  const _reverseEdge = (node) => {
1480
1284
  let pre = null;
1481
1285
  let next = null;
@@ -1487,6 +1291,7 @@ class BinaryTree extends base_1.IterableEntryBase {
1487
1291
  }
1488
1292
  return pre;
1489
1293
  };
1294
+ // Helper to print the reversed edge (for post-order)
1490
1295
  const _printEdge = (node) => {
1491
1296
  const tail = _reverseEdge(node);
1492
1297
  let cur = tail;
@@ -1494,7 +1299,7 @@ class BinaryTree extends base_1.IterableEntryBase {
1494
1299
  ans.push(callback(cur));
1495
1300
  cur = cur.right;
1496
1301
  }
1497
- _reverseEdge(tail);
1302
+ _reverseEdge(tail); // Restore the edge
1498
1303
  };
1499
1304
  switch (pattern) {
1500
1305
  case 'IN':
@@ -1502,11 +1307,13 @@ class BinaryTree extends base_1.IterableEntryBase {
1502
1307
  if (cur.left) {
1503
1308
  const predecessor = this.getPredecessor(cur);
1504
1309
  if (!predecessor.right) {
1310
+ // Create thread
1505
1311
  predecessor.right = cur;
1506
1312
  cur = cur.left;
1507
1313
  continue;
1508
1314
  }
1509
1315
  else {
1316
+ // Remove thread
1510
1317
  predecessor.right = null;
1511
1318
  }
1512
1319
  }
@@ -1519,12 +1326,14 @@ class BinaryTree extends base_1.IterableEntryBase {
1519
1326
  if (cur.left) {
1520
1327
  const predecessor = this.getPredecessor(cur);
1521
1328
  if (!predecessor.right) {
1329
+ // Create thread and visit
1522
1330
  predecessor.right = cur;
1523
1331
  ans.push(callback(cur));
1524
1332
  cur = cur.left;
1525
1333
  continue;
1526
1334
  }
1527
1335
  else {
1336
+ // Remove thread
1528
1337
  predecessor.right = null;
1529
1338
  }
1530
1339
  }
@@ -1539,108 +1348,77 @@ class BinaryTree extends base_1.IterableEntryBase {
1539
1348
  if (cur.left) {
1540
1349
  const predecessor = this.getPredecessor(cur);
1541
1350
  if (predecessor.right === null) {
1351
+ // Create thread
1542
1352
  predecessor.right = cur;
1543
1353
  cur = cur.left;
1544
1354
  continue;
1545
1355
  }
1546
1356
  else {
1357
+ // Remove thread and print right spine of left child
1547
1358
  predecessor.right = null;
1548
1359
  _printEdge(cur.left);
1549
1360
  }
1550
1361
  }
1551
1362
  cur = cur.right;
1552
1363
  }
1553
- _printEdge(startNode);
1364
+ _printEdge(startNode); // Print the right spine of the root
1554
1365
  break;
1555
1366
  }
1556
1367
  return ans;
1557
1368
  }
1558
1369
  /**
1559
- * Time complexity: O(n)
1560
- * Space complexity: O(n)
1370
+ * Clones the tree.
1371
+ * @remarks Time O(N * M), where N is the number of nodes and M is the tree size during insertion (due to `bfs` + `add`, and `add` is O(M)). Space O(N) for the new tree and the BFS queue.
1561
1372
  *
1562
- * The `clone` function creates a deep copy of a tree structure by traversing it using breadth-first
1563
- * search.
1564
- * @returns The `clone()` method is returning a cloned copy of the tree with the same structure and
1565
- * values as the original tree. The method creates a new tree, iterates over the nodes of the
1566
- * original tree using breadth-first search (bfs), and adds the nodes to the new tree. If a node in
1567
- * the original tree is null, a null node is added to the cloned tree. If a node
1373
+ * @returns A new, cloned instance of the tree.
1568
1374
  */
1569
1375
  clone() {
1570
- const cloned = this.createTree();
1571
- this._clone(cloned);
1572
- return cloned;
1573
- }
1574
- /**
1575
- * Time Complexity: O(n)
1576
- * Space Complexity: O(n)
1577
- *
1578
- * The `filter` function iterates over key-value pairs in a tree data structure and creates a new
1579
- * tree with elements that satisfy a given predicate.
1580
- * @param predicate - The `predicate` parameter in the `filter` method is a function that will be
1581
- * called with four arguments: the `value` of the current entry, the `key` of the current entry, the
1582
- * `index` of the current entry in the iteration, and the reference to the tree itself (`
1583
- * @param {any} [thisArg] - The `thisArg` parameter in the `filter` method allows you to specify the
1584
- * value of `this` that should be used when executing the `predicate` function. This is useful when
1585
- * the `predicate` function relies on the context of a specific object or value. By providing a
1586
- * `thisArg
1587
- * @returns The `filter` method is returning a new tree that contains entries that pass the provided
1588
- * predicate function.
1376
+ const out = this._createInstance();
1377
+ this._clone(out);
1378
+ return out;
1379
+ }
1380
+ /**
1381
+ * Creates a new tree containing only the entries that satisfy the predicate.
1382
+ * @remarks Time O(N * M), where N is nodes in this tree, and M is size of the new tree during insertion (O(N) iteration + O(M) `add` for each item). Space O(N) for the new tree.
1383
+ *
1384
+ * @param predicate - A function to test each [key, value] pair.
1385
+ * @param [thisArg] - `this` context for the predicate.
1386
+ * @returns A new, filtered tree.
1589
1387
  */
1590
1388
  filter(predicate, thisArg) {
1591
- const newTree = this.createTree();
1592
- let index = 0;
1593
- for (const [key, value] of this) {
1594
- if (predicate.call(thisArg, key, value, index++, this)) {
1595
- newTree.add([key, value]);
1596
- }
1597
- }
1598
- return newTree;
1599
- }
1600
- /**
1601
- * Time Complexity: O(n)
1602
- * Space Complexity: O(n)
1603
- *
1604
- * The `map` function in TypeScript creates a new BinaryTree by applying a callback function to each
1605
- * entry in the original BinaryTree.
1606
- * @param callback - A function that will be called for each entry in the current binary tree. It
1607
- * takes the key, value (which can be undefined), and an array containing the mapped key and value as
1608
- * arguments.
1609
- * @param [options] - The `options` parameter in the `map` method is of type `BinaryTreeOptions<MK,
1610
- * MV, MR>`. It is an optional parameter that allows you to specify additional options for the binary
1611
- * tree being created during the mapping process. These options could include things like custom
1612
- * comparators, initial
1613
- * @param {any} [thisArg] - The `thisArg` parameter in the `map` method is used to specify the value
1614
- * of `this` when executing the `callback` function. It allows you to set the context (value of
1615
- * `this`) within the callback function. If `thisArg` is provided, it will be passed
1616
- * @returns The `map` function is returning a new `BinaryTree` instance filled with entries that are
1617
- * the result of applying the provided `callback` function to each entry in the original tree.
1618
- */
1619
- map(callback, options, thisArg) {
1620
- const newTree = new BinaryTree([], options);
1621
- let index = 0;
1622
- for (const [key, value] of this) {
1623
- newTree.add(callback.call(thisArg, key, value, index++, this));
1624
- }
1625
- return newTree;
1626
- }
1627
- /**
1628
- * Time Complexity: O(n)
1629
- * Space Complexity: O(n)
1630
- *
1631
- * The function `toVisual` in TypeScript overrides the visual representation of a binary tree with
1632
- * customizable options for displaying undefined, null, and sentinel nodes.
1633
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the
1634
- * `toVisual` method is used to specify the starting point for visualizing the binary tree structure.
1635
- * It can be a node, key, entry, or the root of the tree. If no specific starting point is provided,
1636
- * the default is set to the root
1637
- * @param {BinaryTreePrintOptions} [options] - The `options` parameter in the `toVisual` method is an
1638
- * object that contains the following properties:
1639
- * @returns The `override toVisual` method returns a string that represents the visual display of the
1640
- * binary tree based on the provided options for showing undefined, null, and Red-Black NIL nodes.
1641
- * The method constructs the visual representation by calling the `_displayAux` method and appending
1642
- * the lines to the output string. The final output string contains the visual representation of the
1643
- * binary tree with the specified options.
1389
+ const out = this._createInstance();
1390
+ let i = 0;
1391
+ for (const [k, v] of this)
1392
+ if (predicate.call(thisArg, k, v, i++, this))
1393
+ out.add([k, v]);
1394
+ return out;
1395
+ }
1396
+ /**
1397
+ * Creates a new tree by mapping each [key, value] pair to a new entry.
1398
+ * @remarks Time O(N * M), where N is nodes in this tree, and M is size of the new tree during insertion. Space O(N) for the new tree.
1399
+ *
1400
+ * @template MK - New key type.
1401
+ * @template MV - New value type.
1402
+ * @template MR - New raw type.
1403
+ * @param cb - A function to map each [key, value] pair.
1404
+ * @param [options] - Options for the new tree.
1405
+ * @param [thisArg] - `this` context for the callback.
1406
+ * @returns A new, mapped tree.
1407
+ */
1408
+ map(cb, options, thisArg) {
1409
+ const out = this._createLike([], options);
1410
+ let i = 0;
1411
+ for (const [k, v] of this)
1412
+ out.add(cb.call(thisArg, k, v, i++, this));
1413
+ return out;
1414
+ }
1415
+ /**
1416
+ * Generates a string representation of the tree for visualization.
1417
+ * @remarks Time O(N), visits every node. Space O(N*H) or O(N^2) in the worst case, as the string width can grow significantly.
1418
+ *
1419
+ * @param [startNode=this._root] - The node to start printing from.
1420
+ * @param [options] - Options to control the output (e.g., show nulls).
1421
+ * @returns The string representation of the tree.
1644
1422
  */
1645
1423
  toVisual(startNode = this._root, options) {
1646
1424
  const opts = Object.assign({ isShowUndefined: false, isShowNull: true, isShowRedBlackNIL: false }, options);
@@ -1666,117 +1444,31 @@ class BinaryTree extends base_1.IterableEntryBase {
1666
1444
  return output;
1667
1445
  }
1668
1446
  /**
1669
- * Time Complexity: O(n)
1670
- * Space Complexity: O(n)
1447
+ * Prints a visual representation of the tree to the console.
1448
+ * @remarks Time O(N) (via `toVisual`). Space O(N*H) or O(N^2) (via `toVisual`).
1671
1449
  *
1672
- * The function `print` in TypeScript overrides the default print behavior to log a visual
1673
- * representation of the binary tree to the console.
1674
- * @param {BinaryTreePrintOptions} [options] - The `options` parameter is used to specify the
1675
- * printing options for the binary tree. It is an optional parameter that allows you to customize how
1676
- * the binary tree is printed, such as choosing between different traversal orders or formatting
1677
- * options.
1678
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the
1679
- * `override print` method is used to specify the starting point for printing the binary tree. It can
1680
- * be either a key, a node, an entry, or the root of the tree. If no specific starting point is
1681
- * provided, the default value is set to
1450
+ * @param [options] - Options to control the output.
1451
+ * @param [startNode=this._root] - The node to start printing from.
1682
1452
  */
1683
1453
  print(options, startNode = this._root) {
1684
1454
  console.log(this.toVisual(startNode, options));
1685
1455
  }
1686
- _clone(cloned) {
1687
- this.bfs(node => {
1688
- if (node === null)
1689
- cloned.add(null);
1690
- else {
1691
- if (this._isMapMode)
1692
- cloned.add([node.key, this._store.get(node.key)]);
1693
- else
1694
- cloned.add([node.key, node.value]);
1695
- }
1696
- }, this._root, this.iterationType, true);
1697
- if (this._isMapMode)
1698
- cloned._store = this._store;
1699
- }
1700
1456
  /**
1701
- * Time Complexity: O(1)
1702
- * Space Complexity: O(1)
1457
+ * (Protected) Core DFS implementation.
1458
+ * @remarks Time O(N), visits every node satisfying predicates. Space O(H) for call/explicit stack. O(N) worst-case.
1703
1459
  *
1704
- * The function `keyValueNodeEntryRawToNodeAndValue` converts various input types into a node object
1705
- * or returns null.
1706
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The
1707
- * `keyValueNodeEntryRawToNodeAndValue` function takes in a parameter `keyNodeOrEntry`, which
1708
- * can be of type `K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined ` or `R`. This parameter represents either a key, a
1709
- * node, an entry
1710
- * @param {V} [value] - The `value` parameter in the `keyValueNodeEntryRawToNodeAndValue` function is
1711
- * an optional parameter of type `V`. It represents the value associated with the key in the node
1712
- * being created. If a `value` is provided, it will be used when creating the node. If
1713
- * @returns The `keyValueNodeEntryRawToNodeAndValue` function returns an optional node
1714
- * (`BinaryTreeNode<K, V> | null | undefined`) based on the input parameters provided. The function checks the type of the
1715
- * input parameter (`keyNodeOrEntry`) and processes it accordingly to return a node or null
1716
- * value.
1717
- */
1718
- _keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value) {
1719
- if (keyNodeOrEntry === undefined)
1720
- return [undefined, undefined];
1721
- if (keyNodeOrEntry === null)
1722
- return [null, undefined];
1723
- if (this.isNode(keyNodeOrEntry))
1724
- return [keyNodeOrEntry, value];
1725
- if (this.isEntry(keyNodeOrEntry)) {
1726
- const [key, entryValue] = keyNodeOrEntry;
1727
- if (key === undefined)
1728
- return [undefined, undefined];
1729
- else if (key === null)
1730
- return [null, undefined];
1731
- const finalValue = value !== null && value !== void 0 ? value : entryValue;
1732
- return [this.createNode(key, finalValue), finalValue];
1733
- }
1734
- return [this.createNode(keyNodeOrEntry, value), value];
1735
- }
1736
- /**
1737
- * Time complexity: O(n)
1738
- * Space complexity: O(n)
1739
- *
1740
- * The `_dfs` function performs a depth-first search traversal on a binary tree, with customizable
1741
- * options for traversal order and node processing.
1742
- * @param {C} callback - The `callback` parameter in the `_dfs` method is a function that will be
1743
- * called on each node visited during the depth-first search traversal. It is a generic type `C` that
1744
- * extends `NodeCallback<BinaryTreeNode<K, V> | null>`. The default value for `callback`
1745
- * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `_dfs` method specifies the
1746
- * order in which the nodes are visited during a depth-first search traversal. It can have one of the
1747
- * following values:
1748
- * @param {boolean} [onlyOne=false] - The `onlyOne` parameter in the `_dfs` method is a boolean flag
1749
- * that determines whether the traversal should stop after processing a single node. If `onlyOne` is
1750
- * set to `true`, the traversal will return as soon as a single node is processed. If it is set to
1751
- * `false
1752
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined}
1753
- * startNode - The `startNode` parameter in the `_dfs` method is used to specify the starting node
1754
- * for the depth-first search traversal. It can be provided in different forms:
1755
- * @param {IterationType} iterationType - The `iterationType` parameter in the `_dfs` method
1756
- * specifies whether the traversal should be done recursively or iteratively. It can have two
1757
- * possible values:
1758
- * @param [includeNull=false] - The `includeNull` parameter in the `_dfs` method determines whether
1759
- * null nodes should be included in the traversal process. If `includeNull` is set to `true`, the
1760
- * method will consider null nodes as valid nodes to visit or process. If `includeNull` is set to
1761
- * `false`,
1762
- * @param shouldVisitLeft - The `shouldVisitLeft` parameter in the `_dfs` method is a function that
1763
- * determines whether the left child of a node should be visited during the Depth-First Search
1764
- * traversal. By default, it checks if the node is not null or undefined before visiting the left
1765
- * child. You can customize this behavior
1766
- * @param shouldVisitRight - The `shouldVisitRight` parameter in the `_dfs` method is a function that
1767
- * determines whether to visit the right child node of the current node during a depth-first search
1768
- * traversal. The default implementation of this function checks if the node is not null or undefined
1769
- * before deciding to visit it.
1770
- * @param shouldVisitRoot - The `shouldVisitRoot` parameter in the `_dfs` method is a function that
1771
- * determines whether a given node should be visited during the depth-first search traversal. The
1772
- * function takes a node as an argument and returns a boolean value indicating whether the node
1773
- * should be visited.
1774
- * @param shouldProcessRoot - The `shouldProcessRoot` parameter in the `_dfs` method is a function
1775
- * that determines whether the root node should be processed during the Depth-First Search traversal.
1776
- * It takes a node (BinaryTreeNode<K, V> | null | undefined) as input and returns a boolean value. If
1777
- * the function
1778
- * @returns The `_dfs` method returns an array of the return type of the provided callback function
1779
- * `C`.
1460
+ * @template C - Callback type.
1461
+ * @param [callback=this._DEFAULT_NODE_CALLBACK] - Function to call on nodes.
1462
+ * @param [pattern='IN'] - Traversal order.
1463
+ * @param [onlyOne=false] - Stop after first match.
1464
+ * @param [startNode=this._root] - Starting node.
1465
+ * @param [iterationType=this.iterationType] - Traversal method.
1466
+ * @param [includeNull=false] - Include nulls.
1467
+ * @param [shouldVisitLeft] - Predicate to traverse left.
1468
+ * @param [shouldVisitRight] - Predicate to traverse right.
1469
+ * @param [shouldVisitRoot] - Predicate to visit root.
1470
+ * @param [shouldProcessRoot] - Predicate to process root.
1471
+ * @returns Array of callback results.
1780
1472
  */
1781
1473
  _dfs(callback = this._DEFAULT_NODE_CALLBACK, pattern = 'IN', onlyOne = false, startNode = this._root, iterationType = this.iterationType, includeNull = false, shouldVisitLeft = node => !!node, shouldVisitRight = node => !!node, shouldVisitRoot = node => {
1782
1474
  if (includeNull)
@@ -1832,6 +1524,7 @@ class BinaryTree extends base_1.IterableEntryBase {
1832
1524
  dfs(startNode);
1833
1525
  }
1834
1526
  else {
1527
+ // Iterative
1835
1528
  const stack = [{ opt: common_1.DFSOperation.VISIT, node: startNode }];
1836
1529
  const pushLeft = (cur) => {
1837
1530
  var _a;
@@ -1861,6 +1554,7 @@ class BinaryTree extends base_1.IterableEntryBase {
1861
1554
  }
1862
1555
  }
1863
1556
  else {
1557
+ // VISIT
1864
1558
  switch (pattern) {
1865
1559
  case 'IN':
1866
1560
  pushRight(cur);
@@ -1884,19 +1578,11 @@ class BinaryTree extends base_1.IterableEntryBase {
1884
1578
  return ans;
1885
1579
  }
1886
1580
  /**
1887
- * Time Complexity: O(1)
1888
- * Space Complexity: O(1)
1581
+ * (Protected) Gets the iterator for the tree (default in-order).
1582
+ * @remarks Time O(N) for full iteration. O(H) to get the first element. Space O(H) for the iterative stack. O(H) for recursive stack.
1889
1583
  *
1890
- * The function `_getIterator` returns an iterable iterator for a binary tree data structure, either
1891
- * using an iterative approach or a recursive approach based on the specified iteration type.
1892
- * @param node - The `node` parameter in the `_getIterator` method represents the current node being
1893
- * processed during iteration. It is initially set to the root node of the data structure (or the
1894
- * node passed as an argument), and then it is traversed through the data structure based on the
1895
- * iteration type specified (`ITER
1896
- * @returns The `_getIterator` method returns an IterableIterator containing key-value pairs of nodes
1897
- * in a binary tree structure. The method uses an iterative approach to traverse the tree based on
1898
- * the `iterationType` property. If the `iterationType` is set to 'ITERATIVE', the method uses a
1899
- * stack to perform an in-order traversal of the tree. If the `iterationType` is not 'ITERATIVE
1584
+ * @param [node=this._root] - The node to start iteration from.
1585
+ * @returns An iterator for [key, value] pairs.
1900
1586
  */
1901
1587
  *_getIterator(node = this._root) {
1902
1588
  if (!node)
@@ -1905,21 +1591,25 @@ class BinaryTree extends base_1.IterableEntryBase {
1905
1591
  const stack = [];
1906
1592
  let current = node;
1907
1593
  while (current || stack.length > 0) {
1594
+ // Go to the leftmost node
1908
1595
  while (this.isRealNode(current)) {
1909
1596
  stack.push(current);
1910
1597
  current = current.left;
1911
1598
  }
1599
+ // Visit the node
1912
1600
  current = stack.pop();
1913
1601
  if (this.isRealNode(current)) {
1914
1602
  if (this._isMapMode)
1915
1603
  yield [current.key, this._store.get(current.key)];
1916
1604
  else
1917
1605
  yield [current.key, current.value];
1606
+ // Move to the right subtree
1918
1607
  current = current.right;
1919
1608
  }
1920
1609
  }
1921
1610
  }
1922
1611
  else {
1612
+ // Recursive in-order traversal
1923
1613
  if (node.left && this.isRealNode(node)) {
1924
1614
  yield* this[Symbol.iterator](node.left);
1925
1615
  }
@@ -1933,24 +1623,104 @@ class BinaryTree extends base_1.IterableEntryBase {
1933
1623
  }
1934
1624
  }
1935
1625
  /**
1936
- * Time Complexity: O(n)
1937
- * Space Complexity: O(n)
1626
+ * (Protected) Snapshots the current tree's configuration options.
1627
+ * @remarks Time O(1)
1628
+ *
1629
+ * @template TK, TV, TR - Generic types for the options.
1630
+ * @returns The options object.
1631
+ */
1632
+ _snapshotOptions() {
1633
+ return {
1634
+ iterationType: this.iterationType,
1635
+ toEntryFn: this.toEntryFn,
1636
+ isMapMode: this.isMapMode,
1637
+ isDuplicate: this.isDuplicate
1638
+ };
1639
+ }
1640
+ /**
1641
+ * (Protected) Creates a new, empty instance of the same tree constructor.
1642
+ * @remarks Time O(1)
1938
1643
  *
1939
- * The function `_displayAux` in TypeScript is responsible for generating the display layout of nodes
1940
- * in a binary tree based on specified options.
1941
- * @param node - The `node` parameter in the `_displayAux` function represents a node in a binary
1942
- * tree. It can be either a valid node containing a key or a special type of node like null,
1943
- * undefined, or a Red-Black tree NIL node. The function checks the type of the node and its
1944
- * @param {BinaryTreePrintOptions} options - The `options` parameter in the `_displayAux` function
1945
- * contains the following properties:
1946
- * @returns The `_displayAux` function returns a `NodeDisplayLayout`, which is an array containing
1947
- * information about how to display a node in a binary tree. The `NodeDisplayLayout` consists of four
1948
- * elements:
1644
+ * @template TK, TV, TR - Generic types for the new instance.
1645
+ * @param [options] - Options for the new tree.
1646
+ * @returns A new, empty tree.
1647
+ */
1648
+ _createInstance(options) {
1649
+ const Ctor = this.constructor;
1650
+ return new Ctor([], Object.assign(Object.assign({}, this._snapshotOptions()), (options !== null && options !== void 0 ? options : {})));
1651
+ }
1652
+ /**
1653
+ * (Protected) Creates a new instance of the same tree constructor, potentially with different generic types.
1654
+ * @remarks Time O(N) (or as per constructor) due to processing the iterable.
1655
+ *
1656
+ * @template TK, TV, TR - Generic types for the new instance.
1657
+ * @param [iter=[]] - An iterable to populate the new tree.
1658
+ * @param [options] - Options for the new tree.
1659
+ * @returns A new tree.
1660
+ */
1661
+ _createLike(iter = [], options) {
1662
+ const Ctor = this.constructor;
1663
+ return new Ctor(iter, Object.assign(Object.assign({}, this._snapshotOptions()), (options !== null && options !== void 0 ? options : {})));
1664
+ }
1665
+ /**
1666
+ * (Protected) Converts a key, node, or entry into a standardized [node, value] tuple.
1667
+ * @remarks Time O(1)
1668
+ *
1669
+ * @param keyNodeOrEntry - The input item.
1670
+ * @param [value] - An optional value (used if input is just a key).
1671
+ * @returns A tuple of [node, value].
1672
+ */
1673
+ _keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value) {
1674
+ if (keyNodeOrEntry === undefined)
1675
+ return [undefined, undefined];
1676
+ if (keyNodeOrEntry === null)
1677
+ return [null, undefined];
1678
+ if (this.isNode(keyNodeOrEntry))
1679
+ return [keyNodeOrEntry, value];
1680
+ if (this.isEntry(keyNodeOrEntry)) {
1681
+ const [key, entryValue] = keyNodeOrEntry;
1682
+ if (key === undefined)
1683
+ return [undefined, undefined];
1684
+ else if (key === null)
1685
+ return [null, undefined];
1686
+ const finalValue = value !== null && value !== void 0 ? value : entryValue;
1687
+ return [this._createNode(key, finalValue), finalValue];
1688
+ }
1689
+ return [this._createNode(keyNodeOrEntry, value), value];
1690
+ }
1691
+ /**
1692
+ * (Protected) Helper for cloning. Performs a BFS and adds all nodes to the new tree.
1693
+ * @remarks Time O(N * M) (O(N) BFS + O(M) `add` for each node).
1694
+ *
1695
+ * @param cloned - The new, empty tree instance to populate.
1696
+ */
1697
+ _clone(cloned) {
1698
+ // Use BFS with nulls to preserve the tree structure
1699
+ this.bfs(node => {
1700
+ if (node === null)
1701
+ cloned.add(null);
1702
+ else {
1703
+ if (this._isMapMode)
1704
+ cloned.add([node.key, this._store.get(node.key)]);
1705
+ else
1706
+ cloned.add([node.key, node.value]);
1707
+ }
1708
+ }, this._root, this.iterationType, true // Include nulls
1709
+ );
1710
+ if (this._isMapMode)
1711
+ cloned._store = this._store;
1712
+ }
1713
+ /**
1714
+ * (Protected) Recursive helper for `toVisual`.
1715
+ * @remarks Time O(N), Space O(N*H) or O(N^2)
1716
+ *
1717
+ * @param node - The current node.
1718
+ * @param options - Print options.
1719
+ * @returns Layout information for this subtree.
1949
1720
  */
1950
1721
  _displayAux(node, options) {
1951
1722
  const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
1952
- const emptyDisplayLayout = [['─'], 1, 0, 0];
1953
- // Check if node is null or undefined or key is NaN
1723
+ const emptyDisplayLayout = [['─'], 1, 0, 0]; // Represents an empty spot
1954
1724
  if (node === null && !isShowNull) {
1955
1725
  return emptyDisplayLayout;
1956
1726
  }
@@ -1961,15 +1731,20 @@ class BinaryTree extends base_1.IterableEntryBase {
1961
1731
  return emptyDisplayLayout;
1962
1732
  }
1963
1733
  else if (node !== null && node !== undefined) {
1964
- // Display logic of normal nodes
1734
+ // Real node
1965
1735
  const key = node.key, line = this.isNIL(node) ? 'S' : String(key), width = line.length;
1966
1736
  return _buildNodeDisplay(line, width, this._displayAux(node.left, options), this._displayAux(node.right, options));
1967
1737
  }
1968
1738
  else {
1969
- // For cases where none of the conditions are met, null, undefined, and NaN nodes are not displayed
1739
+ // Null or Undefined
1970
1740
  const line = node === undefined ? 'U' : 'N', width = line.length;
1741
+ // Treat as a leaf
1971
1742
  return _buildNodeDisplay(line, width, [[''], 1, 0, 0], [[''], 1, 0, 0]);
1972
1743
  }
1744
+ /**
1745
+ * (Inner) Builds the display lines for a node.
1746
+ * @remarks Time/Space: Proportional to the width and height of the subtrees.
1747
+ */
1973
1748
  function _buildNodeDisplay(line, width, left, right) {
1974
1749
  const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
1975
1750
  const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
@@ -2000,30 +1775,25 @@ class BinaryTree extends base_1.IterableEntryBase {
2000
1775
  }
2001
1776
  }
2002
1777
  /**
2003
- * Time Complexity: O(1)
2004
- * Space Complexity: O(1)
1778
+ * (Protected) Swaps the key/value properties of two nodes.
1779
+ * @remarks Time O(1)
2005
1780
  *
2006
- * The _swapProperties function swaps key and value properties between two nodes in a binary tree.
2007
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } srcNode - The `srcNode` parameter in the
2008
- * `_swapProperties` method can be either a BTNRep object containing key and value
2009
- * properties, or it can be of type R.
2010
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } destNode - The `destNode` parameter in the
2011
- * `_swapProperties` method represents the node or entry where the properties will be swapped with
2012
- * the `srcNode`. It can be of type `K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined ` or `R`. The method ensures that
2013
- * both `srcNode
2014
- * @returns The `_swapProperties` method returns either the `destNode` with its key and value swapped
2015
- * with the `srcNode`, or `undefined` if either `srcNode` or `destNode` is falsy.
1781
+ * @param srcNode - The source node.
1782
+ * @param destNode - The destination node.
1783
+ * @returns The `destNode` (now holding `srcNode`'s properties).
2016
1784
  */
2017
1785
  _swapProperties(srcNode, destNode) {
2018
1786
  srcNode = this.ensureNode(srcNode);
2019
1787
  destNode = this.ensureNode(destNode);
2020
1788
  if (srcNode && destNode) {
2021
1789
  const { key, value } = destNode;
2022
- const tempNode = this.createNode(key, value);
1790
+ const tempNode = this._createNode(key, value); // Use a temp node to hold dest properties
2023
1791
  if (tempNode) {
1792
+ // Copy src to dest
2024
1793
  destNode.key = srcNode.key;
2025
1794
  if (!this._isMapMode)
2026
1795
  destNode.value = srcNode.value;
1796
+ // Copy temp (original dest) to src
2027
1797
  srcNode.key = tempNode.key;
2028
1798
  if (!this._isMapMode)
2029
1799
  srcNode.value = tempNode.value;
@@ -2033,18 +1803,12 @@ class BinaryTree extends base_1.IterableEntryBase {
2033
1803
  return undefined;
2034
1804
  }
2035
1805
  /**
2036
- * Time Complexity: O(1)
2037
- * Space Complexity: O(1)
1806
+ * (Protected) Replaces a node in the tree with a new node, maintaining children and parent links.
1807
+ * @remarks Time O(1)
2038
1808
  *
2039
- * The _replaceNode function replaces an old node with a new node in a binary tree structure.
2040
- * @param {BinaryTreeNode<K, V>} oldNode - The `oldNode` parameter represents the node that you want to replace in a
2041
- * tree data structure.
2042
- * @param {BinaryTreeNode<K, V>} newNode - The `newNode` parameter in the `_replaceNode` function represents the node
2043
- * that will replace the `oldNode` in a tree data structure. This function is responsible for
2044
- * updating the parent, left child, right child, and root (if necessary) references when replacing a
2045
- * node in the tree.
2046
- * @returns The method `_replaceNode` is returning the `newNode` that was passed as a parameter after
2047
- * replacing the `oldNode` with it in the binary tree structure.
1809
+ * @param oldNode - The node to be replaced.
1810
+ * @param newNode - The node to insert.
1811
+ * @returns The `newNode`.
2048
1812
  */
2049
1813
  _replaceNode(oldNode, newNode) {
2050
1814
  if (oldNode.parent) {
@@ -2064,13 +1828,10 @@ class BinaryTree extends base_1.IterableEntryBase {
2064
1828
  return newNode;
2065
1829
  }
2066
1830
  /**
2067
- * Time Complexity: O(1)
2068
- * Space Complexity: O(1)
1831
+ * (Protected) Sets the root node and clears its parent reference.
1832
+ * @remarks Time O(1)
2069
1833
  *
2070
- * The function _setRoot sets the root node of a data structure while updating the parent reference
2071
- * of the previous root node.
2072
- * @param v - The parameter `v` in the `_setRoot` method is of type `BinaryTreeNode<K, V> | null | undefined`, which means
2073
- * it can either be an optional `BinaryTreeNode<K, V>` type or `null`.
1834
+ * @param v - The node to set as root.
2074
1835
  */
2075
1836
  _setRoot(v) {
2076
1837
  if (v) {
@@ -2078,18 +1839,6 @@ class BinaryTree extends base_1.IterableEntryBase {
2078
1839
  }
2079
1840
  this._root = v;
2080
1841
  }
2081
- /**
2082
- * Time Complexity: O(1)
2083
- * Space Complexity: O(1)
2084
- *
2085
- * The function `_ensurePredicate` in TypeScript ensures that the input is converted into a valid
2086
- * predicate function for a binary tree node.
2087
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate - The
2088
- * `_ensurePredicate` method in the provided code snippet is responsible for ensuring that the input
2089
- * parameter `keyNodeEntryOrPredicate` is transformed into a valid predicate function that can be
2090
- * used for filtering nodes in a binary tree.
2091
- * @returns A NodePredicate<BinaryTreeNode<K, V>> function is being returned.
2092
- */
2093
1842
  _ensurePredicate(keyNodeEntryOrPredicate) {
2094
1843
  if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === undefined)
2095
1844
  return (node) => (node ? false : false);
@@ -2105,6 +1854,7 @@ class BinaryTree extends base_1.IterableEntryBase {
2105
1854
  return node.key === key;
2106
1855
  };
2107
1856
  }
1857
+ // Assume it's a key
2108
1858
  return (node) => {
2109
1859
  if (!node)
2110
1860
  return false;
@@ -2112,32 +1862,21 @@ class BinaryTree extends base_1.IterableEntryBase {
2112
1862
  };
2113
1863
  }
2114
1864
  /**
2115
- * Time Complexity: O(1)
2116
- * Space Complexity: O(1)
1865
+ * (Protected) Checks if an item is a predicate function.
1866
+ * @remarks Time O(1)
2117
1867
  *
2118
- * The function `_isPredicate` checks if a given parameter is a function.
2119
- * @param {any} p - The parameter `p` is a variable of type `any`, which means it can hold any type
2120
- * of value. In this context, the function `_isPredicate` is checking if `p` is a function that
2121
- * satisfies the type `NodePredicate<BinaryTreeNode<K, V>>`.
2122
- * @returns The function is checking if the input `p` is a function and returning a boolean value
2123
- * based on that check. If `p` is a function, it will return `true`, indicating that `p` is a
2124
- * predicate function for a binary tree node. If `p` is not a function, it will return `false`.
1868
+ * @param p - The item to check.
1869
+ * @returns True if it's a function.
2125
1870
  */
2126
1871
  _isPredicate(p) {
2127
1872
  return typeof p === 'function';
2128
1873
  }
2129
1874
  /**
2130
- * Time Complexity: O(1)
2131
- * Space Complexity: O(1)
1875
+ * (Protected) Extracts the key from a key, node, or entry.
1876
+ * @remarks Time O(1)
2132
1877
  *
2133
- * The function `_extractKey` in TypeScript returns the key from a given input, which can be a node,
2134
- * entry, raw data, or null/undefined.
2135
- * @param {K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The `_extractKey` method you provided is a
2136
- * TypeScript method that takes in a parameter `keyNodeOrEntry` of type `K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined `,
2137
- * where `BTNRep` is a generic type with keys `K`, `V`, and `BinaryTreeNode<K, V>`, and `
2138
- * @returns The `_extractKey` method returns the key value extracted from the `keyNodeOrEntry`
2139
- * parameter. The return value can be a key value of type `K`, `null`, or `undefined`, depending on
2140
- * the conditions checked in the method.
1878
+ * @param keyNodeOrEntry - The item.
1879
+ * @returns The extracted key.
2141
1880
  */
2142
1881
  _extractKey(keyNodeOrEntry) {
2143
1882
  if (keyNodeOrEntry === null)
@@ -2153,41 +1892,31 @@ class BinaryTree extends base_1.IterableEntryBase {
2153
1892
  return keyNodeOrEntry;
2154
1893
  }
2155
1894
  /**
2156
- * Time Complexity: O(1)
2157
- * Space Complexity: O(1)
1895
+ * (Protected) Sets a value in the external store (Map mode).
1896
+ * @remarks Time O(1) (average for Map.set).
2158
1897
  *
2159
- * The function `_setValue` sets a value in a store based on a key, handling cases where the key or
2160
- * value is null or undefined.
2161
- * @param {K | null | undefined} key - The `key` parameter can be of type `K`, `null`, or
2162
- * `undefined`.
2163
- * @param {V | undefined} value - The `value` parameter in the `_setValue` method can be of type `V`
2164
- * or `undefined`.
2165
- * @returns The method `_setValue` returns `false` if either the `key` is `null` or `undefined`, or
2166
- * if the `value` is `undefined`. Otherwise, it returns the result of calling the `set` method on the
2167
- * `_store` object with the `key` and `value` arguments.
1898
+ * @param key - The key.
1899
+ * @param value - The value.
1900
+ * @returns True if successful.
2168
1901
  */
2169
1902
  _setValue(key, value) {
2170
1903
  if (key === null || key === undefined)
2171
1904
  return false;
2172
1905
  if (value === undefined)
2173
- return false;
1906
+ return false; // Or allow setting undefined?
2174
1907
  return this._store.set(key, value);
2175
1908
  }
2176
1909
  /**
2177
- * Time Complexity: O(1)
2178
- * Space Complexity: O(1)
2179
- *
2180
- * The _clearNodes function sets the root node to undefined and resets the size to 0.
1910
+ * (Protected) Clears all nodes from the tree.
1911
+ * @remarks Time O(1)
2181
1912
  */
2182
1913
  _clearNodes() {
2183
1914
  this._setRoot(undefined);
2184
1915
  this._size = 0;
2185
1916
  }
2186
1917
  /**
2187
- * Time Complexity: O(1)
2188
- * Space Complexity: O(1)
2189
- *
2190
- * The _clearValues function clears all values stored in the _store object.
1918
+ * (Protected) Clears all values from the external store.
1919
+ * @remarks Time O(N)
2191
1920
  */
2192
1921
  _clearValues() {
2193
1922
  this._store.clear();