data-structure-typed 1.37.2 → 1.37.4
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/CHANGELOG.md +3 -1
- package/dist/data-structures/binary-tree/avl-tree.d.ts +44 -38
- package/dist/data-structures/binary-tree/avl-tree.js +46 -40
- package/dist/data-structures/binary-tree/avl-tree.js.map +1 -1
- package/dist/data-structures/binary-tree/binary-tree.d.ts +305 -192
- package/dist/data-structures/binary-tree/binary-tree.js +304 -201
- package/dist/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/data-structures/binary-tree/bst.d.ts +111 -64
- package/dist/data-structures/binary-tree/bst.js +132 -85
- package/dist/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/data-structures/binary-tree/tree-multiset.d.ts +49 -41
- package/dist/data-structures/binary-tree/tree-multiset.js +49 -41
- package/dist/data-structures/binary-tree/tree-multiset.js.map +1 -1
- package/dist/types/data-structures/binary-tree.d.ts +2 -2
- package/dist/types/data-structures/binary-tree.js +6 -6
- package/dist/types/data-structures/binary-tree.js.map +1 -1
- package/lib/data-structures/binary-tree/avl-tree.d.ts +44 -38
- package/lib/data-structures/binary-tree/avl-tree.js +46 -40
- package/lib/data-structures/binary-tree/binary-tree.d.ts +305 -192
- package/lib/data-structures/binary-tree/binary-tree.js +305 -202
- package/lib/data-structures/binary-tree/bst.d.ts +111 -64
- package/lib/data-structures/binary-tree/bst.js +133 -86
- package/lib/data-structures/binary-tree/tree-multiset.d.ts +49 -41
- package/lib/data-structures/binary-tree/tree-multiset.js +50 -42
- package/lib/types/data-structures/binary-tree.d.ts +2 -2
- package/lib/types/data-structures/binary-tree.js +5 -5
- package/package.json +6 -6
- package/src/data-structures/binary-tree/avl-tree.ts +46 -40
- package/src/data-structures/binary-tree/binary-tree.ts +328 -207
- package/src/data-structures/binary-tree/bst.ts +135 -88
- package/src/data-structures/binary-tree/tree-multiset.ts +50 -42
- package/src/types/data-structures/binary-tree.ts +2 -2
- package/test/config.ts +1 -0
- package/test/integration/avl-tree.test.ts +7 -8
- package/test/integration/bst.test.ts +17 -16
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +50 -0
- package/test/unit/data-structures/binary-tree/bst.test.ts +8 -1
- package/test/unit/data-structures/binary-tree/tree-multiset.test.ts +2 -1
- package/test/unit/data-structures/linked-list/linked-list.test.ts +1 -1
- package/test/utils/big-o.ts +2 -1
- package/umd/bundle.min.js +1 -1
- package/umd/bundle.min.js.map +1 -1
|
@@ -15,39 +15,50 @@ import type {
|
|
|
15
15
|
MapCallback,
|
|
16
16
|
MapCallbackReturn
|
|
17
17
|
} from '../../types';
|
|
18
|
-
import {
|
|
19
|
-
BinaryTreeDeletedResult,
|
|
20
|
-
DFSOrderPattern,
|
|
21
|
-
FamilyPosition,
|
|
22
|
-
LoopType
|
|
23
|
-
} from '../../types';
|
|
18
|
+
import {BinaryTreeDeletedResult, DFSOrderPattern, FamilyPosition, IterationType} from '../../types';
|
|
24
19
|
import {IBinaryTree} from '../../interfaces';
|
|
25
20
|
import {trampoline} from '../../utils';
|
|
26
21
|
import {Queue} from '../queue';
|
|
27
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Represents a node in a binary tree.
|
|
25
|
+
* @template V - The type of data stored in the node.
|
|
26
|
+
* @template FAMILY - The type of the family relationship in the binary tree.
|
|
27
|
+
*/
|
|
28
28
|
export class BinaryTreeNode<V = any, FAMILY extends BinaryTreeNode<V, FAMILY> = BinaryTreeNodeNested<V>> {
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
31
|
-
* @param {BinaryTreeNodeKey} key - The
|
|
32
|
-
*
|
|
33
|
-
* @param {V} [val] - The "val" parameter is an optional parameter of type V. It represents the value that will be
|
|
34
|
-
* stored in the binary tree node. If no value is provided, it will be set to undefined.
|
|
30
|
+
* Creates a new instance of BinaryTreeNode.
|
|
31
|
+
* @param {BinaryTreeNodeKey} key - The key associated with the node.
|
|
32
|
+
* @param {V} val - The value stored in the node.
|
|
35
33
|
*/
|
|
36
34
|
constructor(key: BinaryTreeNodeKey, val?: V) {
|
|
37
35
|
this.key = key;
|
|
38
36
|
this.val = val;
|
|
39
37
|
}
|
|
40
38
|
|
|
39
|
+
/**
|
|
40
|
+
* The key associated with the node.
|
|
41
|
+
*/
|
|
41
42
|
key: BinaryTreeNodeKey;
|
|
42
43
|
|
|
44
|
+
/**
|
|
45
|
+
* The value stored in the node.
|
|
46
|
+
*/
|
|
43
47
|
val: V | undefined;
|
|
44
48
|
|
|
45
49
|
private _left: FAMILY | null | undefined;
|
|
46
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Get the left child node.
|
|
53
|
+
*/
|
|
47
54
|
get left(): FAMILY | null | undefined {
|
|
48
55
|
return this._left;
|
|
49
56
|
}
|
|
50
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Set the left child node.
|
|
60
|
+
* @param {FAMILY | null | undefined} v - The left child node.
|
|
61
|
+
*/
|
|
51
62
|
set left(v: FAMILY | null | undefined) {
|
|
52
63
|
if (v) {
|
|
53
64
|
v.parent = this as unknown as FAMILY;
|
|
@@ -57,10 +68,17 @@ export class BinaryTreeNode<V = any, FAMILY extends BinaryTreeNode<V, FAMILY> =
|
|
|
57
68
|
|
|
58
69
|
private _right: FAMILY | null | undefined;
|
|
59
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Get the right child node.
|
|
73
|
+
*/
|
|
60
74
|
get right(): FAMILY | null | undefined {
|
|
61
75
|
return this._right;
|
|
62
76
|
}
|
|
63
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Set the right child node.
|
|
80
|
+
* @param {FAMILY | null | undefined} v - The right child node.
|
|
81
|
+
*/
|
|
64
82
|
set right(v: FAMILY | null | undefined) {
|
|
65
83
|
if (v) {
|
|
66
84
|
v.parent = this as unknown as FAMILY;
|
|
@@ -68,11 +86,14 @@ export class BinaryTreeNode<V = any, FAMILY extends BinaryTreeNode<V, FAMILY> =
|
|
|
68
86
|
this._right = v;
|
|
69
87
|
}
|
|
70
88
|
|
|
89
|
+
/**
|
|
90
|
+
* The parent node of the current node.
|
|
91
|
+
*/
|
|
71
92
|
parent: FAMILY | null | undefined;
|
|
72
93
|
|
|
73
94
|
/**
|
|
74
|
-
*
|
|
75
|
-
* @returns
|
|
95
|
+
* Get the position of the node within its family.
|
|
96
|
+
* @returns {FamilyPosition} - The family position of the node.
|
|
76
97
|
*/
|
|
77
98
|
get familyPosition(): FamilyPosition {
|
|
78
99
|
const that = this as unknown as FAMILY;
|
|
@@ -102,64 +123,75 @@ export class BinaryTreeNode<V = any, FAMILY extends BinaryTreeNode<V, FAMILY> =
|
|
|
102
123
|
}
|
|
103
124
|
}
|
|
104
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Represents a binary tree data structure.
|
|
128
|
+
* @template N - The type of the binary tree's nodes.
|
|
129
|
+
*/
|
|
105
130
|
export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode> implements IBinaryTree<N> {
|
|
106
131
|
/**
|
|
107
|
-
*
|
|
108
|
-
* @param {BinaryTreeOptions} [options] - The
|
|
109
|
-
* constructor of the `BinaryTree` class. It allows you to customize the behavior of the binary tree by providing
|
|
110
|
-
* different configuration options.
|
|
132
|
+
* Creates a new instance of BinaryTree.
|
|
133
|
+
* @param {BinaryTreeOptions} [options] - The options for the binary tree.
|
|
111
134
|
*/
|
|
112
135
|
constructor(options?: BinaryTreeOptions) {
|
|
113
136
|
if (options !== undefined) {
|
|
114
|
-
const {
|
|
115
|
-
this._loopType =
|
|
137
|
+
const { iterationType = IterationType.ITERATIVE } = options;
|
|
138
|
+
this._loopType = iterationType;
|
|
116
139
|
}
|
|
117
140
|
}
|
|
118
141
|
|
|
119
142
|
/**
|
|
120
|
-
*
|
|
121
|
-
* @param {BinaryTreeNodeKey} key - The
|
|
122
|
-
*
|
|
123
|
-
* @
|
|
124
|
-
* stored in the node.
|
|
125
|
-
* @returns a new instance of a BinaryTreeNode with the specified key and value.
|
|
143
|
+
* Creates a new instance of BinaryTreeNode with the given key and value.
|
|
144
|
+
* @param {BinaryTreeNodeKey} key - The key for the new node.
|
|
145
|
+
* @param {N['val']} val - The value for the new node.
|
|
146
|
+
* @returns {N} - The newly created BinaryTreeNode.
|
|
126
147
|
*/
|
|
127
148
|
createNode(key: BinaryTreeNodeKey, val?: N['val']): N {
|
|
128
149
|
return new BinaryTreeNode<N['val'], N>(key, val) as N;
|
|
129
150
|
}
|
|
130
151
|
|
|
131
|
-
// TODO placeholder node may need redesigned
|
|
132
152
|
private _root: N | null = null;
|
|
133
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Get the root node of the binary tree.
|
|
156
|
+
*/
|
|
134
157
|
get root(): N | null {
|
|
135
158
|
return this._root;
|
|
136
159
|
}
|
|
137
160
|
|
|
138
161
|
private _size = 0;
|
|
139
162
|
|
|
163
|
+
/**
|
|
164
|
+
* Get the number of nodes in the binary tree.
|
|
165
|
+
*/
|
|
140
166
|
get size(): number {
|
|
141
167
|
return this._size;
|
|
142
168
|
}
|
|
143
169
|
|
|
144
|
-
private _loopType:
|
|
170
|
+
private _loopType: IterationType = IterationType.ITERATIVE;
|
|
145
171
|
|
|
146
|
-
|
|
172
|
+
/**
|
|
173
|
+
* Get the iteration type used in the binary tree.
|
|
174
|
+
*/
|
|
175
|
+
get iterationType(): IterationType {
|
|
147
176
|
return this._loopType;
|
|
148
177
|
}
|
|
149
178
|
|
|
150
|
-
|
|
179
|
+
/**
|
|
180
|
+
* Set the iteration type for the binary tree.
|
|
181
|
+
* @param {IterationType} v - The new iteration type to set.
|
|
182
|
+
*/
|
|
183
|
+
set iterationType(v: IterationType) {
|
|
151
184
|
this._loopType = v;
|
|
152
185
|
}
|
|
153
186
|
|
|
154
187
|
/**
|
|
155
|
-
*
|
|
156
|
-
* @param {N} srcNode - The source node
|
|
157
|
-
* @param {N} destNode - The
|
|
158
|
-
*
|
|
159
|
-
* @returns The `destNode` is being returned.
|
|
188
|
+
* Swap the data of two nodes in the binary tree.
|
|
189
|
+
* @param {N} srcNode - The source node to swap.
|
|
190
|
+
* @param {N} destNode - The destination node to swap.
|
|
191
|
+
* @returns {N} - The destination node after the swap.
|
|
160
192
|
*/
|
|
161
193
|
protected _swap(srcNode: N, destNode: N): N {
|
|
162
|
-
const {key, val} = destNode;
|
|
194
|
+
const { key, val } = destNode;
|
|
163
195
|
const tempNode = this.createNode(key, val);
|
|
164
196
|
|
|
165
197
|
if (tempNode) {
|
|
@@ -174,7 +206,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
174
206
|
}
|
|
175
207
|
|
|
176
208
|
/**
|
|
177
|
-
*
|
|
209
|
+
* Clear the binary tree, removing all nodes.
|
|
178
210
|
*/
|
|
179
211
|
clear() {
|
|
180
212
|
this._root = null;
|
|
@@ -182,26 +214,18 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
182
214
|
}
|
|
183
215
|
|
|
184
216
|
/**
|
|
185
|
-
*
|
|
186
|
-
* @returns
|
|
217
|
+
* Check if the binary tree is empty.
|
|
218
|
+
* @returns {boolean} - True if the binary tree is empty, false otherwise.
|
|
187
219
|
*/
|
|
188
220
|
isEmpty(): boolean {
|
|
189
221
|
return this.size === 0;
|
|
190
222
|
}
|
|
191
223
|
|
|
192
224
|
/**
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* The `add` function adds a new node to a binary tree, either by ID or by creating a new node with a given value.
|
|
199
|
-
* @param {BinaryTreeNodeKey | N | null} keyOrNode - The `keyOrNode` parameter can be either a `BinaryTreeNodeKey`, which
|
|
200
|
-
* is a number representing the ID of a binary tree node, or it can be a `N` object, which represents a binary tree
|
|
201
|
-
* node itself. It can also be `null` if no node is specified.
|
|
202
|
-
* @param [val] - The `val` parameter is an optional value that can be assigned to the `val` property of the new node
|
|
203
|
-
* being added to the binary tree.
|
|
204
|
-
* @returns The function `add` returns either the inserted node (`N`), `null`, or `undefined`.
|
|
225
|
+
* Add a node with the given key and value to the binary tree.
|
|
226
|
+
* @param {BinaryTreeNodeKey | N | null} keyOrNode - The key or node to add to the binary tree.
|
|
227
|
+
* @param {N['val']} val - The value for the new node (optional).
|
|
228
|
+
* @returns {N | null | undefined} - The inserted node, or null if nothing was inserted, or undefined if the operation failed.
|
|
205
229
|
*/
|
|
206
230
|
add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val']): N | null | undefined {
|
|
207
231
|
const _bfs = (root: N, newNode: N | null): N | undefined | null => {
|
|
@@ -257,12 +281,12 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
257
281
|
* values, and adds them to the binary tree.
|
|
258
282
|
* @param {(BinaryTreeNodeKey | null)[] | (N | null)[]} keysOrNodes - An array of BinaryTreeNodeKey or BinaryTreeNode
|
|
259
283
|
* objects, or null values.
|
|
260
|
-
* @param {N['val'][]} [
|
|
261
|
-
* the nodes or node IDs being added. It is used to set the value of each node being added. If `
|
|
284
|
+
* @param {N['val'][]} [values] - The `values` parameter is an optional array of values (`N['val'][]`) that corresponds to
|
|
285
|
+
* the nodes or node IDs being added. It is used to set the value of each node being added. If `values` is not provided,
|
|
262
286
|
* the value of the nodes will be `undefined`.
|
|
263
287
|
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
|
|
264
288
|
*/
|
|
265
|
-
addMany(keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[],
|
|
289
|
+
addMany(keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], values?: N['val'][]): (N | null | undefined)[] {
|
|
266
290
|
// TODO not sure addMany not be run multi times
|
|
267
291
|
const inserted: (N | null | undefined)[] = [];
|
|
268
292
|
|
|
@@ -278,7 +302,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
278
302
|
continue;
|
|
279
303
|
}
|
|
280
304
|
|
|
281
|
-
const val =
|
|
305
|
+
const val = values?.[i];
|
|
282
306
|
inserted.push(this.add(keyOrNode, val));
|
|
283
307
|
}
|
|
284
308
|
return inserted;
|
|
@@ -298,12 +322,14 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
298
322
|
return keysOrNodes.length === this.addMany(keysOrNodes, data).length;
|
|
299
323
|
}
|
|
300
324
|
|
|
325
|
+
|
|
301
326
|
/**
|
|
302
|
-
* The `delete` function
|
|
303
|
-
*
|
|
304
|
-
* @param {N | BinaryTreeNodeKey} nodeOrKey - The `nodeOrKey` parameter can be either a node
|
|
305
|
-
*
|
|
306
|
-
*
|
|
327
|
+
* The `delete` function removes a node from a binary search tree and returns the deleted node along
|
|
328
|
+
* with the parent node that needs to be balanced.
|
|
329
|
+
* @param {N | BinaryTreeNodeKey} nodeOrKey - The `nodeOrKey` parameter can be either a node (`N`) or
|
|
330
|
+
* a key (`BinaryTreeNodeKey`). If it is a key, the function will find the corresponding node in the
|
|
331
|
+
* binary tree.
|
|
332
|
+
* @returns an array of `BinaryTreeDeletedResult<N>` objects.
|
|
307
333
|
*/
|
|
308
334
|
delete(nodeOrKey: N | BinaryTreeNodeKey): BinaryTreeDeletedResult<N>[] {
|
|
309
335
|
const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
|
|
@@ -348,10 +374,16 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
348
374
|
}
|
|
349
375
|
|
|
350
376
|
/**
|
|
351
|
-
* The function calculates the depth of a node in a binary tree
|
|
352
|
-
*
|
|
353
|
-
* @param {N | BinaryTreeNodeKey | null}
|
|
354
|
-
*
|
|
377
|
+
* The function `getDepth` calculates the depth of a given node in a binary tree relative to a
|
|
378
|
+
* specified root node.
|
|
379
|
+
* @param {N | BinaryTreeNodeKey | null} distNode - The `distNode` parameter represents the node
|
|
380
|
+
* whose depth we want to find in the binary tree. It can be either a node object (`N`), a key value
|
|
381
|
+
* of the node (`BinaryTreeNodeKey`), or `null`.
|
|
382
|
+
* @param {N | BinaryTreeNodeKey | null} beginRoot - The `beginRoot` parameter represents the
|
|
383
|
+
* starting node from which we want to calculate the depth. It can be either a node object or the key
|
|
384
|
+
* of a node in the binary tree. If no value is provided for `beginRoot`, it defaults to the root
|
|
385
|
+
* node of the binary tree.
|
|
386
|
+
* @returns the depth of the `distNode` relative to the `beginRoot`.
|
|
355
387
|
*/
|
|
356
388
|
getDepth(distNode: N | BinaryTreeNodeKey | null, beginRoot: N | BinaryTreeNodeKey | null = this.root): number {
|
|
357
389
|
if (typeof distNode === 'number') distNode = this.get(distNode);
|
|
@@ -368,17 +400,22 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
368
400
|
}
|
|
369
401
|
|
|
370
402
|
/**
|
|
371
|
-
* The `getHeight` function calculates the maximum height of a binary tree
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
* node
|
|
403
|
+
* The `getHeight` function calculates the maximum height of a binary tree using either recursive or
|
|
404
|
+
* iterative approach.
|
|
405
|
+
* @param {N | BinaryTreeNodeKey | null} beginRoot - The `beginRoot` parameter represents the
|
|
406
|
+
* starting node from which the height of the binary tree is calculated. It can be either a node
|
|
407
|
+
* object (`N`), a key value of a node in the tree (`BinaryTreeNodeKey`), or `null` if no starting
|
|
408
|
+
* node is specified. If `
|
|
409
|
+
* @param iterationType - The `iterationType` parameter is used to determine whether to calculate the
|
|
410
|
+
* height of the binary tree using a recursive approach or an iterative approach. It can have two
|
|
411
|
+
* possible values:
|
|
375
412
|
* @returns the height of the binary tree.
|
|
376
413
|
*/
|
|
377
|
-
getHeight(beginRoot: N | BinaryTreeNodeKey | null = this.root): number {
|
|
414
|
+
getHeight(beginRoot: N | BinaryTreeNodeKey | null = this.root, iterationType = this.iterationType): number {
|
|
378
415
|
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
|
|
379
416
|
if (!beginRoot) return -1;
|
|
380
417
|
|
|
381
|
-
if (
|
|
418
|
+
if (iterationType === IterationType.RECURSIVE) {
|
|
382
419
|
const _getMaxHeight = (cur: N | null | undefined): number => {
|
|
383
420
|
if (!cur) return -1;
|
|
384
421
|
const leftHeight = _getMaxHeight(cur.left);
|
|
@@ -416,17 +453,19 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
416
453
|
protected _defaultCallbackByKey: MapCallback<N> = node => node.key;
|
|
417
454
|
|
|
418
455
|
/**
|
|
419
|
-
* The `getMinHeight` function calculates the minimum height of a binary tree using either a
|
|
420
|
-
* approach.
|
|
421
|
-
* @param {N | null}
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
* @
|
|
456
|
+
* The `getMinHeight` function calculates the minimum height of a binary tree using either a
|
|
457
|
+
* recursive or iterative approach.
|
|
458
|
+
* @param {N | null} beginRoot - The `beginRoot` parameter is the starting node from which we want to
|
|
459
|
+
* calculate the minimum height of the tree. It is optional and defaults to the root of the tree if
|
|
460
|
+
* not provided.
|
|
461
|
+
* @param iterationType - The `iterationType` parameter is used to determine the method of iteration
|
|
462
|
+
* to calculate the minimum height of a binary tree. It can have two possible values:
|
|
463
|
+
* @returns The function `getMinHeight` returns the minimum height of a binary tree.
|
|
425
464
|
*/
|
|
426
|
-
getMinHeight(beginRoot: N | null = this.root): number {
|
|
465
|
+
getMinHeight(beginRoot: N | null = this.root, iterationType = this.iterationType): number {
|
|
427
466
|
if (!beginRoot) return -1;
|
|
428
467
|
|
|
429
|
-
if (
|
|
468
|
+
if (iterationType === IterationType.RECURSIVE) {
|
|
430
469
|
const _getMinHeight = (cur: N | null | undefined): number => {
|
|
431
470
|
if (!cur) return 0;
|
|
432
471
|
if (!cur.left && !cur.right) return 0;
|
|
@@ -466,10 +505,10 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
466
505
|
}
|
|
467
506
|
|
|
468
507
|
/**
|
|
469
|
-
* The function checks if a binary tree is perfectly balanced by comparing the minimum height and the
|
|
470
|
-
* tree.
|
|
471
|
-
* @param {N | null}
|
|
472
|
-
* tree or null
|
|
508
|
+
* The function checks if a binary tree is perfectly balanced by comparing the minimum height and the
|
|
509
|
+
* height of the tree.
|
|
510
|
+
* @param {N | null} beginRoot - The parameter `beginRoot` is of type `N | null`, which means it can
|
|
511
|
+
* either be of type `N` (representing a node in a tree) or `null` (representing an empty tree).
|
|
473
512
|
* @returns The method is returning a boolean value.
|
|
474
513
|
*/
|
|
475
514
|
isPerfectlyBalanced(beginRoot: N | null = this.root): boolean {
|
|
@@ -477,28 +516,38 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
477
516
|
}
|
|
478
517
|
|
|
479
518
|
/**
|
|
480
|
-
* The function `getNodes` returns an array of nodes that match a given property
|
|
481
|
-
*
|
|
482
|
-
* @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter
|
|
483
|
-
* generic type `N`. It represents the property of the
|
|
484
|
-
*
|
|
485
|
-
* @param
|
|
486
|
-
*
|
|
487
|
-
*
|
|
488
|
-
*
|
|
489
|
-
* @
|
|
519
|
+
* The function `getNodes` returns an array of nodes that match a given node property, using either
|
|
520
|
+
* recursive or iterative traversal.
|
|
521
|
+
* @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter is either a
|
|
522
|
+
* `BinaryTreeNodeKey` or a generic type `N`. It represents the property of the node that we are
|
|
523
|
+
* searching for. It can be a specific key value or any other property of the node.
|
|
524
|
+
* @param callback - The `callback` parameter is a function that takes a node as input and returns a
|
|
525
|
+
* value. This value is compared with the `nodeProperty` parameter to determine if the node should be
|
|
526
|
+
* included in the result. The `callback` parameter has a default value of
|
|
527
|
+
* `this._defaultCallbackByKey`, which
|
|
528
|
+
* @param [onlyOne=false] - A boolean value indicating whether to stop searching after finding the
|
|
529
|
+
* first node that matches the nodeProperty. If set to true, the function will return an array with
|
|
530
|
+
* only one element (or an empty array if no matching node is found). If set to false (default), the
|
|
531
|
+
* function will continue searching for all
|
|
532
|
+
* @param {N | null} beginRoot - The `beginRoot` parameter is the starting node from which the
|
|
533
|
+
* traversal of the binary tree will begin. It is optional and defaults to the root of the binary
|
|
534
|
+
* tree.
|
|
535
|
+
* @param iterationType - The `iterationType` parameter determines the type of iteration used to
|
|
536
|
+
* traverse the binary tree. It can have two possible values:
|
|
537
|
+
* @returns The function `getNodes` returns an array of nodes (`N[]`).
|
|
490
538
|
*/
|
|
491
539
|
getNodes(
|
|
492
540
|
nodeProperty: BinaryTreeNodeKey | N,
|
|
493
541
|
callback: MapCallback<N> = this._defaultCallbackByKey,
|
|
494
542
|
onlyOne = false,
|
|
495
|
-
beginRoot: N | null = this.root
|
|
543
|
+
beginRoot: N | null = this.root,
|
|
544
|
+
iterationType = this.iterationType
|
|
496
545
|
): N[] {
|
|
497
546
|
if (!beginRoot) return [];
|
|
498
547
|
|
|
499
548
|
const ans: N[] = [];
|
|
500
549
|
|
|
501
|
-
if (
|
|
550
|
+
if (iterationType === IterationType.RECURSIVE) {
|
|
502
551
|
const _traverse = (cur: N) => {
|
|
503
552
|
if (callback(cur) === nodeProperty) {
|
|
504
553
|
ans.push(cur);
|
|
@@ -529,43 +578,66 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
529
578
|
}
|
|
530
579
|
|
|
531
580
|
/**
|
|
532
|
-
* The function checks if a binary tree node
|
|
533
|
-
* @param
|
|
534
|
-
*
|
|
535
|
-
*
|
|
536
|
-
*
|
|
581
|
+
* The function checks if a binary tree has a node with a given property or key.
|
|
582
|
+
* @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter is the key or value of
|
|
583
|
+
* the node that you want to find in the binary tree. It can be either a `BinaryTreeNodeKey` or a
|
|
584
|
+
* generic type `N`.
|
|
585
|
+
* @param callback - The `callback` parameter is a function that is used to determine whether a node
|
|
586
|
+
* matches the desired criteria. It takes a node as input and returns a boolean value indicating
|
|
587
|
+
* whether the node matches the criteria or not. The default callback function
|
|
588
|
+
* `this._defaultCallbackByKey` is used if no callback function is
|
|
589
|
+
* @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
|
|
590
|
+
* the node from which the search should begin. By default, it is set to `this.root`, which means the
|
|
591
|
+
* search will start from the root node of the binary tree. However, you can provide a different node
|
|
592
|
+
* as
|
|
593
|
+
* @param iterationType - The `iterationType` parameter specifies the type of iteration to be
|
|
594
|
+
* performed when searching for nodes in the binary tree. It can have one of the following values:
|
|
537
595
|
* @returns a boolean value.
|
|
538
596
|
*/
|
|
539
|
-
has(
|
|
597
|
+
has(
|
|
598
|
+
nodeProperty: BinaryTreeNodeKey | N,
|
|
599
|
+
callback: MapCallback<N> = this._defaultCallbackByKey,
|
|
600
|
+
beginRoot = this.root,
|
|
601
|
+
iterationType = this.iterationType
|
|
602
|
+
): boolean {
|
|
540
603
|
// TODO may support finding node by value equal
|
|
541
|
-
return this.getNodes(nodeProperty, callback, true).length > 0;
|
|
604
|
+
return this.getNodes(nodeProperty, callback, true, beginRoot, iterationType).length > 0;
|
|
542
605
|
}
|
|
543
606
|
|
|
544
607
|
/**
|
|
545
|
-
* The function returns the first node that matches the given property
|
|
546
|
-
*
|
|
547
|
-
*
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
*
|
|
553
|
-
*
|
|
608
|
+
* The function `get` returns the first node in a binary tree that matches the given property or key.
|
|
609
|
+
* @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter is the key or value of
|
|
610
|
+
* the node that you want to find in the binary tree. It can be either a `BinaryTreeNodeKey` or `N`
|
|
611
|
+
* type.
|
|
612
|
+
* @param callback - The `callback` parameter is a function that is used to determine whether a node
|
|
613
|
+
* matches the desired criteria. It takes a node as input and returns a boolean value indicating
|
|
614
|
+
* whether the node matches the criteria or not. The default callback function
|
|
615
|
+
* (`this._defaultCallbackByKey`) is used if no callback function is
|
|
616
|
+
* @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
|
|
617
|
+
* the root node from which the search should begin.
|
|
618
|
+
* @param iterationType - The `iterationType` parameter specifies the type of iteration to be
|
|
619
|
+
* performed when searching for a node in the binary tree. It can have one of the following values:
|
|
620
|
+
* @returns either the found node (of type N) or null if no node is found.
|
|
554
621
|
*/
|
|
555
|
-
get(
|
|
622
|
+
get(
|
|
623
|
+
nodeProperty: BinaryTreeNodeKey | N,
|
|
624
|
+
callback: MapCallback<N> = this._defaultCallbackByKey,
|
|
625
|
+
beginRoot = this.root,
|
|
626
|
+
iterationType = this.iterationType
|
|
627
|
+
): N | null {
|
|
556
628
|
// TODO may support finding node by value equal
|
|
557
|
-
return this.getNodes(nodeProperty, callback, true)[0] ?? null;
|
|
629
|
+
return this.getNodes(nodeProperty, callback, true, beginRoot, iterationType)[0] ?? null;
|
|
558
630
|
}
|
|
559
631
|
|
|
560
632
|
/**
|
|
561
|
-
* The function `getPathToRoot` returns an array of nodes
|
|
562
|
-
*
|
|
563
|
-
*
|
|
564
|
-
*
|
|
565
|
-
* @param
|
|
566
|
-
* path should be reversed or not. If `isReverse` is set to `true`, the path will be
|
|
567
|
-
* `isReverse` is set to `false` or not provided, the path will
|
|
568
|
-
* @returns The function `getPathToRoot` returns an array of
|
|
633
|
+
* The function `getPathToRoot` returns an array of nodes starting from a given node and traversing
|
|
634
|
+
* up to the root node, with the option to reverse the order of the nodes.
|
|
635
|
+
* @param {N} beginRoot - The `beginRoot` parameter represents the starting node from which you want
|
|
636
|
+
* to find the path to the root node.
|
|
637
|
+
* @param [isReverse=true] - The `isReverse` parameter is a boolean flag that determines whether the
|
|
638
|
+
* resulting path should be reversed or not. If `isReverse` is set to `true`, the path will be
|
|
639
|
+
* reversed before returning it. If `isReverse` is set to `false` or not provided, the path will
|
|
640
|
+
* @returns The function `getPathToRoot` returns an array of type `N[]`.
|
|
569
641
|
*/
|
|
570
642
|
getPathToRoot(beginRoot: N, isReverse = true): N[] {
|
|
571
643
|
// TODO to support get path through passing key
|
|
@@ -581,22 +653,22 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
581
653
|
}
|
|
582
654
|
|
|
583
655
|
/**
|
|
584
|
-
* The function `getLeftMost` returns the leftmost node in a binary tree,
|
|
585
|
-
*
|
|
586
|
-
* @param {N | BinaryTreeNodeKey | null}
|
|
587
|
-
*
|
|
588
|
-
* node), or `null
|
|
589
|
-
* @
|
|
590
|
-
*
|
|
591
|
-
*
|
|
592
|
-
* node
|
|
656
|
+
* The function `getLeftMost` returns the leftmost node in a binary tree, either using recursive or
|
|
657
|
+
* iterative traversal.
|
|
658
|
+
* @param {N | BinaryTreeNodeKey | null} beginRoot - The `beginRoot` parameter is the starting point
|
|
659
|
+
* for finding the leftmost node in a binary tree. It can be either a node object (`N`), a key value
|
|
660
|
+
* of a node (`BinaryTreeNodeKey`), or `null` if the tree is empty.
|
|
661
|
+
* @param iterationType - The `iterationType` parameter is used to determine the type of iteration to
|
|
662
|
+
* be performed when finding the leftmost node in a binary tree. It can have two possible values:
|
|
663
|
+
* @returns The function `getLeftMost` returns the leftmost node (`N`) in a binary tree. If there is
|
|
664
|
+
* no leftmost node, it returns `null`.
|
|
593
665
|
*/
|
|
594
|
-
getLeftMost(beginRoot: N | BinaryTreeNodeKey | null = this.root): N | null {
|
|
666
|
+
getLeftMost(beginRoot: N | BinaryTreeNodeKey | null = this.root, iterationType = this.iterationType): N | null {
|
|
595
667
|
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
|
|
596
668
|
|
|
597
669
|
if (!beginRoot) return beginRoot;
|
|
598
670
|
|
|
599
|
-
if (
|
|
671
|
+
if (iterationType === IterationType.RECURSIVE) {
|
|
600
672
|
const _traverse = (cur: N): N => {
|
|
601
673
|
if (!cur.left) return cur;
|
|
602
674
|
return _traverse(cur.left);
|
|
@@ -615,20 +687,21 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
615
687
|
}
|
|
616
688
|
|
|
617
689
|
/**
|
|
618
|
-
* The `getRightMost`
|
|
619
|
-
*
|
|
620
|
-
* @param {N | null}
|
|
621
|
-
*
|
|
622
|
-
*
|
|
623
|
-
* @
|
|
624
|
-
*
|
|
625
|
-
*
|
|
690
|
+
* The function `getRightMost` returns the rightmost node in a binary tree, either recursively or
|
|
691
|
+
* iteratively.
|
|
692
|
+
* @param {N | null} beginRoot - The `beginRoot` parameter is the starting node from which we want to
|
|
693
|
+
* find the rightmost node. It is of type `N | null`, which means it can either be a node of type `N`
|
|
694
|
+
* or `null`. If it is `null`, it means there is no starting node
|
|
695
|
+
* @param iterationType - The `iterationType` parameter is used to determine the type of iteration to
|
|
696
|
+
* be performed when finding the rightmost node in a binary tree. It can have two possible values:
|
|
697
|
+
* @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If the
|
|
698
|
+
* `beginRoot` parameter is `null`, it returns `null`.
|
|
626
699
|
*/
|
|
627
|
-
getRightMost(beginRoot: N | null = this.root): N | null {
|
|
700
|
+
getRightMost(beginRoot: N | null = this.root, iterationType = this.iterationType): N | null {
|
|
628
701
|
// TODO support get right most by passing key in
|
|
629
702
|
if (!beginRoot) return beginRoot;
|
|
630
703
|
|
|
631
|
-
if (
|
|
704
|
+
if (iterationType === IterationType.RECURSIVE) {
|
|
632
705
|
const _traverse = (cur: N): N => {
|
|
633
706
|
if (!cur.right) return cur;
|
|
634
707
|
return _traverse(cur.right);
|
|
@@ -647,26 +720,30 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
647
720
|
}
|
|
648
721
|
|
|
649
722
|
/**
|
|
650
|
-
* The function checks if a binary
|
|
651
|
-
* @param {N
|
|
652
|
-
*
|
|
723
|
+
* The function `isSubtreeBST` checks if a given binary tree is a valid binary search tree.
|
|
724
|
+
* @param {N} beginRoot - The `beginRoot` parameter is the root node of the binary tree that you want
|
|
725
|
+
* to check if it is a binary search tree (BST) subtree.
|
|
726
|
+
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
727
|
+
* type of iteration to use when checking if a subtree is a binary search tree (BST). It can have two
|
|
728
|
+
* possible values:
|
|
729
|
+
* @returns The function `isSubtreeBST` returns a boolean value.
|
|
653
730
|
*/
|
|
654
|
-
isSubtreeBST(
|
|
731
|
+
isSubtreeBST(beginRoot: N, iterationType = this.iterationType): boolean {
|
|
655
732
|
// TODO there is a bug
|
|
656
|
-
if (!
|
|
733
|
+
if (!beginRoot) return true;
|
|
657
734
|
|
|
658
|
-
if (
|
|
735
|
+
if (iterationType === IterationType.RECURSIVE) {
|
|
659
736
|
const dfs = (cur: N | null | undefined, min: BinaryTreeNodeKey, max: BinaryTreeNodeKey): boolean => {
|
|
660
737
|
if (!cur) return true;
|
|
661
738
|
if (cur.key <= min || cur.key >= max) return false;
|
|
662
739
|
return dfs(cur.left, min, cur.key) && dfs(cur.right, cur.key, max);
|
|
663
740
|
};
|
|
664
741
|
|
|
665
|
-
return dfs(
|
|
742
|
+
return dfs(beginRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
|
|
666
743
|
} else {
|
|
667
744
|
const stack = [];
|
|
668
745
|
let prev = Number.MIN_SAFE_INTEGER,
|
|
669
|
-
curr: N | null | undefined =
|
|
746
|
+
curr: N | null | undefined = beginRoot;
|
|
670
747
|
while (curr || stack.length > 0) {
|
|
671
748
|
while (curr) {
|
|
672
749
|
stack.push(curr);
|
|
@@ -682,40 +759,52 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
682
759
|
}
|
|
683
760
|
|
|
684
761
|
/**
|
|
685
|
-
* The function
|
|
686
|
-
* @
|
|
762
|
+
* The function checks if a binary tree is a binary search tree.
|
|
763
|
+
* @param iterationType - The parameter "iterationType" is used to specify the type of iteration to
|
|
764
|
+
* be used when checking if the binary tree is a binary search tree (BST). It is an optional
|
|
765
|
+
* parameter with a default value of "this.iterationType". The value of "this.iterationType" is not
|
|
766
|
+
* provided in
|
|
767
|
+
* @returns a boolean value.
|
|
687
768
|
*/
|
|
688
|
-
isBST(): boolean {
|
|
689
|
-
|
|
769
|
+
isBST(iterationType = this.iterationType): boolean {
|
|
770
|
+
if (this.root === null) return true;
|
|
771
|
+
return this.isSubtreeBST(this.root, iterationType);
|
|
690
772
|
}
|
|
691
773
|
|
|
692
774
|
/**
|
|
693
|
-
* The function `subTreeTraverse`
|
|
694
|
-
*
|
|
695
|
-
*
|
|
696
|
-
*
|
|
697
|
-
*
|
|
698
|
-
*
|
|
775
|
+
* The function `subTreeTraverse` traverses a binary tree and applies a callback function to each
|
|
776
|
+
* node, either recursively or iteratively.
|
|
777
|
+
* @param callback - The `callback` parameter is a function that will be called on each node in the
|
|
778
|
+
* subtree traversal. It takes a single argument, which is the current node being traversed, and
|
|
779
|
+
* returns a value. The return values from each callback invocation will be collected and returned as
|
|
780
|
+
* an array.
|
|
781
|
+
* @param {N | BinaryTreeNodeKey | null} beginRoot - The `beginRoot` parameter is the starting point
|
|
782
|
+
* for traversing the subtree. It can be either a node object, a key value of a node, or `null` to
|
|
783
|
+
* start from the root of the tree.
|
|
784
|
+
* @param iterationType - The `iterationType` parameter determines the type of traversal to be
|
|
785
|
+
* performed on the binary tree. It can have two possible values:
|
|
786
|
+
* @returns The function `subTreeTraverse` returns an array of `MapCallbackReturn<N>`.
|
|
699
787
|
*/
|
|
700
788
|
subTreeTraverse(
|
|
701
789
|
callback: MapCallback<N> = this._defaultCallbackByKey,
|
|
702
|
-
|
|
790
|
+
beginRoot: N | BinaryTreeNodeKey | null = this.root,
|
|
791
|
+
iterationType = this.iterationType
|
|
703
792
|
): MapCallbackReturn<N>[] {
|
|
704
|
-
if (typeof
|
|
793
|
+
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
|
|
705
794
|
|
|
706
795
|
const ans: MapCallbackReturn<N>[] = [];
|
|
707
|
-
if (!
|
|
796
|
+
if (!beginRoot) return ans;
|
|
708
797
|
|
|
709
|
-
if (
|
|
798
|
+
if (iterationType === IterationType.RECURSIVE) {
|
|
710
799
|
const _traverse = (cur: N) => {
|
|
711
800
|
ans.push(callback(cur));
|
|
712
801
|
cur.left && _traverse(cur.left);
|
|
713
802
|
cur.right && _traverse(cur.right);
|
|
714
803
|
};
|
|
715
804
|
|
|
716
|
-
_traverse(
|
|
805
|
+
_traverse(beginRoot);
|
|
717
806
|
} else {
|
|
718
|
-
const stack: N[] = [
|
|
807
|
+
const stack: N[] = [beginRoot];
|
|
719
808
|
|
|
720
809
|
while (stack.length > 0) {
|
|
721
810
|
const cur = stack.pop()!;
|
|
@@ -729,23 +818,29 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
729
818
|
}
|
|
730
819
|
|
|
731
820
|
/**
|
|
732
|
-
* The dfs function performs a depth-first search traversal on a binary tree
|
|
733
|
-
* each node
|
|
734
|
-
* @param callback
|
|
735
|
-
*
|
|
736
|
-
*
|
|
737
|
-
* @param
|
|
738
|
-
*
|
|
821
|
+
* The `dfs` function performs a depth-first search traversal on a binary tree, executing a callback
|
|
822
|
+
* function on each node according to a specified order pattern.
|
|
823
|
+
* @param callback - The `callback` parameter is a function that will be called on each node during
|
|
824
|
+
* the depth-first search traversal. It takes a node as input and returns a value. The default value
|
|
825
|
+
* is `this._defaultCallbackByKey`, which is a callback function defined elsewhere in the code.
|
|
826
|
+
* @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter determines the order in which the
|
|
827
|
+
* nodes are visited during the depth-first search. There are three possible values for `pattern`:
|
|
828
|
+
* @param {N | null} beginRoot - The `beginRoot` parameter is the starting node for the depth-first
|
|
829
|
+
* search. It determines where the search will begin in the tree or graph structure. If `beginRoot`
|
|
830
|
+
* is `null`, an empty array will be returned.
|
|
831
|
+
* @param {IterationType} iterationType - The `iterationType` parameter determines the type of
|
|
832
|
+
* iteration used in the depth-first search algorithm. It can have two possible values:
|
|
833
|
+
* @returns The function `dfs` returns an array of `MapCallbackReturn<N>` values.
|
|
739
834
|
*/
|
|
740
835
|
dfs(
|
|
741
836
|
callback: MapCallback<N> = this._defaultCallbackByKey,
|
|
742
837
|
pattern: DFSOrderPattern = 'in',
|
|
743
838
|
beginRoot: N | null = this.root,
|
|
744
|
-
|
|
839
|
+
iterationType: IterationType = IterationType.ITERATIVE
|
|
745
840
|
): MapCallbackReturn<N>[] {
|
|
746
841
|
if (!beginRoot) return [];
|
|
747
842
|
const ans: MapCallbackReturn<N>[] = [];
|
|
748
|
-
if (
|
|
843
|
+
if (iterationType === IterationType.RECURSIVE) {
|
|
749
844
|
const _traverse = (node: N) => {
|
|
750
845
|
switch (pattern) {
|
|
751
846
|
case 'in':
|
|
@@ -811,31 +906,42 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
811
906
|
// --- start additional methods ---
|
|
812
907
|
|
|
813
908
|
/**
|
|
814
|
-
* The
|
|
815
|
-
*
|
|
816
|
-
* @param callback - The `callback` parameter is a function that
|
|
817
|
-
*
|
|
909
|
+
* The bfs function performs a breadth-first search traversal on a binary tree, executing a callback
|
|
910
|
+
* function on each node.
|
|
911
|
+
* @param callback - The `callback` parameter is a function that will be called for each node in the
|
|
912
|
+
* breadth-first search. It takes a node of type `N` as its argument and returns a value of type
|
|
913
|
+
* `BFSCallbackReturn<N>`. The default value for this parameter is `this._defaultCallbackByKey
|
|
914
|
+
* @param {boolean} [withLevel=false] - The `withLevel` parameter is a boolean flag that determines
|
|
915
|
+
* whether or not to include the level of each node in the callback function. If `withLevel` is set
|
|
916
|
+
* to `true`, the level of each node will be passed as an argument to the callback function. If
|
|
917
|
+
* `withLevel` is
|
|
918
|
+
* @param {N | null} beginRoot - The `beginRoot` parameter is the starting node for the breadth-first
|
|
919
|
+
* search. It determines from which node the search will begin. If `beginRoot` is `null`, the search
|
|
920
|
+
* will not be performed and an empty array will be returned.
|
|
921
|
+
* @param iterationType - The `iterationType` parameter determines the type of iteration to be used
|
|
922
|
+
* in the breadth-first search (BFS) algorithm. It can have two possible values:
|
|
923
|
+
* @returns The function `bfs` returns an array of `BFSCallbackReturn<N>[]`.
|
|
818
924
|
*/
|
|
819
925
|
bfs(
|
|
820
926
|
callback: BFSCallback<N> = this._defaultCallbackByKey,
|
|
821
927
|
withLevel: boolean = false,
|
|
822
|
-
|
|
928
|
+
beginRoot: N | null = this.root,
|
|
929
|
+
iterationType = this.iterationType
|
|
823
930
|
): BFSCallbackReturn<N>[] {
|
|
824
|
-
if (!
|
|
825
|
-
if (!node) return [];
|
|
931
|
+
if (!beginRoot) return [];
|
|
826
932
|
|
|
827
933
|
const ans: BFSCallbackReturn<N>[] = [];
|
|
828
934
|
|
|
829
|
-
if (
|
|
935
|
+
if (iterationType === IterationType.RECURSIVE) {
|
|
830
936
|
const _recursive = (node: N, level: number) => {
|
|
831
937
|
callback && ans.push(callback(node, withLevel ? level : undefined));
|
|
832
938
|
if (node.left) _recursive(node.left, level + 1);
|
|
833
939
|
if (node.right) _recursive(node.right, level + 1);
|
|
834
940
|
};
|
|
835
941
|
|
|
836
|
-
_recursive(
|
|
942
|
+
_recursive(beginRoot, 0);
|
|
837
943
|
} else {
|
|
838
|
-
const stack: [N, number][] = [[
|
|
944
|
+
const stack: [N, number][] = [[beginRoot, 0]];
|
|
839
945
|
|
|
840
946
|
while (stack.length > 0) {
|
|
841
947
|
const head = stack.pop()!;
|
|
@@ -850,9 +956,9 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
850
956
|
}
|
|
851
957
|
|
|
852
958
|
/**
|
|
853
|
-
* The function returns the predecessor of a given node in a binary tree.
|
|
854
|
-
* @param node - The parameter
|
|
855
|
-
* @returns the predecessor of the given node
|
|
959
|
+
* The function returns the predecessor node of a given node in a binary tree.
|
|
960
|
+
* @param {N} node - The parameter "node" represents a node in a binary tree.
|
|
961
|
+
* @returns The function `getPredecessor` returns the predecessor node of the given node `node`.
|
|
856
962
|
*/
|
|
857
963
|
getPredecessor(node: N): N {
|
|
858
964
|
if (node.left) {
|
|
@@ -871,22 +977,34 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
871
977
|
/**
|
|
872
978
|
* Time complexity is O(n)
|
|
873
979
|
* Space complexity of Iterative dfs equals to recursive dfs which is O(n) because of the stack
|
|
980
|
+
* The Morris algorithm only modifies the tree's structure during traversal; once the traversal is complete,
|
|
981
|
+
* the tree's structure should be restored to its original state to maintain the tree's integrity.
|
|
982
|
+
* This is because the purpose of the Morris algorithm is to save space rather than permanently alter the tree's shape.
|
|
874
983
|
*/
|
|
875
984
|
|
|
876
985
|
/**
|
|
877
|
-
* The `morris` function performs
|
|
878
|
-
*
|
|
879
|
-
* @param callback
|
|
880
|
-
*
|
|
986
|
+
* The `morris` function performs a depth-first traversal of a binary tree using the Morris traversal
|
|
987
|
+
* algorithm and returns an array of values obtained by applying a callback function to each node.
|
|
988
|
+
* @param callback - The `callback` parameter is a function that will be called on each node in the
|
|
989
|
+
* tree. It takes a node of type `N` as input and returns a value of type `MapCallbackReturn<N>`. The
|
|
990
|
+
* default value for this parameter is `this._defaultCallbackByKey`.
|
|
991
|
+
* @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter in the `morris` function
|
|
992
|
+
* determines the order in which the nodes of a binary tree are traversed. It can have one of the
|
|
993
|
+
* following values:
|
|
994
|
+
* @param {N | null} beginRoot - The `beginRoot` parameter is the starting node for the Morris
|
|
995
|
+
* traversal. It specifies the root node of the tree from which the traversal should begin. If
|
|
996
|
+
* `beginRoot` is `null`, an empty array will be returned.
|
|
997
|
+
* @returns The `morris` function returns an array of `MapCallbackReturn<N>` values.
|
|
881
998
|
*/
|
|
882
999
|
morris(
|
|
883
1000
|
callback: MapCallback<N> = this._defaultCallbackByKey,
|
|
884
|
-
pattern: DFSOrderPattern = 'in'
|
|
1001
|
+
pattern: DFSOrderPattern = 'in',
|
|
1002
|
+
beginRoot: N | null = this.root
|
|
885
1003
|
): MapCallbackReturn<N>[] {
|
|
886
|
-
if (
|
|
1004
|
+
if (beginRoot === null) return [];
|
|
887
1005
|
const ans: MapCallbackReturn<N>[] = [];
|
|
888
1006
|
|
|
889
|
-
let cur: N | null | undefined =
|
|
1007
|
+
let cur: N | null | undefined = beginRoot;
|
|
890
1008
|
const _reverseEdge = (node: N | null | undefined) => {
|
|
891
1009
|
let pre: N | null | undefined = null;
|
|
892
1010
|
let next: N | null | undefined = null;
|
|
@@ -957,21 +1075,22 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
957
1075
|
}
|
|
958
1076
|
cur = cur.right;
|
|
959
1077
|
}
|
|
960
|
-
_printEdge(
|
|
1078
|
+
_printEdge(beginRoot);
|
|
961
1079
|
break;
|
|
962
1080
|
}
|
|
963
1081
|
return ans;
|
|
964
1082
|
}
|
|
965
1083
|
|
|
966
1084
|
/**
|
|
967
|
-
* The function adds a new node to a binary tree if there is an available position.
|
|
968
|
-
* @param {N | null} newNode - The `newNode` parameter
|
|
969
|
-
*
|
|
970
|
-
* @param {N} parent - The parent parameter
|
|
971
|
-
*
|
|
972
|
-
*
|
|
973
|
-
*
|
|
974
|
-
* undefined.
|
|
1085
|
+
* The function `_addTo` adds a new node to a binary tree if there is an available position.
|
|
1086
|
+
* @param {N | null} newNode - The `newNode` parameter represents the node that you want to add to
|
|
1087
|
+
* the binary tree. It can be either a node object or `null`.
|
|
1088
|
+
* @param {N} parent - The `parent` parameter represents the parent node to which the new node will
|
|
1089
|
+
* be added as a child.
|
|
1090
|
+
* @returns either the left or right child node of the parent node, depending on which child is
|
|
1091
|
+
* available for adding the new node. If a new node is added, the function also updates the size of
|
|
1092
|
+
* the binary tree. If neither the left nor right child is available, the function returns undefined.
|
|
1093
|
+
* If the parent node is null, the function also returns undefined.
|
|
975
1094
|
*/
|
|
976
1095
|
protected _addTo(newNode: N | null, parent: N): N | null | undefined {
|
|
977
1096
|
if (parent) {
|
|
@@ -998,9 +1117,10 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
998
1117
|
}
|
|
999
1118
|
|
|
1000
1119
|
/**
|
|
1001
|
-
* The function sets the root property of an object to a given value, and if the value is not null,
|
|
1002
|
-
* parent property of the value to undefined.
|
|
1003
|
-
* @param {N | null} v - The parameter `v` is of type `N | null`, which means it can either be of
|
|
1120
|
+
* The function sets the root property of an object to a given value, and if the value is not null,
|
|
1121
|
+
* it also sets the parent property of the value to undefined.
|
|
1122
|
+
* @param {N | null} v - The parameter `v` is of type `N | null`, which means it can either be of
|
|
1123
|
+
* type `N` or `null`.
|
|
1004
1124
|
*/
|
|
1005
1125
|
protected _setRoot(v: N | null) {
|
|
1006
1126
|
if (v) {
|
|
@@ -1010,8 +1130,9 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
1010
1130
|
}
|
|
1011
1131
|
|
|
1012
1132
|
/**
|
|
1013
|
-
* The function sets the
|
|
1014
|
-
* @param {number} v - number
|
|
1133
|
+
* The function sets the value of the protected property "_size" to the given number.
|
|
1134
|
+
* @param {number} v - The parameter "v" is a number that represents the size value that we want to
|
|
1135
|
+
* set.
|
|
1015
1136
|
*/
|
|
1016
1137
|
protected _setSize(v: number) {
|
|
1017
1138
|
this._size = v;
|