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