heap-typed 1.52.8 → 1.53.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.
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +22 -22
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +64 -47
- package/dist/data-structures/binary-tree/avl-tree.d.ts +20 -20
- package/dist/data-structures/binary-tree/avl-tree.js +28 -26
- package/dist/data-structures/binary-tree/binary-tree.d.ts +240 -141
- package/dist/data-structures/binary-tree/binary-tree.js +395 -269
- package/dist/data-structures/binary-tree/bst.d.ts +56 -56
- package/dist/data-structures/binary-tree/bst.js +114 -91
- package/dist/data-structures/binary-tree/rb-tree.d.ts +13 -13
- package/dist/data-structures/binary-tree/rb-tree.js +35 -31
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +22 -23
- package/dist/data-structures/binary-tree/tree-multi-map.js +59 -48
- package/dist/data-structures/trie/trie.js +3 -3
- package/dist/interfaces/binary-tree.d.ts +5 -5
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +13 -13
- package/dist/types/data-structures/binary-tree/bst.d.ts +3 -3
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +60 -55
- package/src/data-structures/binary-tree/avl-tree.ts +31 -35
- package/src/data-structures/binary-tree/binary-tree.ts +461 -385
- package/src/data-structures/binary-tree/bst.ts +155 -128
- package/src/data-structures/binary-tree/rb-tree.ts +37 -39
- package/src/data-structures/binary-tree/tree-multi-map.ts +57 -60
- package/src/data-structures/trie/trie.ts +3 -3
- package/src/interfaces/binary-tree.ts +6 -6
- package/src/types/data-structures/binary-tree/binary-tree.ts +14 -15
- package/src/types/data-structures/binary-tree/bst.ts +4 -4
|
@@ -66,29 +66,39 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
66
66
|
/**
|
|
67
67
|
* The constructor initializes a binary tree with optional options and adds keys, nodes, entries, or
|
|
68
68
|
* raw data if provided.
|
|
69
|
-
* @param
|
|
70
|
-
* is an iterable that can contain elements of type `
|
|
69
|
+
* @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the constructor
|
|
70
|
+
* is an iterable that can contain elements of type `BTNRep<K, V, NODE>` or `R`. It is
|
|
71
71
|
* initialized with an empty array `[]` by default.
|
|
72
72
|
* @param [options] - The `options` parameter in the constructor is an object that can contain the
|
|
73
73
|
* following properties:
|
|
74
74
|
*/
|
|
75
|
-
constructor(
|
|
75
|
+
constructor(keysNodesEntriesOrRaws = [], options) {
|
|
76
76
|
super();
|
|
77
77
|
this.iterationType = 'ITERATIVE';
|
|
78
|
+
this._isMapMode = false;
|
|
79
|
+
this._store = new Map();
|
|
78
80
|
this._size = 0;
|
|
79
81
|
this._NIL = new BinaryTreeNode(NaN);
|
|
80
|
-
this.
|
|
82
|
+
this._DEFAULT_NODE_CALLBACK = (node) => (node ? node.key : undefined);
|
|
81
83
|
if (options) {
|
|
82
|
-
const { iterationType, toEntryFn } = options;
|
|
84
|
+
const { iterationType, toEntryFn, isMapMode } = options;
|
|
83
85
|
if (iterationType)
|
|
84
86
|
this.iterationType = iterationType;
|
|
87
|
+
if (isMapMode !== undefined)
|
|
88
|
+
this._isMapMode = isMapMode;
|
|
85
89
|
if (typeof toEntryFn === 'function')
|
|
86
90
|
this._toEntryFn = toEntryFn;
|
|
87
91
|
else if (toEntryFn)
|
|
88
92
|
throw TypeError('toEntryFn must be a function type');
|
|
89
93
|
}
|
|
90
|
-
if (
|
|
91
|
-
this.addMany(
|
|
94
|
+
if (keysNodesEntriesOrRaws)
|
|
95
|
+
this.addMany(keysNodesEntriesOrRaws);
|
|
96
|
+
}
|
|
97
|
+
get isMapMode() {
|
|
98
|
+
return this._isMapMode;
|
|
99
|
+
}
|
|
100
|
+
get store() {
|
|
101
|
+
return this._store;
|
|
92
102
|
}
|
|
93
103
|
get root() {
|
|
94
104
|
return this._root;
|
|
@@ -123,49 +133,51 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
123
133
|
* @returns A new instance of a binary tree with the specified options is being returned.
|
|
124
134
|
*/
|
|
125
135
|
createTree(options) {
|
|
126
|
-
return new BinaryTree([], Object.assign({ iterationType: this.iterationType, toEntryFn: this._toEntryFn }, options));
|
|
136
|
+
return new BinaryTree([], Object.assign({ iterationType: this.iterationType, isMapMode: this._isMapMode, toEntryFn: this._toEntryFn }, options));
|
|
127
137
|
}
|
|
128
138
|
/**
|
|
129
|
-
* The function `
|
|
139
|
+
* The function `keyValueNodeEntryRawToNodeAndValue` converts various input types into a node object
|
|
130
140
|
* or returns null.
|
|
131
|
-
* @param {
|
|
132
|
-
* `
|
|
133
|
-
* can be of type `
|
|
141
|
+
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The
|
|
142
|
+
* `keyValueNodeEntryRawToNodeAndValue` function takes in a parameter `keyNodeEntryOrRaw`, which
|
|
143
|
+
* can be of type `BTNRep<K, V, NODE>` or `R`. This parameter represents either a key, a
|
|
134
144
|
* node, an entry
|
|
135
|
-
* @param {V} [value] - The `value` parameter in the `
|
|
145
|
+
* @param {V} [value] - The `value` parameter in the `keyValueNodeEntryRawToNodeAndValue` function is
|
|
136
146
|
* an optional parameter of type `V`. It represents the value associated with the key in the node
|
|
137
147
|
* being created. If a `value` is provided, it will be used when creating the node. If
|
|
138
|
-
* @returns The `
|
|
139
|
-
* (`
|
|
140
|
-
* input parameter (`
|
|
148
|
+
* @returns The `keyValueNodeEntryRawToNodeAndValue` function returns an optional node
|
|
149
|
+
* (`OptNodeOrNull<NODE>`) based on the input parameters provided. The function checks the type of the
|
|
150
|
+
* input parameter (`keyNodeEntryOrRaw`) and processes it accordingly to return a node or null
|
|
141
151
|
* value.
|
|
142
152
|
*/
|
|
143
|
-
|
|
144
|
-
if (
|
|
145
|
-
return;
|
|
146
|
-
if (
|
|
147
|
-
return null;
|
|
148
|
-
if (this.isNode(
|
|
149
|
-
return
|
|
150
|
-
if (this.isEntry(
|
|
151
|
-
const [key, entryValue] =
|
|
153
|
+
keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value) {
|
|
154
|
+
if (keyNodeEntryOrRaw === undefined)
|
|
155
|
+
return [undefined, undefined];
|
|
156
|
+
if (keyNodeEntryOrRaw === null)
|
|
157
|
+
return [null, undefined];
|
|
158
|
+
if (this.isNode(keyNodeEntryOrRaw))
|
|
159
|
+
return [keyNodeEntryOrRaw, value];
|
|
160
|
+
if (this.isEntry(keyNodeEntryOrRaw)) {
|
|
161
|
+
const [key, entryValue] = keyNodeEntryOrRaw;
|
|
152
162
|
if (key === undefined)
|
|
153
|
-
return;
|
|
163
|
+
return [undefined, undefined];
|
|
154
164
|
else if (key === null)
|
|
155
|
-
return null;
|
|
156
|
-
|
|
157
|
-
|
|
165
|
+
return [null, undefined];
|
|
166
|
+
const finalValue = value !== null && value !== void 0 ? value : entryValue;
|
|
167
|
+
return [this.createNode(key, finalValue), finalValue];
|
|
158
168
|
}
|
|
159
|
-
if (this.
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
169
|
+
if (this.isKey(keyNodeEntryOrRaw))
|
|
170
|
+
return [this.createNode(keyNodeEntryOrRaw, value), value];
|
|
171
|
+
if (this.isRaw(keyNodeEntryOrRaw)) {
|
|
172
|
+
if (this._toEntryFn) {
|
|
173
|
+
const [key, entryValue] = this._toEntryFn(keyNodeEntryOrRaw);
|
|
174
|
+
const finalValue = value !== null && value !== void 0 ? value : entryValue;
|
|
175
|
+
if (this.isKey(key))
|
|
176
|
+
return [this.createNode(key, finalValue), finalValue];
|
|
177
|
+
}
|
|
178
|
+
return [undefined, undefined];
|
|
165
179
|
}
|
|
166
|
-
|
|
167
|
-
return this.createNode(keyOrNodeOrEntryOrRaw, value);
|
|
168
|
-
return;
|
|
180
|
+
return [undefined, undefined];
|
|
169
181
|
}
|
|
170
182
|
/**
|
|
171
183
|
* Time Complexity: O(n)
|
|
@@ -173,8 +185,8 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
173
185
|
*
|
|
174
186
|
* The function `ensureNode` in TypeScript checks if a given input is a node, entry, key, or raw
|
|
175
187
|
* value and returns the corresponding node or null.
|
|
176
|
-
* @param {
|
|
177
|
-
* parameter in the `ensureNode` function can be of type `
|
|
188
|
+
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The `keyNodeEntryOrRaw`
|
|
189
|
+
* parameter in the `ensureNode` function can be of type `BTNRep<K, V, NODE>` or `R`. It
|
|
178
190
|
* is used to determine whether the input is a key, node, entry, or raw data. The
|
|
179
191
|
* @param {IterationType} iterationType - The `iterationType` parameter in the `ensureNode` function
|
|
180
192
|
* is used to specify the type of iteration to be performed. It has a default value of
|
|
@@ -182,17 +194,17 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
182
194
|
* @returns The `ensureNode` function returns either a node, `null`, or `undefined` based on the
|
|
183
195
|
* conditions specified in the code snippet.
|
|
184
196
|
*/
|
|
185
|
-
ensureNode(
|
|
186
|
-
if (
|
|
197
|
+
ensureNode(keyNodeEntryOrRaw, iterationType = this.iterationType) {
|
|
198
|
+
if (keyNodeEntryOrRaw === null)
|
|
187
199
|
return null;
|
|
188
|
-
if (
|
|
200
|
+
if (keyNodeEntryOrRaw === undefined)
|
|
189
201
|
return;
|
|
190
|
-
if (
|
|
202
|
+
if (keyNodeEntryOrRaw === this._NIL)
|
|
191
203
|
return;
|
|
192
|
-
if (this.isNode(
|
|
193
|
-
return
|
|
194
|
-
if (this.isEntry(
|
|
195
|
-
const key =
|
|
204
|
+
if (this.isNode(keyNodeEntryOrRaw))
|
|
205
|
+
return keyNodeEntryOrRaw;
|
|
206
|
+
if (this.isEntry(keyNodeEntryOrRaw)) {
|
|
207
|
+
const key = keyNodeEntryOrRaw[0];
|
|
196
208
|
if (key === null)
|
|
197
209
|
return null;
|
|
198
210
|
if (key === undefined)
|
|
@@ -200,95 +212,98 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
200
212
|
return this.getNodeByKey(key, iterationType);
|
|
201
213
|
}
|
|
202
214
|
if (this._toEntryFn) {
|
|
203
|
-
const [key] = this._toEntryFn(
|
|
215
|
+
const [key] = this._toEntryFn(keyNodeEntryOrRaw);
|
|
204
216
|
if (this.isKey(key))
|
|
205
217
|
return this.getNodeByKey(key);
|
|
206
218
|
}
|
|
207
|
-
if (this.isKey(
|
|
208
|
-
return this.getNodeByKey(
|
|
219
|
+
if (this.isKey(keyNodeEntryOrRaw))
|
|
220
|
+
return this.getNodeByKey(keyNodeEntryOrRaw, iterationType);
|
|
209
221
|
return;
|
|
210
222
|
}
|
|
211
223
|
/**
|
|
212
224
|
* The function isNode checks if the input is an instance of BinaryTreeNode.
|
|
213
|
-
* @param {
|
|
214
|
-
* `
|
|
225
|
+
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The parameter
|
|
226
|
+
* `keyNodeEntryOrRaw` can be either a key, a node, an entry, or raw data. The function is
|
|
215
227
|
* checking if the input is an instance of a `BinaryTreeNode` and returning a boolean value
|
|
216
228
|
* accordingly.
|
|
217
|
-
* @returns The function `isNode` is checking if the input `
|
|
229
|
+
* @returns The function `isNode` is checking if the input `keyNodeEntryOrRaw` is an instance of
|
|
218
230
|
* `BinaryTreeNode`. If it is, the function returns `true`, indicating that the input is a node. If
|
|
219
231
|
* it is not an instance of `BinaryTreeNode`, the function returns `false`, indicating that the input
|
|
220
232
|
* is not a node.
|
|
221
233
|
*/
|
|
222
|
-
isNode(
|
|
223
|
-
return
|
|
234
|
+
isNode(keyNodeEntryOrRaw) {
|
|
235
|
+
return keyNodeEntryOrRaw instanceof BinaryTreeNode;
|
|
236
|
+
}
|
|
237
|
+
isRaw(keyNodeEntryOrRaw) {
|
|
238
|
+
return typeof keyNodeEntryOrRaw === 'object';
|
|
224
239
|
}
|
|
225
240
|
/**
|
|
226
241
|
* The function `isRealNode` checks if a given input is a valid node in a binary tree.
|
|
227
|
-
* @param {
|
|
228
|
-
* parameter in the `isRealNode` function can be of type `
|
|
242
|
+
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The `keyNodeEntryOrRaw`
|
|
243
|
+
* parameter in the `isRealNode` function can be of type `BTNRep<K, V, NODE>` or `R`.
|
|
229
244
|
* The function checks if the input parameter is a `NODE` type by verifying if it is not equal
|
|
230
|
-
* @returns The function `isRealNode` is checking if the input `
|
|
245
|
+
* @returns The function `isRealNode` is checking if the input `keyNodeEntryOrRaw` is a valid
|
|
231
246
|
* node by comparing it to `this._NIL`, `null`, and `undefined`. If the input is not one of these
|
|
232
247
|
* values, it then calls the `isNode` method to further determine if the input is a node. The
|
|
233
248
|
* function will return a boolean value indicating whether the
|
|
234
249
|
*/
|
|
235
|
-
isRealNode(
|
|
236
|
-
if (
|
|
250
|
+
isRealNode(keyNodeEntryOrRaw) {
|
|
251
|
+
if (keyNodeEntryOrRaw === this._NIL || keyNodeEntryOrRaw === null || keyNodeEntryOrRaw === undefined)
|
|
237
252
|
return false;
|
|
238
|
-
return this.isNode(
|
|
253
|
+
return this.isNode(keyNodeEntryOrRaw);
|
|
239
254
|
}
|
|
240
255
|
/**
|
|
241
256
|
* The function checks if a given input is a valid node or null.
|
|
242
|
-
* @param {
|
|
243
|
-
* `
|
|
257
|
+
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The parameter
|
|
258
|
+
* `keyNodeEntryOrRaw` in the `isRealNodeOrNull` function can be of type `BTNRep<K,
|
|
244
259
|
* V, NODE>` or `R`. It is a union type that can either be a key, a node, an entry, or
|
|
245
260
|
* @returns The function `isRealNodeOrNull` is returning a boolean value. It checks if the input
|
|
246
|
-
* `
|
|
261
|
+
* `keyNodeEntryOrRaw` is either `null` or a real node, and returns `true` if it is a node or
|
|
247
262
|
* `null`, and `false` otherwise.
|
|
248
263
|
*/
|
|
249
|
-
isRealNodeOrNull(
|
|
250
|
-
return
|
|
264
|
+
isRealNodeOrNull(keyNodeEntryOrRaw) {
|
|
265
|
+
return keyNodeEntryOrRaw === null || this.isRealNode(keyNodeEntryOrRaw);
|
|
251
266
|
}
|
|
252
267
|
/**
|
|
253
268
|
* The function isNIL checks if a given key, node, entry, or raw value is equal to the _NIL value.
|
|
254
|
-
* @param {
|
|
269
|
+
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - BTNRep<K, V,
|
|
255
270
|
* NODE> | R
|
|
256
|
-
* @returns The function is checking if the `
|
|
271
|
+
* @returns The function is checking if the `keyNodeEntryOrRaw` parameter is equal to the `_NIL`
|
|
257
272
|
* property of the current object and returning a boolean value based on that comparison.
|
|
258
273
|
*/
|
|
259
|
-
isNIL(
|
|
260
|
-
return
|
|
274
|
+
isNIL(keyNodeEntryOrRaw) {
|
|
275
|
+
return keyNodeEntryOrRaw === this._NIL;
|
|
261
276
|
}
|
|
262
277
|
/**
|
|
263
278
|
* The function determines whether a given key, node, entry, or raw data is a leaf node in a binary
|
|
264
279
|
* tree.
|
|
265
|
-
* @param {
|
|
266
|
-
* `
|
|
280
|
+
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The parameter
|
|
281
|
+
* `keyNodeEntryOrRaw` can be of type `BTNRep<K, V, NODE>` or `R`. It represents a
|
|
267
282
|
* key, node, entry, or raw data in a binary tree structure. The function `isLeaf` checks whether the
|
|
268
283
|
* provided
|
|
269
284
|
* @returns The function `isLeaf` returns a boolean value indicating whether the input
|
|
270
|
-
* `
|
|
285
|
+
* `keyNodeEntryOrRaw` is a leaf node in a binary tree.
|
|
271
286
|
*/
|
|
272
|
-
isLeaf(
|
|
273
|
-
|
|
274
|
-
if (
|
|
287
|
+
isLeaf(keyNodeEntryOrRaw) {
|
|
288
|
+
keyNodeEntryOrRaw = this.ensureNode(keyNodeEntryOrRaw);
|
|
289
|
+
if (keyNodeEntryOrRaw === undefined)
|
|
275
290
|
return false;
|
|
276
|
-
if (
|
|
291
|
+
if (keyNodeEntryOrRaw === null)
|
|
277
292
|
return true;
|
|
278
|
-
return !this.isRealNode(
|
|
293
|
+
return !this.isRealNode(keyNodeEntryOrRaw.left) && !this.isRealNode(keyNodeEntryOrRaw.right);
|
|
279
294
|
}
|
|
280
295
|
/**
|
|
281
296
|
* The function `isEntry` checks if the input is a BTNEntry object by verifying if it is an array
|
|
282
297
|
* with a length of 2.
|
|
283
|
-
* @param {
|
|
284
|
-
* parameter in the `isEntry` function can be of type `
|
|
285
|
-
* The function checks if the provided `
|
|
286
|
-
* @returns The `isEntry` function is checking if the `
|
|
298
|
+
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The `keyNodeEntryOrRaw`
|
|
299
|
+
* parameter in the `isEntry` function can be of type `BTNRep<K, V, NODE>` or type `R`.
|
|
300
|
+
* The function checks if the provided `keyNodeEntryOrRaw` is of type `BTN
|
|
301
|
+
* @returns The `isEntry` function is checking if the `keyNodeEntryOrRaw` parameter is an array
|
|
287
302
|
* with a length of 2. If it is, then it returns `true`, indicating that the parameter is of type
|
|
288
303
|
* `BTNEntry<K, V>`. If the condition is not met, it returns `false`.
|
|
289
304
|
*/
|
|
290
|
-
isEntry(
|
|
291
|
-
return Array.isArray(
|
|
305
|
+
isEntry(keyNodeEntryOrRaw) {
|
|
306
|
+
return Array.isArray(keyNodeEntryOrRaw) && keyNodeEntryOrRaw.length === 2;
|
|
292
307
|
}
|
|
293
308
|
/**
|
|
294
309
|
* Time Complexity O(1)
|
|
@@ -312,8 +327,8 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
312
327
|
*
|
|
313
328
|
* The `add` function in TypeScript adds a new node to a binary tree while handling duplicate keys
|
|
314
329
|
* and finding the correct insertion position.
|
|
315
|
-
* @param {
|
|
316
|
-
* seems to be for adding a new node to a binary tree structure. The `
|
|
330
|
+
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The `add` method you provided
|
|
331
|
+
* seems to be for adding a new node to a binary tree structure. The `keyNodeEntryOrRaw`
|
|
317
332
|
* parameter in the method can accept different types of values:
|
|
318
333
|
* @param {V} [value] - The `value` parameter in the `add` method represents the value associated
|
|
319
334
|
* with the key that you want to add to the binary tree. When adding a key-value pair to the binary
|
|
@@ -323,13 +338,15 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
323
338
|
* node was successful, and `false` if the insertion position could not be found or if a duplicate
|
|
324
339
|
* key was found and the node was replaced instead of inserted.
|
|
325
340
|
*/
|
|
326
|
-
add(
|
|
327
|
-
const newNode = this.
|
|
341
|
+
add(keyNodeEntryOrRaw, value) {
|
|
342
|
+
const [newNode, newValue] = this.keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
|
|
328
343
|
if (newNode === undefined)
|
|
329
344
|
return false;
|
|
330
345
|
// If the tree is empty, directly set the new node as the root node
|
|
331
346
|
if (!this._root) {
|
|
332
347
|
this._setRoot(newNode);
|
|
348
|
+
if (this._isMapMode)
|
|
349
|
+
this._setValue(newNode === null || newNode === void 0 ? void 0 : newNode.key, newValue);
|
|
333
350
|
this._size = 1;
|
|
334
351
|
return true;
|
|
335
352
|
}
|
|
@@ -342,6 +359,8 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
342
359
|
// Check for duplicate keys when newNode is not null
|
|
343
360
|
if (newNode !== null && cur.key === newNode.key) {
|
|
344
361
|
this._replaceNode(cur, newNode);
|
|
362
|
+
if (this._isMapMode)
|
|
363
|
+
this._setValue(cur.key, newValue);
|
|
345
364
|
return true; // If duplicate keys are found, no insertion is performed
|
|
346
365
|
}
|
|
347
366
|
// Record the first possible insertion location found
|
|
@@ -366,6 +385,8 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
366
385
|
else if (potentialParent.right === undefined) {
|
|
367
386
|
potentialParent.right = newNode;
|
|
368
387
|
}
|
|
388
|
+
if (this._isMapMode)
|
|
389
|
+
this._setValue(newNode === null || newNode === void 0 ? void 0 : newNode.key, newValue);
|
|
369
390
|
this._size++;
|
|
370
391
|
return true;
|
|
371
392
|
}
|
|
@@ -378,25 +399,25 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
378
399
|
* The `addMany` function takes in multiple keys or nodes or entries or raw values along with
|
|
379
400
|
* optional values, and adds them to a data structure while returning an array indicating whether
|
|
380
401
|
* each insertion was successful.
|
|
381
|
-
* @param
|
|
402
|
+
* @param keysNodesEntriesOrRaws - `keysNodesEntriesOrRaws` is an iterable that can contain a
|
|
382
403
|
* mix of keys, nodes, entries, or raw values. Each element in this iterable can be of type
|
|
383
|
-
* `
|
|
404
|
+
* `BTNRep<K, V, NODE>` or `R`.
|
|
384
405
|
* @param [values] - The `values` parameter in the `addMany` function is an optional parameter that
|
|
385
406
|
* accepts an iterable of values. These values correspond to the keys or nodes being added in the
|
|
386
|
-
* `
|
|
407
|
+
* `keysNodesEntriesOrRaws` parameter. If provided, the function will iterate over the values and
|
|
387
408
|
* assign them
|
|
388
409
|
* @returns The `addMany` method returns an array of boolean values indicating whether each key,
|
|
389
410
|
* node, entry, or raw value was successfully added to the data structure. Each boolean value
|
|
390
411
|
* corresponds to the success of adding the corresponding key or value in the input iterable.
|
|
391
412
|
*/
|
|
392
|
-
addMany(
|
|
413
|
+
addMany(keysNodesEntriesOrRaws, values) {
|
|
393
414
|
// TODO not sure addMany not be run multi times
|
|
394
415
|
const inserted = [];
|
|
395
416
|
let valuesIterator;
|
|
396
417
|
if (values) {
|
|
397
418
|
valuesIterator = values[Symbol.iterator]();
|
|
398
419
|
}
|
|
399
|
-
for (const
|
|
420
|
+
for (const keyNodeEntryOrRaw of keysNodesEntriesOrRaws) {
|
|
400
421
|
let value = undefined;
|
|
401
422
|
if (valuesIterator) {
|
|
402
423
|
const valueResult = valuesIterator.next();
|
|
@@ -404,7 +425,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
404
425
|
value = valueResult.value;
|
|
405
426
|
}
|
|
406
427
|
}
|
|
407
|
-
inserted.push(this.add(
|
|
428
|
+
inserted.push(this.add(keyNodeEntryOrRaw, value));
|
|
408
429
|
}
|
|
409
430
|
return inserted;
|
|
410
431
|
}
|
|
@@ -414,15 +435,15 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
414
435
|
*
|
|
415
436
|
* The `refill` function clears the existing data structure and then adds new key-value pairs based
|
|
416
437
|
* on the provided input.
|
|
417
|
-
* @param
|
|
418
|
-
* method can accept an iterable containing a mix of `
|
|
438
|
+
* @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the `refill`
|
|
439
|
+
* method can accept an iterable containing a mix of `BTNRep<K, V, NODE>` objects or `R`
|
|
419
440
|
* objects.
|
|
420
441
|
* @param [values] - The `values` parameter in the `refill` method is an optional parameter that
|
|
421
442
|
* accepts an iterable of values of type `V` or `undefined`.
|
|
422
443
|
*/
|
|
423
|
-
refill(
|
|
444
|
+
refill(keysNodesEntriesOrRaws, values) {
|
|
424
445
|
this.clear();
|
|
425
|
-
this.addMany(
|
|
446
|
+
this.addMany(keysNodesEntriesOrRaws, values);
|
|
426
447
|
}
|
|
427
448
|
/**
|
|
428
449
|
* Time Complexity: O(n)
|
|
@@ -430,20 +451,20 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
430
451
|
*
|
|
431
452
|
* The function `delete` in TypeScript implements the deletion of a node in a binary tree and returns
|
|
432
453
|
* the deleted node along with information for tree balancing.
|
|
433
|
-
* @param {
|
|
454
|
+
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw
|
|
434
455
|
* - The `delete` method you provided is used to delete a node from a binary tree based on the key,
|
|
435
|
-
* node, entry
|
|
456
|
+
* node, entry or raw data. The method returns an array of
|
|
436
457
|
* `BinaryTreeDeleteResult` objects containing information about the deleted node and whether
|
|
437
458
|
* balancing is needed.
|
|
438
459
|
* @returns The `delete` method returns an array of `BinaryTreeDeleteResult` objects. Each object in
|
|
439
460
|
* the array contains information about the node that was deleted (`deleted`) and the node that may
|
|
440
461
|
* need to be balanced (`needBalanced`).
|
|
441
462
|
*/
|
|
442
|
-
delete(
|
|
463
|
+
delete(keyNodeEntryOrRaw) {
|
|
443
464
|
const deletedResult = [];
|
|
444
465
|
if (!this._root)
|
|
445
466
|
return deletedResult;
|
|
446
|
-
const curr = this.getNode(
|
|
467
|
+
const curr = this.getNode(keyNodeEntryOrRaw);
|
|
447
468
|
if (!curr)
|
|
448
469
|
return deletedResult;
|
|
449
470
|
const parent = curr === null || curr === void 0 ? void 0 : curr.parent;
|
|
@@ -482,6 +503,8 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
482
503
|
}
|
|
483
504
|
this._size = this._size - 1;
|
|
484
505
|
deletedResult.push({ deleted: orgCurrent, needBalanced });
|
|
506
|
+
if (this._isMapMode && orgCurrent)
|
|
507
|
+
this._store.delete(orgCurrent.key);
|
|
485
508
|
return deletedResult;
|
|
486
509
|
}
|
|
487
510
|
/**
|
|
@@ -490,12 +513,12 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
490
513
|
*
|
|
491
514
|
* The function `getNodes` retrieves nodes from a binary tree based on a key, node, entry, raw data,
|
|
492
515
|
* or predicate, with options for recursive or iterative traversal.
|
|
493
|
-
* @param {
|
|
516
|
+
* @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate
|
|
494
517
|
* - The `getNodes` function you provided takes several parameters:
|
|
495
518
|
* @param [onlyOne=false] - The `onlyOne` parameter in the `getNodes` function is a boolean flag that
|
|
496
519
|
* determines whether to return only the first node that matches the criteria specified by the
|
|
497
|
-
* `
|
|
498
|
-
* @param {
|
|
520
|
+
* `keyNodeEntryRawOrPredicate` parameter. If `onlyOne` is set to `true`, the function will
|
|
521
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
|
|
499
522
|
* `getNodes` function is used to specify the starting point for traversing the binary tree. It
|
|
500
523
|
* represents the root node of the binary tree or the node from which the traversal should begin. If
|
|
501
524
|
* not provided, the default value is set to `this._root
|
|
@@ -505,15 +528,15 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
505
528
|
* @returns The `getNodes` function returns an array of nodes that satisfy the provided condition
|
|
506
529
|
* based on the input parameters and the iteration type specified.
|
|
507
530
|
*/
|
|
508
|
-
getNodes(
|
|
509
|
-
if (
|
|
531
|
+
getNodes(keyNodeEntryRawOrPredicate, onlyOne = false, startNode = this._root, iterationType = this.iterationType) {
|
|
532
|
+
if (keyNodeEntryRawOrPredicate === undefined)
|
|
510
533
|
return [];
|
|
511
|
-
if (
|
|
534
|
+
if (keyNodeEntryRawOrPredicate === null)
|
|
512
535
|
return [];
|
|
513
|
-
|
|
514
|
-
if (!
|
|
536
|
+
startNode = this.ensureNode(startNode);
|
|
537
|
+
if (!startNode)
|
|
515
538
|
return [];
|
|
516
|
-
const callback = this._ensurePredicate(
|
|
539
|
+
const callback = this._ensurePredicate(keyNodeEntryRawOrPredicate);
|
|
517
540
|
const ans = [];
|
|
518
541
|
if (iterationType === 'RECURSIVE') {
|
|
519
542
|
const dfs = (cur) => {
|
|
@@ -529,10 +552,10 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
529
552
|
if (this.isRealNode(cur.right))
|
|
530
553
|
dfs(cur.right);
|
|
531
554
|
};
|
|
532
|
-
dfs(
|
|
555
|
+
dfs(startNode);
|
|
533
556
|
}
|
|
534
557
|
else {
|
|
535
|
-
const stack = [
|
|
558
|
+
const stack = [startNode];
|
|
536
559
|
while (stack.length > 0) {
|
|
537
560
|
const cur = stack.pop();
|
|
538
561
|
if (this.isRealNode(cur)) {
|
|
@@ -556,10 +579,10 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
556
579
|
*
|
|
557
580
|
* The `getNode` function retrieves a node based on the provided key, node, entry, raw data, or
|
|
558
581
|
* predicate.
|
|
559
|
-
* @param {
|
|
560
|
-
* - The `
|
|
582
|
+
* @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate
|
|
583
|
+
* - The `keyNodeEntryRawOrPredicate` parameter in the `getNode` function can accept a key,
|
|
561
584
|
* node, entry, raw data, or a predicate function.
|
|
562
|
-
* @param {
|
|
585
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
|
|
563
586
|
* `getNode` function is used to specify the starting point for searching for a node in a binary
|
|
564
587
|
* tree. If no specific starting point is provided, the default value is set to `this._root`, which
|
|
565
588
|
* is typically the root node of the binary tree.
|
|
@@ -570,9 +593,9 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
570
593
|
* @returns The `getNode` function is returning the first node that matches the specified criteria,
|
|
571
594
|
* or `null` if no matching node is found.
|
|
572
595
|
*/
|
|
573
|
-
getNode(
|
|
596
|
+
getNode(keyNodeEntryRawOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
574
597
|
var _a;
|
|
575
|
-
return (_a = this.getNodes(
|
|
598
|
+
return (_a = this.getNodes(keyNodeEntryRawOrPredicate, true, startNode, iterationType)[0]) !== null && _a !== void 0 ? _a : null;
|
|
576
599
|
}
|
|
577
600
|
/**
|
|
578
601
|
* Time Complexity: O(n)
|
|
@@ -585,7 +608,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
585
608
|
* specifies how the tree nodes should be traversed when searching for a node with the given key. It
|
|
586
609
|
* is an optional parameter with a default value of `this.iterationType`.
|
|
587
610
|
* @returns The `getNodeByKey` function is returning an optional binary tree node
|
|
588
|
-
* (`
|
|
611
|
+
* (`OptNodeOrNull<NODE>`).
|
|
589
612
|
*/
|
|
590
613
|
getNodeByKey(key, iterationType = this.iterationType) {
|
|
591
614
|
return this.getNode(key, this._root, iterationType);
|
|
@@ -596,10 +619,10 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
596
619
|
*
|
|
597
620
|
* This function overrides the `get` method to retrieve the value associated with a specified key,
|
|
598
621
|
* node, entry, raw data, or predicate in a data structure.
|
|
599
|
-
* @param {
|
|
600
|
-
* - The `
|
|
622
|
+
* @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate
|
|
623
|
+
* - The `keyNodeEntryRawOrPredicate` parameter in the `get` method can accept one of the
|
|
601
624
|
* following types:
|
|
602
|
-
* @param {
|
|
625
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `get`
|
|
603
626
|
* method is used to specify the starting point for searching for a key or node in the binary tree.
|
|
604
627
|
* If no specific starting point is provided, the default starting point is the root of the binary
|
|
605
628
|
* tree (`this._root`).
|
|
@@ -612,9 +635,15 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
612
635
|
* the method returns the corresponding value. If the key or node is not found, it returns
|
|
613
636
|
* `undefined`.
|
|
614
637
|
*/
|
|
615
|
-
get(
|
|
638
|
+
get(keyNodeEntryRawOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
616
639
|
var _a;
|
|
617
|
-
|
|
640
|
+
if (this._isMapMode) {
|
|
641
|
+
const key = this._getKey(keyNodeEntryRawOrPredicate);
|
|
642
|
+
if (key === null || key === undefined)
|
|
643
|
+
return;
|
|
644
|
+
return this._store.get(key);
|
|
645
|
+
}
|
|
646
|
+
return (_a = this.getNode(keyNodeEntryRawOrPredicate, startNode, iterationType)) === null || _a === void 0 ? void 0 : _a.value;
|
|
618
647
|
}
|
|
619
648
|
/**
|
|
620
649
|
* Time Complexity: O(n)
|
|
@@ -622,10 +651,10 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
622
651
|
*
|
|
623
652
|
* The `has` function in TypeScript checks if a specified key, node, entry, raw data, or predicate
|
|
624
653
|
* exists in the data structure.
|
|
625
|
-
* @param {
|
|
626
|
-
* - The `
|
|
654
|
+
* @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate
|
|
655
|
+
* - The `keyNodeEntryRawOrPredicate` parameter in the `override has` method can accept one of
|
|
627
656
|
* the following types:
|
|
628
|
-
* @param {
|
|
657
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
|
|
629
658
|
* `override` method is used to specify the starting point for the search operation within the data
|
|
630
659
|
* structure. It defaults to `this._root` if not provided explicitly.
|
|
631
660
|
* @param {IterationType} iterationType - The `iterationType` parameter in the `override has` method
|
|
@@ -637,8 +666,8 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
637
666
|
* are matching nodes, it returns `true`, indicating that the tree contains the specified element.
|
|
638
667
|
* Otherwise, it returns `false`.
|
|
639
668
|
*/
|
|
640
|
-
has(
|
|
641
|
-
return this.getNodes(
|
|
669
|
+
has(keyNodeEntryRawOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
670
|
+
return this.getNodes(keyNodeEntryRawOrPredicate, true, startNode, iterationType).length > 0;
|
|
642
671
|
}
|
|
643
672
|
/**
|
|
644
673
|
* Time Complexity: O(1)
|
|
@@ -647,8 +676,9 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
647
676
|
* The `clear` function resets the root node and size of a data structure to empty.
|
|
648
677
|
*/
|
|
649
678
|
clear() {
|
|
650
|
-
this.
|
|
651
|
-
this.
|
|
679
|
+
this._clearNodes();
|
|
680
|
+
if (this._isMapMode)
|
|
681
|
+
this._clearValues();
|
|
652
682
|
}
|
|
653
683
|
/**
|
|
654
684
|
* Time Complexity: O(1)
|
|
@@ -668,17 +698,17 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
668
698
|
*
|
|
669
699
|
* The function checks if a binary tree is perfectly balanced by comparing its minimum height with
|
|
670
700
|
* its height.
|
|
671
|
-
* @param {
|
|
701
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter is the starting
|
|
672
702
|
* point for checking if the binary tree is perfectly balanced. It represents the root node of the
|
|
673
703
|
* binary tree or a specific node from which the balance check should begin.
|
|
674
704
|
* @returns The method `isPerfectlyBalanced` is returning a boolean value, which indicates whether
|
|
675
|
-
* the tree starting from the `
|
|
705
|
+
* the tree starting from the `startNode` node is perfectly balanced or not. The return value is
|
|
676
706
|
* determined by comparing the minimum height of the tree with the height of the tree. If the minimum
|
|
677
707
|
* height plus 1 is greater than or equal to the height of the tree, then it is considered perfectly
|
|
678
708
|
* balanced and
|
|
679
709
|
*/
|
|
680
|
-
isPerfectlyBalanced(
|
|
681
|
-
return this.getMinHeight(
|
|
710
|
+
isPerfectlyBalanced(startNode = this._root) {
|
|
711
|
+
return this.getMinHeight(startNode) + 1 >= this.getHeight(startNode);
|
|
682
712
|
}
|
|
683
713
|
/**
|
|
684
714
|
* Time Complexity: O(n)
|
|
@@ -686,7 +716,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
686
716
|
*
|
|
687
717
|
* The function `isBST` in TypeScript checks if a binary search tree is valid using either recursive
|
|
688
718
|
* or iterative methods.
|
|
689
|
-
* @param {
|
|
719
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `isBST`
|
|
690
720
|
* function represents the starting point for checking whether a binary search tree (BST) is valid.
|
|
691
721
|
* It can be a node in the BST or a reference to the root of the BST. If no specific node is
|
|
692
722
|
* provided, the function will default to
|
|
@@ -698,10 +728,10 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
698
728
|
* the tree satisfies the BST property, where for every node, all nodes in its left subtree have keys
|
|
699
729
|
* less than the node's key, and all nodes in its right subtree have keys greater than the node's
|
|
700
730
|
*/
|
|
701
|
-
isBST(
|
|
731
|
+
isBST(startNode = this._root, iterationType = this.iterationType) {
|
|
702
732
|
// TODO there is a bug
|
|
703
|
-
|
|
704
|
-
if (!
|
|
733
|
+
startNode = this.ensureNode(startNode);
|
|
734
|
+
if (!startNode)
|
|
705
735
|
return true;
|
|
706
736
|
if (iterationType === 'RECURSIVE') {
|
|
707
737
|
const dfs = (cur, min, max) => {
|
|
@@ -712,8 +742,8 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
712
742
|
return false;
|
|
713
743
|
return dfs(cur.left, min, numKey) && dfs(cur.right, numKey, max);
|
|
714
744
|
};
|
|
715
|
-
const isStandardBST = dfs(
|
|
716
|
-
const isInverseBST = dfs(
|
|
745
|
+
const isStandardBST = dfs(startNode, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
|
|
746
|
+
const isInverseBST = dfs(startNode, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER);
|
|
717
747
|
return isStandardBST || isInverseBST;
|
|
718
748
|
}
|
|
719
749
|
else {
|
|
@@ -721,7 +751,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
721
751
|
const stack = [];
|
|
722
752
|
let prev = checkMax ? Number.MAX_SAFE_INTEGER : Number.MIN_SAFE_INTEGER;
|
|
723
753
|
// @ts-ignore
|
|
724
|
-
let curr =
|
|
754
|
+
let curr = startNode;
|
|
725
755
|
while (this.isRealNode(curr) || stack.length > 0) {
|
|
726
756
|
while (this.isRealNode(curr)) {
|
|
727
757
|
stack.push(curr);
|
|
@@ -745,20 +775,20 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
745
775
|
* Space Complexity: O(1)
|
|
746
776
|
*
|
|
747
777
|
* The `getDepth` function calculates the depth between two nodes in a binary tree.
|
|
748
|
-
* @param {
|
|
778
|
+
* @param {BTNRep<K, V, NODE> | R} dist - The `dist` parameter in the `getDepth`
|
|
749
779
|
* function represents the node or entry in a binary tree map, or a reference to a node in the tree.
|
|
750
|
-
* It is the target node for which you want to calculate the depth from the `
|
|
751
|
-
* @param {
|
|
780
|
+
* It is the target node for which you want to calculate the depth from the `startNode` node.
|
|
781
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
|
|
752
782
|
* `getDepth` function represents the starting point from which you want to calculate the depth of a
|
|
753
783
|
* given node or entry in a binary tree. If no specific starting point is provided, the default value
|
|
754
|
-
* for `
|
|
784
|
+
* for `startNode` is set to the root of the binary
|
|
755
785
|
* @returns The `getDepth` method returns the depth of a given node `dist` relative to the
|
|
756
|
-
* `
|
|
786
|
+
* `startNode` node in a binary tree. If the `dist` node is not found in the path to the `startNode`
|
|
757
787
|
* node, it returns the depth of the `dist` node from the root of the tree.
|
|
758
788
|
*/
|
|
759
|
-
getDepth(dist,
|
|
789
|
+
getDepth(dist, startNode = this._root) {
|
|
760
790
|
let distEnsured = this.ensureNode(dist);
|
|
761
|
-
const beginRootEnsured = this.ensureNode(
|
|
791
|
+
const beginRootEnsured = this.ensureNode(startNode);
|
|
762
792
|
let depth = 0;
|
|
763
793
|
while (distEnsured === null || distEnsured === void 0 ? void 0 : distEnsured.parent) {
|
|
764
794
|
if (distEnsured === beginRootEnsured) {
|
|
@@ -775,7 +805,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
775
805
|
*
|
|
776
806
|
* The `getHeight` function calculates the maximum height of a binary tree using either a recursive
|
|
777
807
|
* or iterative approach in TypeScript.
|
|
778
|
-
* @param {
|
|
808
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter is the starting
|
|
779
809
|
* point from which the height of the binary tree will be calculated. It can be a node in the binary
|
|
780
810
|
* tree or a reference to the root of the tree. If not provided, it defaults to the root of the
|
|
781
811
|
* binary tree data structure.
|
|
@@ -786,9 +816,9 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
786
816
|
* root node. The height is calculated based on the maximum depth of the tree, considering either a
|
|
787
817
|
* recursive approach or an iterative approach depending on the `iterationType` parameter.
|
|
788
818
|
*/
|
|
789
|
-
getHeight(
|
|
790
|
-
|
|
791
|
-
if (!this.isRealNode(
|
|
819
|
+
getHeight(startNode = this._root, iterationType = this.iterationType) {
|
|
820
|
+
startNode = this.ensureNode(startNode);
|
|
821
|
+
if (!this.isRealNode(startNode))
|
|
792
822
|
return -1;
|
|
793
823
|
if (iterationType === 'RECURSIVE') {
|
|
794
824
|
const _getMaxHeight = (cur) => {
|
|
@@ -798,10 +828,10 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
798
828
|
const rightHeight = _getMaxHeight(cur.right);
|
|
799
829
|
return Math.max(leftHeight, rightHeight) + 1;
|
|
800
830
|
};
|
|
801
|
-
return _getMaxHeight(
|
|
831
|
+
return _getMaxHeight(startNode);
|
|
802
832
|
}
|
|
803
833
|
else {
|
|
804
|
-
const stack = [{ node:
|
|
834
|
+
const stack = [{ node: startNode, depth: 0 }];
|
|
805
835
|
let maxHeight = 0;
|
|
806
836
|
while (stack.length > 0) {
|
|
807
837
|
const { node, depth } = stack.pop();
|
|
@@ -820,7 +850,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
820
850
|
*
|
|
821
851
|
* The `getMinHeight` function calculates the minimum height of a binary tree using either a
|
|
822
852
|
* recursive or iterative approach in TypeScript.
|
|
823
|
-
* @param {
|
|
853
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
|
|
824
854
|
* `getMinHeight` function represents the starting node from which the minimum height of the binary
|
|
825
855
|
* tree will be calculated. It is either a node in the binary tree or a reference to the root of the
|
|
826
856
|
* tree. If not provided, the default value is the root
|
|
@@ -832,9 +862,9 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
832
862
|
* leaf node in the tree. The method uses either a recursive approach or an iterative approach (using
|
|
833
863
|
* a stack) based on the `iterationType` parameter.
|
|
834
864
|
*/
|
|
835
|
-
getMinHeight(
|
|
836
|
-
|
|
837
|
-
if (!
|
|
865
|
+
getMinHeight(startNode = this._root, iterationType = this.iterationType) {
|
|
866
|
+
startNode = this.ensureNode(startNode);
|
|
867
|
+
if (!startNode)
|
|
838
868
|
return -1;
|
|
839
869
|
if (iterationType === 'RECURSIVE') {
|
|
840
870
|
const _getMinHeight = (cur) => {
|
|
@@ -846,11 +876,11 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
846
876
|
const rightMinHeight = _getMinHeight(cur.right);
|
|
847
877
|
return Math.min(leftMinHeight, rightMinHeight) + 1;
|
|
848
878
|
};
|
|
849
|
-
return _getMinHeight(
|
|
879
|
+
return _getMinHeight(startNode);
|
|
850
880
|
}
|
|
851
881
|
else {
|
|
852
882
|
const stack = [];
|
|
853
|
-
let node =
|
|
883
|
+
let node = startNode, last = null;
|
|
854
884
|
const depths = new Map();
|
|
855
885
|
while (stack.length > 0 || node) {
|
|
856
886
|
if (this.isRealNode(node)) {
|
|
@@ -873,7 +903,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
873
903
|
node = node.right;
|
|
874
904
|
}
|
|
875
905
|
}
|
|
876
|
-
return depths.get(
|
|
906
|
+
return depths.get(startNode);
|
|
877
907
|
}
|
|
878
908
|
}
|
|
879
909
|
/**
|
|
@@ -886,7 +916,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
886
916
|
* the path to the root. It is expected to be a function that takes a node as an argument and returns
|
|
887
917
|
* a value based on that node. The return type of the callback function is determined by the generic
|
|
888
918
|
* type `C
|
|
889
|
-
* @param {
|
|
919
|
+
* @param {BTNRep<K, V, NODE> | R} beginNode - The `beginNode` parameter in the
|
|
890
920
|
* `getPathToRoot` function can be either a key, a node, an entry, or any other value of type `R`.
|
|
891
921
|
* @param [isReverse=true] - The `isReverse` parameter in the `getPathToRoot` function determines
|
|
892
922
|
* whether the resulting path from the given `beginNode` to the root should be in reverse order or
|
|
@@ -896,7 +926,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
896
926
|
* array is either in reverse order or in the original order based on the value of the `isReverse`
|
|
897
927
|
* parameter.
|
|
898
928
|
*/
|
|
899
|
-
getPathToRoot(callback = this.
|
|
929
|
+
getPathToRoot(callback = this._DEFAULT_NODE_CALLBACK, beginNode, isReverse = true) {
|
|
900
930
|
const result = [];
|
|
901
931
|
let beginNodeEnsured = this.ensureNode(beginNode);
|
|
902
932
|
if (!beginNodeEnsured)
|
|
@@ -917,8 +947,8 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
917
947
|
* tail-recursive iteration.
|
|
918
948
|
* @param {C} callback - The `callback` parameter is a function that will be called with the leftmost
|
|
919
949
|
* node of a binary tree or with `undefined` if the tree is empty. It is provided with a default
|
|
920
|
-
* value of `
|
|
921
|
-
* @param {
|
|
950
|
+
* value of `_DEFAULT_NODE_CALLBACK` if not specified.
|
|
951
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
|
|
922
952
|
* `getLeftMost` function represents the starting point for finding the leftmost node in a binary
|
|
923
953
|
* tree. It can be either a key, a node, or an entry in the binary tree structure. If no specific
|
|
924
954
|
* starting point is provided, the function will default
|
|
@@ -926,23 +956,23 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
926
956
|
* specifies the type of iteration to be used when traversing the binary tree nodes. It can have two
|
|
927
957
|
* possible values:
|
|
928
958
|
* @returns The `getLeftMost` function returns the result of the callback function `C` applied to the
|
|
929
|
-
* leftmost node in the binary tree starting from the `
|
|
930
|
-
* `NIL`, it returns the result of the callback function applied to `undefined`. If the `
|
|
959
|
+
* leftmost node in the binary tree starting from the `startNode` node. If the `startNode` node is
|
|
960
|
+
* `NIL`, it returns the result of the callback function applied to `undefined`. If the `startNode`
|
|
931
961
|
* node is not a real node, it returns the result of the callback
|
|
932
962
|
*/
|
|
933
|
-
getLeftMost(callback = this.
|
|
934
|
-
if (this.isNIL(
|
|
963
|
+
getLeftMost(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType) {
|
|
964
|
+
if (this.isNIL(startNode))
|
|
935
965
|
return callback(undefined);
|
|
936
|
-
|
|
937
|
-
if (!this.isRealNode(
|
|
938
|
-
return callback(
|
|
966
|
+
startNode = this.ensureNode(startNode);
|
|
967
|
+
if (!this.isRealNode(startNode))
|
|
968
|
+
return callback(startNode);
|
|
939
969
|
if (iterationType === 'RECURSIVE') {
|
|
940
970
|
const dfs = (cur) => {
|
|
941
971
|
if (!this.isRealNode(cur.left))
|
|
942
972
|
return cur;
|
|
943
973
|
return dfs(cur.left);
|
|
944
974
|
};
|
|
945
|
-
return callback(dfs(
|
|
975
|
+
return callback(dfs(startNode));
|
|
946
976
|
}
|
|
947
977
|
else {
|
|
948
978
|
// Indirect implementation of iteration using tail recursion optimization
|
|
@@ -951,7 +981,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
951
981
|
return cur;
|
|
952
982
|
return dfs.cont(cur.left);
|
|
953
983
|
});
|
|
954
|
-
return callback(dfs(
|
|
984
|
+
return callback(dfs(startNode));
|
|
955
985
|
}
|
|
956
986
|
}
|
|
957
987
|
/**
|
|
@@ -961,10 +991,10 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
961
991
|
* The function `getRightMost` retrieves the rightmost node in a binary tree using either recursive
|
|
962
992
|
* or iterative traversal methods.
|
|
963
993
|
* @param {C} callback - The `callback` parameter is a function that will be called with the result
|
|
964
|
-
* of finding the rightmost node in a binary tree. It is of type `
|
|
994
|
+
* of finding the rightmost node in a binary tree. It is of type `NodeCallback<OptNodeOrNull<NODE>>`,
|
|
965
995
|
* which means it is a callback function that can accept either an optional binary tree node or null
|
|
966
996
|
* as
|
|
967
|
-
* @param {
|
|
997
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
|
|
968
998
|
* `getRightMost` function represents the starting point for finding the rightmost node in a binary
|
|
969
999
|
* tree. It can be either a key, a node, or an entry in the binary tree structure. If no specific
|
|
970
1000
|
* starting point is provided, the function will default
|
|
@@ -976,20 +1006,20 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
976
1006
|
* the binary tree structure, determined based on the specified iteration type ('RECURSIVE' or
|
|
977
1007
|
* other).
|
|
978
1008
|
*/
|
|
979
|
-
getRightMost(callback = this.
|
|
980
|
-
if (this.isNIL(
|
|
1009
|
+
getRightMost(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType) {
|
|
1010
|
+
if (this.isNIL(startNode))
|
|
981
1011
|
return callback(undefined);
|
|
982
1012
|
// TODO support get right most by passing key in
|
|
983
|
-
|
|
984
|
-
if (!
|
|
985
|
-
return callback(
|
|
1013
|
+
startNode = this.ensureNode(startNode);
|
|
1014
|
+
if (!startNode)
|
|
1015
|
+
return callback(startNode);
|
|
986
1016
|
if (iterationType === 'RECURSIVE') {
|
|
987
1017
|
const dfs = (cur) => {
|
|
988
1018
|
if (!this.isRealNode(cur.right))
|
|
989
1019
|
return cur;
|
|
990
1020
|
return dfs(cur.right);
|
|
991
1021
|
};
|
|
992
|
-
return callback(dfs(
|
|
1022
|
+
return callback(dfs(startNode));
|
|
993
1023
|
}
|
|
994
1024
|
else {
|
|
995
1025
|
// Indirect implementation of iteration using tail recursion optimization
|
|
@@ -998,7 +1028,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
998
1028
|
return cur;
|
|
999
1029
|
return dfs.cont(cur.right);
|
|
1000
1030
|
});
|
|
1001
|
-
return callback(dfs(
|
|
1031
|
+
return callback(dfs(startNode));
|
|
1002
1032
|
}
|
|
1003
1033
|
}
|
|
1004
1034
|
/**
|
|
@@ -1062,14 +1092,14 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1062
1092
|
* The function `dfs` performs a depth-first search traversal on a binary tree structure based on the
|
|
1063
1093
|
* specified parameters.
|
|
1064
1094
|
* @param {C} callback - The `callback` parameter is a generic type `C` that extends the
|
|
1065
|
-
* `
|
|
1066
|
-
* `this.
|
|
1095
|
+
* `NodeCallback` interface with a type parameter of `OptNodeOrNull<NODE>`. It has a default value of
|
|
1096
|
+
* `this._DEFAULT_NODE_CALLBACK as C`.
|
|
1067
1097
|
* @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `dfs` method specifies the
|
|
1068
1098
|
* order in which the Depth-First Search (DFS) algorithm should traverse the nodes in the tree. The
|
|
1069
1099
|
* possible values for the `pattern` parameter are:
|
|
1070
|
-
* @param {
|
|
1100
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `dfs`
|
|
1071
1101
|
* method is used to specify the starting point for the Depth-First Search traversal. It can be
|
|
1072
|
-
* either a `
|
|
1102
|
+
* either a `BTNRep` object representing a key, node, or entry in the binary tree map,
|
|
1073
1103
|
* or it can be a
|
|
1074
1104
|
* @param {IterationType} iterationType - The `iterationType` parameter in the `dfs` method specifies
|
|
1075
1105
|
* the type of iteration to be performed during the depth-first search traversal. It is used to
|
|
@@ -1081,11 +1111,11 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1081
1111
|
* @returns The `dfs` method is returning an array of the return type specified by the generic type
|
|
1082
1112
|
* parameter `C`. The return type is determined by the callback function provided to the method.
|
|
1083
1113
|
*/
|
|
1084
|
-
dfs(callback = this.
|
|
1085
|
-
|
|
1086
|
-
if (!
|
|
1114
|
+
dfs(callback = this._DEFAULT_NODE_CALLBACK, pattern = 'IN', startNode = this._root, iterationType = this.iterationType, includeNull = false) {
|
|
1115
|
+
startNode = this.ensureNode(startNode);
|
|
1116
|
+
if (!startNode)
|
|
1087
1117
|
return [];
|
|
1088
|
-
return this._dfs(callback, pattern,
|
|
1118
|
+
return this._dfs(callback, pattern, startNode, iterationType, includeNull);
|
|
1089
1119
|
}
|
|
1090
1120
|
/**
|
|
1091
1121
|
* Time complexity: O(n)
|
|
@@ -1095,8 +1125,8 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1095
1125
|
* tree, executing a specified callback function on each node visited.
|
|
1096
1126
|
* @param {C} callback - The `callback` parameter in the `bfs` function is a function that will be
|
|
1097
1127
|
* called on each node visited during the breadth-first search traversal. It is a generic type `C`
|
|
1098
|
-
* that extends the `
|
|
1099
|
-
* @param {
|
|
1128
|
+
* that extends the `NodeCallback` type, which takes a parameter of type `NODE` or `null`.
|
|
1129
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `bfs`
|
|
1100
1130
|
* function represents the starting point for the breadth-first search traversal in a binary tree. It
|
|
1101
1131
|
* can be specified as a key, node, or entry in the binary tree structure. If not provided, the
|
|
1102
1132
|
* default value is the root node of the binary
|
|
@@ -1110,13 +1140,13 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1110
1140
|
* @returns The `bfs` function returns an array of values that are the result of applying the
|
|
1111
1141
|
* provided callback function to each node in the binary tree in a breadth-first search manner.
|
|
1112
1142
|
*/
|
|
1113
|
-
bfs(callback = this.
|
|
1114
|
-
|
|
1115
|
-
if (!
|
|
1143
|
+
bfs(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType, includeNull = false) {
|
|
1144
|
+
startNode = this.ensureNode(startNode);
|
|
1145
|
+
if (!startNode)
|
|
1116
1146
|
return [];
|
|
1117
1147
|
const ans = [];
|
|
1118
1148
|
if (iterationType === 'RECURSIVE') {
|
|
1119
|
-
const queue = new queue_1.Queue([
|
|
1149
|
+
const queue = new queue_1.Queue([startNode]);
|
|
1120
1150
|
const dfs = (level) => {
|
|
1121
1151
|
if (queue.size === 0)
|
|
1122
1152
|
return;
|
|
@@ -1139,7 +1169,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1139
1169
|
dfs(0);
|
|
1140
1170
|
}
|
|
1141
1171
|
else {
|
|
1142
|
-
const queue = new queue_1.Queue([
|
|
1172
|
+
const queue = new queue_1.Queue([startNode]);
|
|
1143
1173
|
while (queue.size > 0) {
|
|
1144
1174
|
const levelSize = queue.size;
|
|
1145
1175
|
for (let i = 0; i < levelSize; i++) {
|
|
@@ -1170,7 +1200,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1170
1200
|
* structure based on a specified callback and iteration type.
|
|
1171
1201
|
* @param {C} callback - The `callback` parameter is a function that will be called on each leaf node
|
|
1172
1202
|
* in the binary tree. It is optional and defaults to a default callback function if not provided.
|
|
1173
|
-
* @param {
|
|
1203
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `leaves`
|
|
1174
1204
|
* method is used to specify the starting point for finding and processing the leaves of a binary
|
|
1175
1205
|
* tree. It can be provided as either a key, a node, or an entry in the binary tree structure. If not
|
|
1176
1206
|
* explicitly provided, the default value
|
|
@@ -1180,10 +1210,10 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1180
1210
|
* @returns The `leaves` method returns an array of values that are the result of applying the
|
|
1181
1211
|
* provided callback function to each leaf node in the binary tree.
|
|
1182
1212
|
*/
|
|
1183
|
-
leaves(callback = this.
|
|
1184
|
-
|
|
1213
|
+
leaves(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType) {
|
|
1214
|
+
startNode = this.ensureNode(startNode);
|
|
1185
1215
|
const leaves = [];
|
|
1186
|
-
if (!this.isRealNode(
|
|
1216
|
+
if (!this.isRealNode(startNode))
|
|
1187
1217
|
return [];
|
|
1188
1218
|
if (iterationType === 'RECURSIVE') {
|
|
1189
1219
|
const dfs = (cur) => {
|
|
@@ -1197,10 +1227,10 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1197
1227
|
if (this.isRealNode(cur.right))
|
|
1198
1228
|
dfs(cur.right);
|
|
1199
1229
|
};
|
|
1200
|
-
dfs(
|
|
1230
|
+
dfs(startNode);
|
|
1201
1231
|
}
|
|
1202
1232
|
else {
|
|
1203
|
-
const queue = new queue_1.Queue([
|
|
1233
|
+
const queue = new queue_1.Queue([startNode]);
|
|
1204
1234
|
while (queue.size > 0) {
|
|
1205
1235
|
const cur = queue.shift();
|
|
1206
1236
|
if (this.isRealNode(cur)) {
|
|
@@ -1225,7 +1255,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1225
1255
|
* @param {C} callback - The `callback` parameter is a function that will be applied to each node in
|
|
1226
1256
|
* the binary tree during the traversal. It is used to process each node and determine what
|
|
1227
1257
|
* information to include in the output for each level of the tree.
|
|
1228
|
-
* @param {
|
|
1258
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
|
|
1229
1259
|
* `listLevels` function represents the starting point for traversing the binary tree. It can be
|
|
1230
1260
|
* either a key, a node, or an entry in the binary tree. If not provided, the default value is the
|
|
1231
1261
|
* root of the binary tree.
|
|
@@ -1240,10 +1270,10 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1240
1270
|
* level in a binary tree. Each inner array contains the return value of the provided callback
|
|
1241
1271
|
* function applied to the nodes at that level.
|
|
1242
1272
|
*/
|
|
1243
|
-
listLevels(callback = this.
|
|
1244
|
-
|
|
1273
|
+
listLevels(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType, includeNull = false) {
|
|
1274
|
+
startNode = this.ensureNode(startNode);
|
|
1245
1275
|
const levelsNodes = [];
|
|
1246
|
-
if (!
|
|
1276
|
+
if (!startNode)
|
|
1247
1277
|
return levelsNodes;
|
|
1248
1278
|
if (iterationType === 'RECURSIVE') {
|
|
1249
1279
|
const _recursive = (node, level) => {
|
|
@@ -1263,10 +1293,10 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1263
1293
|
_recursive(node.right, level + 1);
|
|
1264
1294
|
}
|
|
1265
1295
|
};
|
|
1266
|
-
_recursive(
|
|
1296
|
+
_recursive(startNode, 0);
|
|
1267
1297
|
}
|
|
1268
1298
|
else {
|
|
1269
|
-
const stack = [[
|
|
1299
|
+
const stack = [[startNode, 0]];
|
|
1270
1300
|
while (stack.length > 0) {
|
|
1271
1301
|
const head = stack.pop();
|
|
1272
1302
|
const [node, level] = head;
|
|
@@ -1297,11 +1327,11 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1297
1327
|
* Morris Traversal algorithm with different order patterns.
|
|
1298
1328
|
* @param {C} callback - The `callback` parameter in the `morris` function is a function that will be
|
|
1299
1329
|
* called on each node in the binary tree during the traversal. It is of type `C`, which extends the
|
|
1300
|
-
* `
|
|
1330
|
+
* `NodeCallback<NODE>` type. The default value for `callback` is `this._DEFAULT
|
|
1301
1331
|
* @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `morris` function specifies
|
|
1302
1332
|
* the type of Depth-First Search (DFS) order pattern to traverse the binary tree. The possible
|
|
1303
1333
|
* values for the `pattern` parameter are:
|
|
1304
|
-
* @param {
|
|
1334
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `morris`
|
|
1305
1335
|
* function is the starting point for the Morris traversal algorithm. It represents the root node of
|
|
1306
1336
|
* the binary tree or the node from which the traversal should begin. It can be provided as either a
|
|
1307
1337
|
* key, a node, an entry, or a reference
|
|
@@ -1309,12 +1339,12 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1309
1339
|
* provided callback function to each node in the binary tree in the specified order pattern (IN,
|
|
1310
1340
|
* PRE, or POST).
|
|
1311
1341
|
*/
|
|
1312
|
-
morris(callback = this.
|
|
1313
|
-
|
|
1314
|
-
if (!
|
|
1342
|
+
morris(callback = this._DEFAULT_NODE_CALLBACK, pattern = 'IN', startNode = this._root) {
|
|
1343
|
+
startNode = this.ensureNode(startNode);
|
|
1344
|
+
if (!startNode)
|
|
1315
1345
|
return [];
|
|
1316
1346
|
const ans = [];
|
|
1317
|
-
let cur =
|
|
1347
|
+
let cur = startNode;
|
|
1318
1348
|
const _reverseEdge = (node) => {
|
|
1319
1349
|
let pre = null;
|
|
1320
1350
|
let next = null;
|
|
@@ -1389,7 +1419,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1389
1419
|
}
|
|
1390
1420
|
cur = cur.right;
|
|
1391
1421
|
}
|
|
1392
|
-
_printEdge(
|
|
1422
|
+
_printEdge(startNode);
|
|
1393
1423
|
break;
|
|
1394
1424
|
}
|
|
1395
1425
|
return ans;
|
|
@@ -1410,9 +1440,15 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1410
1440
|
this.bfs(node => {
|
|
1411
1441
|
if (node === null)
|
|
1412
1442
|
cloned.add(null);
|
|
1413
|
-
else
|
|
1414
|
-
|
|
1443
|
+
else {
|
|
1444
|
+
if (this._isMapMode)
|
|
1445
|
+
cloned.add([node.key, this._store.get(node.key)]);
|
|
1446
|
+
else
|
|
1447
|
+
cloned.add([node.key, node.value]);
|
|
1448
|
+
}
|
|
1415
1449
|
}, this._root, this.iterationType, true);
|
|
1450
|
+
if (this._isMapMode)
|
|
1451
|
+
cloned._store = this._store;
|
|
1416
1452
|
return cloned;
|
|
1417
1453
|
}
|
|
1418
1454
|
/**
|
|
@@ -1479,7 +1515,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1479
1515
|
*
|
|
1480
1516
|
* The function `toVisual` in TypeScript overrides the visual representation of a binary tree with
|
|
1481
1517
|
* customizable options for displaying undefined, null, and sentinel nodes.
|
|
1482
|
-
* @param {
|
|
1518
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
|
|
1483
1519
|
* `toVisual` method is used to specify the starting point for visualizing the binary tree structure.
|
|
1484
1520
|
* It can be a node, key, entry, or the root of the tree. If no specific starting point is provided,
|
|
1485
1521
|
* the default is set to the root
|
|
@@ -1491,21 +1527,18 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1491
1527
|
* the lines to the output string. The final output string contains the visual representation of the
|
|
1492
1528
|
* binary tree with the specified options.
|
|
1493
1529
|
*/
|
|
1494
|
-
toVisual(
|
|
1495
|
-
const opts = Object.assign({ isShowUndefined: false, isShowNull:
|
|
1496
|
-
|
|
1530
|
+
toVisual(startNode = this._root, options) {
|
|
1531
|
+
const opts = Object.assign({ isShowUndefined: false, isShowNull: true, isShowRedBlackNIL: false }, options);
|
|
1532
|
+
startNode = this.ensureNode(startNode);
|
|
1497
1533
|
let output = '';
|
|
1498
|
-
if (!
|
|
1534
|
+
if (!startNode)
|
|
1499
1535
|
return output;
|
|
1500
1536
|
if (opts.isShowUndefined)
|
|
1501
|
-
output += `U for undefined
|
|
1502
|
-
`;
|
|
1537
|
+
output += `U for undefined\n`;
|
|
1503
1538
|
if (opts.isShowNull)
|
|
1504
|
-
output += `N for null
|
|
1505
|
-
`;
|
|
1539
|
+
output += `N for null\n`;
|
|
1506
1540
|
if (opts.isShowRedBlackNIL)
|
|
1507
|
-
output += `S for Sentinel Node(NIL)
|
|
1508
|
-
`;
|
|
1541
|
+
output += `S for Sentinel Node(NIL)\n`;
|
|
1509
1542
|
const display = (root) => {
|
|
1510
1543
|
const [lines, , ,] = this._displayAux(root, opts);
|
|
1511
1544
|
let paragraph = '';
|
|
@@ -1514,9 +1547,27 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1514
1547
|
}
|
|
1515
1548
|
output += paragraph;
|
|
1516
1549
|
};
|
|
1517
|
-
display(
|
|
1550
|
+
display(startNode);
|
|
1518
1551
|
return output;
|
|
1519
1552
|
}
|
|
1553
|
+
/**
|
|
1554
|
+
* Time Complexity: O(n)
|
|
1555
|
+
* Space Complexity: O(n)
|
|
1556
|
+
*
|
|
1557
|
+
* The function `print` in TypeScript overrides the default print behavior to log a visual
|
|
1558
|
+
* representation of the binary tree to the console.
|
|
1559
|
+
* @param {BinaryTreePrintOptions} [options] - The `options` parameter is used to specify the
|
|
1560
|
+
* printing options for the binary tree. It is an optional parameter that allows you to customize how
|
|
1561
|
+
* the binary tree is printed, such as choosing between different traversal orders or formatting
|
|
1562
|
+
* options.
|
|
1563
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
|
|
1564
|
+
* `override print` method is used to specify the starting point for printing the binary tree. It can
|
|
1565
|
+
* be either a key, a node, an entry, or the root of the tree. If no specific starting point is
|
|
1566
|
+
* provided, the default value is set to
|
|
1567
|
+
*/
|
|
1568
|
+
print(options, startNode = this._root) {
|
|
1569
|
+
console.log(this.toVisual(startNode, options));
|
|
1570
|
+
}
|
|
1520
1571
|
/**
|
|
1521
1572
|
* Time complexity: O(n)
|
|
1522
1573
|
* Space complexity: O(n)
|
|
@@ -1525,13 +1576,13 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1525
1576
|
* the specified order pattern and callback function.
|
|
1526
1577
|
* @param {C} callback - The `callback` parameter in the `_dfs` method is a function that will be
|
|
1527
1578
|
* called on each node visited during the depth-first search traversal. It is of type `C`, which
|
|
1528
|
-
* extends `
|
|
1579
|
+
* extends `NodeCallback<OptNodeOrNull<NODE>>`. The default value for this parameter is `this._DEFAULT
|
|
1529
1580
|
* @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `_dfs` method specifies the
|
|
1530
1581
|
* order in which the nodes are visited during the Depth-First Search traversal. It can have one of
|
|
1531
1582
|
* the following values:
|
|
1532
|
-
* @param {
|
|
1583
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `_dfs`
|
|
1533
1584
|
* method is used to specify the starting point for the depth-first search traversal in a binary
|
|
1534
|
-
* tree. It can be provided as either a `
|
|
1585
|
+
* tree. It can be provided as either a `BTNRep` object or a reference to the root node
|
|
1535
1586
|
* of the tree. If no specific
|
|
1536
1587
|
* @param {IterationType} iterationType - The `iterationType` parameter in the `_dfs` method
|
|
1537
1588
|
* specifies the type of iteration to be performed during the Depth-First Search (DFS) traversal of a
|
|
@@ -1559,13 +1610,13 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1559
1610
|
* @returns The function `_dfs` returns an array of the return type of the callback function provided
|
|
1560
1611
|
* as input.
|
|
1561
1612
|
*/
|
|
1562
|
-
_dfs(callback = this.
|
|
1613
|
+
_dfs(callback = this._DEFAULT_NODE_CALLBACK, pattern = 'IN', startNode = this._root, iterationType = this.iterationType, includeNull = false, shouldVisitLeft = node => !!node, shouldVisitRight = node => !!node, shouldVisitRoot = node => {
|
|
1563
1614
|
if (includeNull)
|
|
1564
1615
|
return this.isRealNodeOrNull(node);
|
|
1565
1616
|
return this.isRealNode(node);
|
|
1566
1617
|
}, shouldProcessRoot = node => this.isRealNodeOrNull(node)) {
|
|
1567
|
-
|
|
1568
|
-
if (!
|
|
1618
|
+
startNode = this.ensureNode(startNode);
|
|
1619
|
+
if (!startNode)
|
|
1569
1620
|
return [];
|
|
1570
1621
|
const ans = [];
|
|
1571
1622
|
if (iterationType === 'RECURSIVE') {
|
|
@@ -1601,10 +1652,10 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1601
1652
|
break;
|
|
1602
1653
|
}
|
|
1603
1654
|
};
|
|
1604
|
-
dfs(
|
|
1655
|
+
dfs(startNode);
|
|
1605
1656
|
}
|
|
1606
1657
|
else {
|
|
1607
|
-
const stack = [{ opt: constants_1.DFSOperation.VISIT, node:
|
|
1658
|
+
const stack = [{ opt: constants_1.DFSOperation.VISIT, node: startNode }];
|
|
1608
1659
|
const pushLeft = (cur) => {
|
|
1609
1660
|
var _a;
|
|
1610
1661
|
if (shouldVisitLeft(cur.node))
|
|
@@ -1680,7 +1731,10 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1680
1731
|
}
|
|
1681
1732
|
current = stack.pop();
|
|
1682
1733
|
if (this.isRealNode(current)) {
|
|
1683
|
-
|
|
1734
|
+
if (this._isMapMode)
|
|
1735
|
+
yield [current.key, this._store.get(current.key)];
|
|
1736
|
+
else
|
|
1737
|
+
yield [current.key, current.value];
|
|
1684
1738
|
current = current.right;
|
|
1685
1739
|
}
|
|
1686
1740
|
}
|
|
@@ -1689,7 +1743,10 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1689
1743
|
if (node.left && this.isRealNode(node)) {
|
|
1690
1744
|
yield* this[Symbol.iterator](node.left);
|
|
1691
1745
|
}
|
|
1692
|
-
|
|
1746
|
+
if (this._isMapMode)
|
|
1747
|
+
yield [node.key, this._store.get(node.key)];
|
|
1748
|
+
else
|
|
1749
|
+
yield [node.key, node.value];
|
|
1693
1750
|
if (node.right && this.isRealNode(node)) {
|
|
1694
1751
|
yield* this[Symbol.iterator](node.right);
|
|
1695
1752
|
}
|
|
@@ -1767,12 +1824,12 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1767
1824
|
* Space Complexity: O(1)
|
|
1768
1825
|
*
|
|
1769
1826
|
* The _swapProperties function swaps key and value properties between two nodes in a binary tree.
|
|
1770
|
-
* @param {
|
|
1771
|
-
* `_swapProperties` method can be either a
|
|
1827
|
+
* @param {BTNRep<K, V, NODE> | R} srcNode - The `srcNode` parameter in the
|
|
1828
|
+
* `_swapProperties` method can be either a BTNRep object containing key and value
|
|
1772
1829
|
* properties, or it can be of type R.
|
|
1773
|
-
* @param {
|
|
1830
|
+
* @param {BTNRep<K, V, NODE> | R} destNode - The `destNode` parameter in the
|
|
1774
1831
|
* `_swapProperties` method represents the node or entry where the properties will be swapped with
|
|
1775
|
-
* the `srcNode`. It can be of type `
|
|
1832
|
+
* the `srcNode`. It can be of type `BTNRep<K, V, NODE>` or `R`. The method ensures that
|
|
1776
1833
|
* both `srcNode
|
|
1777
1834
|
* @returns The `_swapProperties` method returns either the `destNode` with its key and value swapped
|
|
1778
1835
|
* with the `srcNode`, or `undefined` if either `srcNode` or `destNode` is falsy.
|
|
@@ -1785,9 +1842,11 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1785
1842
|
const tempNode = this.createNode(key, value);
|
|
1786
1843
|
if (tempNode) {
|
|
1787
1844
|
destNode.key = srcNode.key;
|
|
1788
|
-
|
|
1845
|
+
if (!this._isMapMode)
|
|
1846
|
+
destNode.value = srcNode.value;
|
|
1789
1847
|
srcNode.key = tempNode.key;
|
|
1790
|
-
|
|
1848
|
+
if (!this._isMapMode)
|
|
1849
|
+
srcNode.value = tempNode.value;
|
|
1791
1850
|
}
|
|
1792
1851
|
return destNode;
|
|
1793
1852
|
}
|
|
@@ -1830,7 +1889,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1830
1889
|
*
|
|
1831
1890
|
* The function _setRoot sets the root node of a data structure while updating the parent reference
|
|
1832
1891
|
* of the previous root node.
|
|
1833
|
-
* @param v - The parameter `v` in the `_setRoot` method is of type `
|
|
1892
|
+
* @param v - The parameter `v` in the `_setRoot` method is of type `OptNodeOrNull<NODE>`, which means
|
|
1834
1893
|
* it can either be an optional `NODE` type or `null`.
|
|
1835
1894
|
*/
|
|
1836
1895
|
_setRoot(v) {
|
|
@@ -1845,45 +1904,112 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1845
1904
|
*
|
|
1846
1905
|
* The function `_ensurePredicate` in TypeScript ensures that the input is converted into a valid
|
|
1847
1906
|
* predicate function for a binary tree node.
|
|
1848
|
-
* @param {
|
|
1907
|
+
* @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate - The
|
|
1849
1908
|
* `_ensurePredicate` method in the provided code snippet is responsible for ensuring that the input
|
|
1850
|
-
* parameter `
|
|
1909
|
+
* parameter `keyNodeEntryRawOrPredicate` is transformed into a valid predicate function that can be
|
|
1851
1910
|
* used for filtering nodes in a binary tree.
|
|
1852
|
-
* @returns A
|
|
1911
|
+
* @returns A NodePredicate<NODE> function is being returned.
|
|
1853
1912
|
*/
|
|
1854
|
-
_ensurePredicate(
|
|
1855
|
-
if (
|
|
1913
|
+
_ensurePredicate(keyNodeEntryRawOrPredicate) {
|
|
1914
|
+
if (keyNodeEntryRawOrPredicate === null || keyNodeEntryRawOrPredicate === undefined)
|
|
1856
1915
|
return (node) => (node ? false : false);
|
|
1857
|
-
if (this.
|
|
1858
|
-
return
|
|
1859
|
-
if (this.isRealNode(
|
|
1860
|
-
return (node) => node ===
|
|
1861
|
-
if (this.isEntry(
|
|
1862
|
-
const [key] =
|
|
1916
|
+
if (this._isPredicate(keyNodeEntryRawOrPredicate))
|
|
1917
|
+
return keyNodeEntryRawOrPredicate;
|
|
1918
|
+
if (this.isRealNode(keyNodeEntryRawOrPredicate))
|
|
1919
|
+
return (node) => node === keyNodeEntryRawOrPredicate;
|
|
1920
|
+
if (this.isEntry(keyNodeEntryRawOrPredicate)) {
|
|
1921
|
+
const [key] = keyNodeEntryRawOrPredicate;
|
|
1863
1922
|
return (node) => node.key === key;
|
|
1864
1923
|
}
|
|
1865
|
-
if (this.isKey(
|
|
1866
|
-
return (node) => node.key ===
|
|
1924
|
+
if (this.isKey(keyNodeEntryRawOrPredicate))
|
|
1925
|
+
return (node) => node.key === keyNodeEntryRawOrPredicate;
|
|
1867
1926
|
if (this._toEntryFn) {
|
|
1868
|
-
const [key] = this._toEntryFn(
|
|
1927
|
+
const [key] = this._toEntryFn(keyNodeEntryRawOrPredicate);
|
|
1869
1928
|
return (node) => node.key === key;
|
|
1870
1929
|
}
|
|
1871
|
-
return (node) => node.key ===
|
|
1930
|
+
return (node) => node.key === keyNodeEntryRawOrPredicate;
|
|
1872
1931
|
}
|
|
1873
1932
|
/**
|
|
1874
1933
|
* Time Complexity: O(1)
|
|
1875
1934
|
* Space Complexity: O(1)
|
|
1876
1935
|
*
|
|
1877
|
-
* The function `
|
|
1936
|
+
* The function `_isPredicate` checks if a given parameter is a function.
|
|
1878
1937
|
* @param {any} p - The parameter `p` is a variable of type `any`, which means it can hold any type
|
|
1879
|
-
* of value. In this context, the function `
|
|
1880
|
-
* satisfies the type `
|
|
1938
|
+
* of value. In this context, the function `_isPredicate` is checking if `p` is a function that
|
|
1939
|
+
* satisfies the type `NodePredicate<NODE>`.
|
|
1881
1940
|
* @returns The function is checking if the input `p` is a function and returning a boolean value
|
|
1882
1941
|
* based on that check. If `p` is a function, it will return `true`, indicating that `p` is a
|
|
1883
1942
|
* predicate function for a binary tree node. If `p` is not a function, it will return `false`.
|
|
1884
1943
|
*/
|
|
1885
|
-
|
|
1944
|
+
_isPredicate(p) {
|
|
1886
1945
|
return typeof p === 'function';
|
|
1887
1946
|
}
|
|
1947
|
+
/**
|
|
1948
|
+
* Time Complexity: O(1)
|
|
1949
|
+
* Space Complexity: O(1)
|
|
1950
|
+
*
|
|
1951
|
+
* The function `_getKey` in TypeScript returns the key from a given input, which can be a node,
|
|
1952
|
+
* entry, raw data, or null/undefined.
|
|
1953
|
+
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The `_getKey` method you provided is a
|
|
1954
|
+
* TypeScript method that takes in a parameter `keyNodeEntryOrRaw` of type `BTNRep<K, V, NODE> | R`,
|
|
1955
|
+
* where `BTNRep` is a generic type with keys `K`, `V`, and `NODE`, and `
|
|
1956
|
+
* @returns The `_getKey` method returns the key value extracted from the `keyNodeEntryOrRaw`
|
|
1957
|
+
* parameter. The return value can be a key value of type `K`, `null`, or `undefined`, depending on
|
|
1958
|
+
* the conditions checked in the method.
|
|
1959
|
+
*/
|
|
1960
|
+
_getKey(keyNodeEntryOrRaw) {
|
|
1961
|
+
if (keyNodeEntryOrRaw === null)
|
|
1962
|
+
return null;
|
|
1963
|
+
if (keyNodeEntryOrRaw === undefined)
|
|
1964
|
+
return;
|
|
1965
|
+
if (keyNodeEntryOrRaw === this._NIL)
|
|
1966
|
+
return;
|
|
1967
|
+
if (this.isNode(keyNodeEntryOrRaw))
|
|
1968
|
+
return keyNodeEntryOrRaw.key;
|
|
1969
|
+
if (this.isEntry(keyNodeEntryOrRaw))
|
|
1970
|
+
return keyNodeEntryOrRaw[0];
|
|
1971
|
+
if (this.isRaw(keyNodeEntryOrRaw)) {
|
|
1972
|
+
if (this._toEntryFn) {
|
|
1973
|
+
const [key] = this._toEntryFn(keyNodeEntryOrRaw);
|
|
1974
|
+
return key;
|
|
1975
|
+
}
|
|
1976
|
+
return;
|
|
1977
|
+
}
|
|
1978
|
+
return keyNodeEntryOrRaw;
|
|
1979
|
+
}
|
|
1980
|
+
/**
|
|
1981
|
+
* Time Complexity: O(1)
|
|
1982
|
+
* Space Complexity: O(1)
|
|
1983
|
+
*
|
|
1984
|
+
* The function `_setValue` sets a value in a store based on a key, handling cases where the key or
|
|
1985
|
+
* value is null or undefined.
|
|
1986
|
+
* @param {K | null | undefined} key - The `key` parameter can be of type `K`, `null`, or
|
|
1987
|
+
* `undefined`.
|
|
1988
|
+
* @param {V | undefined} value - The `value` parameter in the `_setValue` method can be of type `V`
|
|
1989
|
+
* or `undefined`.
|
|
1990
|
+
* @returns The method `_setValue` returns `false` if either the `key` is `null` or `undefined`, or
|
|
1991
|
+
* if the `value` is `undefined`. Otherwise, it returns the result of calling the `set` method on the
|
|
1992
|
+
* `_store` object with the `key` and `value` arguments.
|
|
1993
|
+
*/
|
|
1994
|
+
_setValue(key, value) {
|
|
1995
|
+
if (key === null || key === undefined)
|
|
1996
|
+
return false;
|
|
1997
|
+
if (value === undefined)
|
|
1998
|
+
return false;
|
|
1999
|
+
return this._store.set(key, value);
|
|
2000
|
+
}
|
|
2001
|
+
/**
|
|
2002
|
+
* The _clearNodes function sets the root node to undefined and resets the size to 0.
|
|
2003
|
+
*/
|
|
2004
|
+
_clearNodes() {
|
|
2005
|
+
this._setRoot(undefined);
|
|
2006
|
+
this._size = 0;
|
|
2007
|
+
}
|
|
2008
|
+
/**
|
|
2009
|
+
* The _clearValues function clears all values stored in the _store object.
|
|
2010
|
+
*/
|
|
2011
|
+
_clearValues() {
|
|
2012
|
+
this._store.clear();
|
|
2013
|
+
}
|
|
1888
2014
|
}
|
|
1889
2015
|
exports.BinaryTree = BinaryTree;
|