linked-list-typed 1.38.5 → 1.38.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data-structures/binary-tree/avl-tree.d.ts +14 -8
- package/dist/data-structures/binary-tree/avl-tree.js +10 -5
- package/dist/data-structures/binary-tree/binary-tree.d.ts +59 -107
- package/dist/data-structures/binary-tree/binary-tree.js +72 -81
- package/dist/data-structures/binary-tree/bst.d.ts +13 -13
- package/dist/data-structures/binary-tree/bst.js +14 -14
- package/dist/data-structures/binary-tree/rb-tree.d.ts +3 -3
- package/dist/data-structures/binary-tree/tree-multiset.d.ts +15 -11
- package/dist/data-structures/binary-tree/tree-multiset.js +11 -7
- package/dist/interfaces/binary-tree.d.ts +3 -3
- package/dist/types/helpers.d.ts +2 -0
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree.ts +22 -13
- package/src/data-structures/binary-tree/binary-tree.ts +155 -111
- package/src/data-structures/binary-tree/bst.ts +26 -26
- package/src/data-structures/binary-tree/rb-tree.ts +6 -9
- package/src/data-structures/binary-tree/tree-multiset.ts +24 -19
- package/src/data-structures/linked-list/doubly-linked-list.ts +0 -1
- package/src/interfaces/binary-tree.ts +3 -3
- package/src/types/helpers.ts +4 -0
|
@@ -15,7 +15,7 @@ import type {
|
|
|
15
15
|
MapCallback,
|
|
16
16
|
MapCallbackReturn
|
|
17
17
|
} from '../../types';
|
|
18
|
-
import {BinaryTreeDeletedResult, DFSOrderPattern, FamilyPosition, IterationType} from '../../types';
|
|
18
|
+
import {BinaryTreeDeletedResult, DefaultMapCallback, DFSOrderPattern, FamilyPosition, IterationType} from '../../types';
|
|
19
19
|
import {IBinaryTree} from '../../interfaces';
|
|
20
20
|
import {trampoline} from '../../utils';
|
|
21
21
|
import {Queue} from '../queue';
|
|
@@ -23,9 +23,9 @@ import {Queue} from '../queue';
|
|
|
23
23
|
/**
|
|
24
24
|
* Represents a node in a binary tree.
|
|
25
25
|
* @template V - The type of data stored in the node.
|
|
26
|
-
* @template
|
|
26
|
+
* @template N - The type of the family relationship in the binary tree.
|
|
27
27
|
*/
|
|
28
|
-
export class BinaryTreeNode<V = any,
|
|
28
|
+
export class BinaryTreeNode<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode<V, BinaryTreeNodeNested<V>>> {
|
|
29
29
|
/**
|
|
30
30
|
* The key associated with the node.
|
|
31
31
|
*/
|
|
@@ -39,7 +39,7 @@ export class BinaryTreeNode<V = any, FAMILY extends BinaryTreeNode<V, FAMILY> =
|
|
|
39
39
|
/**
|
|
40
40
|
* The parent node of the current node.
|
|
41
41
|
*/
|
|
42
|
-
parent:
|
|
42
|
+
parent: N | null | undefined;
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
* Creates a new instance of BinaryTreeNode.
|
|
@@ -51,42 +51,42 @@ export class BinaryTreeNode<V = any, FAMILY extends BinaryTreeNode<V, FAMILY> =
|
|
|
51
51
|
this.val = val;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
private _left:
|
|
54
|
+
private _left: N | null | undefined;
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
57
|
* Get the left child node.
|
|
58
58
|
*/
|
|
59
|
-
get left():
|
|
59
|
+
get left(): N | null | undefined {
|
|
60
60
|
return this._left;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
64
|
* Set the left child node.
|
|
65
|
-
* @param {
|
|
65
|
+
* @param {N | null | undefined} v - The left child node.
|
|
66
66
|
*/
|
|
67
|
-
set left(v:
|
|
67
|
+
set left(v: N | null | undefined) {
|
|
68
68
|
if (v) {
|
|
69
|
-
v.parent = this as unknown as
|
|
69
|
+
v.parent = this as unknown as N;
|
|
70
70
|
}
|
|
71
71
|
this._left = v;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
private _right:
|
|
74
|
+
private _right: N | null | undefined;
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
77
|
* Get the right child node.
|
|
78
78
|
*/
|
|
79
|
-
get right():
|
|
79
|
+
get right(): N | null | undefined {
|
|
80
80
|
return this._right;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
/**
|
|
84
84
|
* Set the right child node.
|
|
85
|
-
* @param {
|
|
85
|
+
* @param {N | null | undefined} v - The right child node.
|
|
86
86
|
*/
|
|
87
|
-
set right(v:
|
|
87
|
+
set right(v: N | null | undefined) {
|
|
88
88
|
if (v) {
|
|
89
|
-
v.parent = this as unknown as
|
|
89
|
+
v.parent = this as unknown as N;
|
|
90
90
|
}
|
|
91
91
|
this._right = v;
|
|
92
92
|
}
|
|
@@ -96,30 +96,18 @@ export class BinaryTreeNode<V = any, FAMILY extends BinaryTreeNode<V, FAMILY> =
|
|
|
96
96
|
* @returns {FamilyPosition} - The family position of the node.
|
|
97
97
|
*/
|
|
98
98
|
get familyPosition(): FamilyPosition {
|
|
99
|
-
const that = this as unknown as
|
|
100
|
-
if (
|
|
101
|
-
|
|
102
|
-
if (that.left || that.right) {
|
|
103
|
-
return FamilyPosition.ROOT_LEFT;
|
|
104
|
-
} else {
|
|
105
|
-
return FamilyPosition.LEFT;
|
|
106
|
-
}
|
|
107
|
-
} else if (that.parent.right === that) {
|
|
108
|
-
if (that.left || that.right) {
|
|
109
|
-
return FamilyPosition.ROOT_RIGHT;
|
|
110
|
-
} else {
|
|
111
|
-
return FamilyPosition.RIGHT;
|
|
112
|
-
}
|
|
113
|
-
} else {
|
|
114
|
-
return FamilyPosition.MAL_NODE;
|
|
115
|
-
}
|
|
116
|
-
} else {
|
|
117
|
-
if (that.left || that.right) {
|
|
118
|
-
return FamilyPosition.ROOT;
|
|
119
|
-
} else {
|
|
120
|
-
return FamilyPosition.ISOLATED;
|
|
121
|
-
}
|
|
99
|
+
const that = this as unknown as N;
|
|
100
|
+
if (!this.parent) {
|
|
101
|
+
return this.left || this.right ? FamilyPosition.ROOT : FamilyPosition.ISOLATED;
|
|
122
102
|
}
|
|
103
|
+
|
|
104
|
+
if (this.parent.left === that) {
|
|
105
|
+
return this.left || this.right ? FamilyPosition.ROOT_LEFT : FamilyPosition.LEFT;
|
|
106
|
+
} else if (this.parent.right === that) {
|
|
107
|
+
return this.left || this.right ? FamilyPosition.ROOT_RIGHT : FamilyPosition.RIGHT;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return FamilyPosition.MAL_NODE;
|
|
123
111
|
}
|
|
124
112
|
}
|
|
125
113
|
|
|
@@ -127,9 +115,7 @@ export class BinaryTreeNode<V = any, FAMILY extends BinaryTreeNode<V, FAMILY> =
|
|
|
127
115
|
* Represents a binary tree data structure.
|
|
128
116
|
* @template N - The type of the binary tree's nodes.
|
|
129
117
|
*/
|
|
130
|
-
export class BinaryTree<N extends BinaryTreeNode<
|
|
131
|
-
private _loopType: IterationType = IterationType.ITERATIVE;
|
|
132
|
-
|
|
118
|
+
export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode> implements IBinaryTree<V, N> {
|
|
133
119
|
/**
|
|
134
120
|
* Creates a new instance of BinaryTree.
|
|
135
121
|
* @param {BinaryTreeOptions} [options] - The options for the binary tree.
|
|
@@ -137,10 +123,27 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
137
123
|
constructor(options?: BinaryTreeOptions) {
|
|
138
124
|
if (options !== undefined) {
|
|
139
125
|
const {iterationType = IterationType.ITERATIVE} = options;
|
|
140
|
-
this.
|
|
126
|
+
this._iterationType = iterationType;
|
|
141
127
|
}
|
|
142
128
|
}
|
|
143
129
|
|
|
130
|
+
private _iterationType: IterationType = IterationType.ITERATIVE;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Get the iteration type used in the binary tree.
|
|
134
|
+
*/
|
|
135
|
+
get iterationType(): IterationType {
|
|
136
|
+
return this._iterationType;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Set the iteration type for the binary tree.
|
|
141
|
+
* @param {IterationType} v - The new iteration type to set.
|
|
142
|
+
*/
|
|
143
|
+
set iterationType(v: IterationType) {
|
|
144
|
+
this._iterationType = v;
|
|
145
|
+
}
|
|
146
|
+
|
|
144
147
|
private _root: N | null = null;
|
|
145
148
|
|
|
146
149
|
/**
|
|
@@ -159,29 +162,14 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
159
162
|
return this._size;
|
|
160
163
|
}
|
|
161
164
|
|
|
162
|
-
/**
|
|
163
|
-
* Get the iteration type used in the binary tree.
|
|
164
|
-
*/
|
|
165
|
-
get iterationType(): IterationType {
|
|
166
|
-
return this._loopType;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Set the iteration type for the binary tree.
|
|
171
|
-
* @param {IterationType} v - The new iteration type to set.
|
|
172
|
-
*/
|
|
173
|
-
set iterationType(v: IterationType) {
|
|
174
|
-
this._loopType = v;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
165
|
/**
|
|
178
166
|
* Creates a new instance of BinaryTreeNode with the given key and value.
|
|
179
167
|
* @param {BinaryTreeNodeKey} key - The key for the new node.
|
|
180
|
-
* @param {
|
|
168
|
+
* @param {V} val - The value for the new node.
|
|
181
169
|
* @returns {N} - The newly created BinaryTreeNode.
|
|
182
170
|
*/
|
|
183
|
-
createNode(key: BinaryTreeNodeKey, val?:
|
|
184
|
-
return new BinaryTreeNode<
|
|
171
|
+
createNode(key: BinaryTreeNodeKey, val?: V): N {
|
|
172
|
+
return new BinaryTreeNode<V, N>(key, val) as N;
|
|
185
173
|
}
|
|
186
174
|
|
|
187
175
|
/**
|
|
@@ -203,10 +191,10 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
203
191
|
/**
|
|
204
192
|
* Add a node with the given key and value to the binary tree.
|
|
205
193
|
* @param {BinaryTreeNodeKey | N | null} keyOrNode - The key or node to add to the binary tree.
|
|
206
|
-
* @param {
|
|
194
|
+
* @param {V} val - The value for the new node (optional).
|
|
207
195
|
* @returns {N | null | undefined} - The inserted node, or null if nothing was inserted, or undefined if the operation failed.
|
|
208
196
|
*/
|
|
209
|
-
add(keyOrNode: BinaryTreeNodeKey | N | null, val?:
|
|
197
|
+
add(keyOrNode: BinaryTreeNodeKey | N | null, val?: V): N | null | undefined {
|
|
210
198
|
const _bfs = (root: N, newNode: N | null): N | undefined | null => {
|
|
211
199
|
const queue = new Queue<N | null>([root]);
|
|
212
200
|
while (queue.size > 0) {
|
|
@@ -234,7 +222,8 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
234
222
|
return;
|
|
235
223
|
}
|
|
236
224
|
|
|
237
|
-
const
|
|
225
|
+
const key = typeof keyOrNode === 'number' ? keyOrNode : keyOrNode ? keyOrNode.key : undefined;
|
|
226
|
+
const existNode = key !== undefined ? this.get(key, this._defaultCallbackByKey) : undefined;
|
|
238
227
|
|
|
239
228
|
if (this.root) {
|
|
240
229
|
if (existNode) {
|
|
@@ -260,60 +249,68 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
260
249
|
* values, and adds them to the binary tree.
|
|
261
250
|
* @param {(BinaryTreeNodeKey | null)[] | (N | null)[]} keysOrNodes - An array of BinaryTreeNodeKey or BinaryTreeNode
|
|
262
251
|
* objects, or null values.
|
|
263
|
-
* @param {
|
|
252
|
+
* @param {V[]} [values] - The `values` parameter is an optional array of values (`V[]`) that corresponds to
|
|
264
253
|
* the nodes or node IDs being added. It is used to set the value of each node being added. If `values` is not provided,
|
|
265
254
|
* the value of the nodes will be `undefined`.
|
|
266
255
|
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
|
|
267
256
|
*/
|
|
268
|
-
addMany(keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], values?:
|
|
257
|
+
addMany(keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], values?: V[]): (N | null | undefined)[] {
|
|
269
258
|
// TODO not sure addMany not be run multi times
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
for (let i = 0; i < keysOrNodes.length; i++) {
|
|
273
|
-
const keyOrNode = keysOrNodes[i];
|
|
259
|
+
return keysOrNodes.map((keyOrNode, i) => {
|
|
274
260
|
if (keyOrNode instanceof BinaryTreeNode) {
|
|
275
|
-
|
|
276
|
-
continue;
|
|
261
|
+
return this.add(keyOrNode.key, keyOrNode.val);
|
|
277
262
|
}
|
|
278
263
|
|
|
279
264
|
if (keyOrNode === null) {
|
|
280
|
-
|
|
281
|
-
continue;
|
|
265
|
+
return this.add(null);
|
|
282
266
|
}
|
|
283
267
|
|
|
284
268
|
const val = values?.[i];
|
|
285
|
-
|
|
286
|
-
}
|
|
287
|
-
return inserted;
|
|
269
|
+
return this.add(keyOrNode, val);
|
|
270
|
+
});
|
|
288
271
|
}
|
|
289
272
|
|
|
290
273
|
/**
|
|
291
274
|
* The `refill` function clears the binary tree and adds multiple nodes with the given IDs or nodes and optional data.
|
|
292
275
|
* @param {(BinaryTreeNodeKey | N)[]} keysOrNodes - The `keysOrNodes` parameter is an array that can contain either
|
|
293
276
|
* `BinaryTreeNodeKey` or `N` values.
|
|
294
|
-
* @param {N[] | Array<
|
|
277
|
+
* @param {N[] | Array<V>} [data] - The `data` parameter is an optional array of values that will be assigned to
|
|
295
278
|
* the nodes being added. If provided, the length of the `data` array should be equal to the length of the `keysOrNodes`
|
|
296
279
|
* array. Each value in the `data` array will be assigned to the
|
|
297
280
|
* @returns The method is returning a boolean value.
|
|
298
281
|
*/
|
|
299
|
-
refill(keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], data?:
|
|
282
|
+
refill(keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], data?: Array<V>): boolean {
|
|
300
283
|
this.clear();
|
|
301
284
|
return keysOrNodes.length === this.addMany(keysOrNodes, data).length;
|
|
302
285
|
}
|
|
303
286
|
|
|
287
|
+
delete<C extends MapCallback<N>>(identifier: ReturnType<C> | N): BinaryTreeDeletedResult<N>[];
|
|
288
|
+
|
|
289
|
+
delete<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C): BinaryTreeDeletedResult<N>[];
|
|
290
|
+
|
|
304
291
|
/**
|
|
305
292
|
* The `delete` function removes a node from a binary search tree and returns the deleted node along
|
|
306
293
|
* with the parent node that needs to be balanced.
|
|
307
|
-
* @param {N | BinaryTreeNodeKey} nodeOrKey - The `nodeOrKey` parameter can be either a node (`N`) or
|
|
308
294
|
* a key (`BinaryTreeNodeKey`). If it is a key, the function will find the corresponding node in the
|
|
309
295
|
* binary tree.
|
|
310
296
|
* @returns an array of `BinaryTreeDeletedResult<N>` objects.
|
|
297
|
+
* @param {ReturnType<C>} identifier - The `identifier` parameter is either a
|
|
298
|
+
* `BinaryTreeNodeKey` or a generic type `N`. It represents the property of the node that we are
|
|
299
|
+
* searching for. It can be a specific key value or any other property of the node.
|
|
300
|
+
* @param callback - The `callback` parameter is a function that takes a node as input and returns a
|
|
301
|
+
* value. This value is compared with the `identifier` parameter to determine if the node should be
|
|
302
|
+
* included in the result. The `callback` parameter has a default value of
|
|
303
|
+
* `this._defaultCallbackByKey`, which
|
|
311
304
|
*/
|
|
312
|
-
delete
|
|
305
|
+
delete<C extends MapCallback<N>>(
|
|
306
|
+
identifier: ReturnType<C> | N,
|
|
307
|
+
callback: C = this._defaultCallbackByKey as C
|
|
308
|
+
): BinaryTreeDeletedResult<N>[] {
|
|
313
309
|
const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
|
|
314
310
|
if (!this.root) return bstDeletedResult;
|
|
311
|
+
if (identifier instanceof BinaryTreeNode) callback = (node => node) as C;
|
|
315
312
|
|
|
316
|
-
const curr
|
|
313
|
+
const curr = this.get(identifier, callback);
|
|
317
314
|
if (!curr) return bstDeletedResult;
|
|
318
315
|
|
|
319
316
|
const parent: N | null = curr?.parent ? curr.parent : null;
|
|
@@ -354,16 +351,16 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
354
351
|
/**
|
|
355
352
|
* The function `getDepth` calculates the depth of a given node in a binary tree relative to a
|
|
356
353
|
* specified root node.
|
|
357
|
-
* @param {
|
|
354
|
+
* @param {BinaryTreeNodeKey | N | null} distNode - The `distNode` parameter represents the node
|
|
358
355
|
* whose depth we want to find in the binary tree. It can be either a node object (`N`), a key value
|
|
359
356
|
* of the node (`BinaryTreeNodeKey`), or `null`.
|
|
360
|
-
* @param {
|
|
357
|
+
* @param {BinaryTreeNodeKey | N | null} beginRoot - The `beginRoot` parameter represents the
|
|
361
358
|
* starting node from which we want to calculate the depth. It can be either a node object or the key
|
|
362
359
|
* of a node in the binary tree. If no value is provided for `beginRoot`, it defaults to the root
|
|
363
360
|
* node of the binary tree.
|
|
364
361
|
* @returns the depth of the `distNode` relative to the `beginRoot`.
|
|
365
362
|
*/
|
|
366
|
-
getDepth(distNode:
|
|
363
|
+
getDepth(distNode: BinaryTreeNodeKey | N | null, beginRoot: BinaryTreeNodeKey | N | null = this.root): number {
|
|
367
364
|
if (typeof distNode === 'number') distNode = this.get(distNode);
|
|
368
365
|
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
|
|
369
366
|
let depth = 0;
|
|
@@ -380,7 +377,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
380
377
|
/**
|
|
381
378
|
* The `getHeight` function calculates the maximum height of a binary tree using either recursive or
|
|
382
379
|
* iterative approach.
|
|
383
|
-
* @param {
|
|
380
|
+
* @param {BinaryTreeNodeKey | N | null} beginRoot - The `beginRoot` parameter represents the
|
|
384
381
|
* starting node from which the height of the binary tree is calculated. It can be either a node
|
|
385
382
|
* object (`N`), a key value of a node in the tree (`BinaryTreeNodeKey`), or `null` if no starting
|
|
386
383
|
* node is specified. If `
|
|
@@ -389,7 +386,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
389
386
|
* possible values:
|
|
390
387
|
* @returns the height of the binary tree.
|
|
391
388
|
*/
|
|
392
|
-
getHeight(beginRoot:
|
|
389
|
+
getHeight(beginRoot: BinaryTreeNodeKey | N | null = this.root, iterationType = this.iterationType): number {
|
|
393
390
|
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
|
|
394
391
|
if (!beginRoot) return -1;
|
|
395
392
|
|
|
@@ -491,18 +488,41 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
491
488
|
return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
|
|
492
489
|
}
|
|
493
490
|
|
|
491
|
+
getNodes<C extends MapCallback<N>>(identifier: ReturnType<C> | N): N[];
|
|
492
|
+
|
|
493
|
+
getNodes<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C): N[];
|
|
494
|
+
|
|
495
|
+
getNodes<C extends MapCallback<N>>(identifier: ReturnType<C> | N, onlyOne: boolean): N[];
|
|
496
|
+
|
|
497
|
+
getNodes<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C, onlyOne: boolean): N[];
|
|
498
|
+
|
|
499
|
+
getNodes<C extends MapCallback<N>>(
|
|
500
|
+
identifier: ReturnType<C> | N,
|
|
501
|
+
callback: C,
|
|
502
|
+
onlyOne: boolean,
|
|
503
|
+
beginRoot: N | null
|
|
504
|
+
): N[];
|
|
505
|
+
|
|
506
|
+
getNodes<C extends MapCallback<N>>(
|
|
507
|
+
identifier: ReturnType<C> | N,
|
|
508
|
+
callback: C,
|
|
509
|
+
onlyOne: boolean,
|
|
510
|
+
beginRoot: N | null,
|
|
511
|
+
iterationType: IterationType
|
|
512
|
+
): N[];
|
|
513
|
+
|
|
494
514
|
/**
|
|
495
515
|
* The function `getNodes` returns an array of nodes that match a given node property, using either
|
|
496
516
|
* recursive or iterative traversal.
|
|
497
|
-
* @param {
|
|
517
|
+
* @param {ReturnType<C>} identifier - The `identifier` parameter is either a
|
|
498
518
|
* `BinaryTreeNodeKey` or a generic type `N`. It represents the property of the node that we are
|
|
499
519
|
* searching for. It can be a specific key value or any other property of the node.
|
|
500
520
|
* @param callback - The `callback` parameter is a function that takes a node as input and returns a
|
|
501
|
-
* value. This value is compared with the `
|
|
521
|
+
* value. This value is compared with the `identifier` parameter to determine if the node should be
|
|
502
522
|
* included in the result. The `callback` parameter has a default value of
|
|
503
523
|
* `this._defaultCallbackByKey`, which
|
|
504
524
|
* @param [onlyOne=false] - A boolean value indicating whether to stop searching after finding the
|
|
505
|
-
* first node that matches the
|
|
525
|
+
* first node that matches the identifier. If set to true, the function will return an array with
|
|
506
526
|
* only one element (or an empty array if no matching node is found). If set to false (default), the
|
|
507
527
|
* function will continue searching for all
|
|
508
528
|
* @param {N | null} beginRoot - The `beginRoot` parameter is the starting node from which the
|
|
@@ -512,20 +532,20 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
512
532
|
* traverse the binary tree. It can have two possible values:
|
|
513
533
|
* @returns The function `getNodes` returns an array of nodes (`N[]`).
|
|
514
534
|
*/
|
|
515
|
-
getNodes<C extends MapCallback<N
|
|
516
|
-
|
|
535
|
+
getNodes<C extends MapCallback<N>>(
|
|
536
|
+
identifier: ReturnType<C> | N,
|
|
517
537
|
callback: C = this._defaultCallbackByKey as C,
|
|
518
538
|
onlyOne = false,
|
|
519
539
|
beginRoot: N | null = this.root,
|
|
520
540
|
iterationType = this.iterationType
|
|
521
541
|
): N[] {
|
|
522
542
|
if (!beginRoot) return [];
|
|
523
|
-
|
|
543
|
+
if (identifier instanceof BinaryTreeNode) callback = (node => node) as C;
|
|
524
544
|
const ans: N[] = [];
|
|
525
545
|
|
|
526
546
|
if (iterationType === IterationType.RECURSIVE) {
|
|
527
547
|
const _traverse = (cur: N) => {
|
|
528
|
-
if (callback(cur) ===
|
|
548
|
+
if (callback(cur) === identifier) {
|
|
529
549
|
ans.push(cur);
|
|
530
550
|
if (onlyOne) return;
|
|
531
551
|
}
|
|
@@ -540,7 +560,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
540
560
|
while (queue.size > 0) {
|
|
541
561
|
const cur = queue.shift();
|
|
542
562
|
if (cur) {
|
|
543
|
-
if (callback(cur) ===
|
|
563
|
+
if (callback(cur) === identifier) {
|
|
544
564
|
ans.push(cur);
|
|
545
565
|
if (onlyOne) return ans;
|
|
546
566
|
}
|
|
@@ -553,9 +573,17 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
553
573
|
return ans;
|
|
554
574
|
}
|
|
555
575
|
|
|
576
|
+
has<C extends MapCallback<N>>(identifier: ReturnType<C> | N): boolean;
|
|
577
|
+
|
|
578
|
+
has<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C): boolean;
|
|
579
|
+
|
|
580
|
+
has<C extends MapCallback<N>>(identifier: ReturnType<C> | N, beginRoot: N | null): boolean;
|
|
581
|
+
|
|
582
|
+
has<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C, beginRoot: N | null): boolean;
|
|
583
|
+
|
|
556
584
|
/**
|
|
557
585
|
* The function checks if a binary tree has a node with a given property or key.
|
|
558
|
-
* @param {BinaryTreeNodeKey | N}
|
|
586
|
+
* @param {BinaryTreeNodeKey | N} identifier - The `identifier` parameter is the key or value of
|
|
559
587
|
* the node that you want to find in the binary tree. It can be either a `BinaryTreeNodeKey` or a
|
|
560
588
|
* generic type `N`.
|
|
561
589
|
* @param callback - The `callback` parameter is a function that is used to determine whether a node
|
|
@@ -570,19 +598,35 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
570
598
|
* performed when searching for nodes in the binary tree. It can have one of the following values:
|
|
571
599
|
* @returns a boolean value.
|
|
572
600
|
*/
|
|
573
|
-
has<C extends MapCallback<N
|
|
574
|
-
|
|
601
|
+
has<C extends MapCallback<N>>(
|
|
602
|
+
identifier: ReturnType<C> | N,
|
|
575
603
|
callback: C = this._defaultCallbackByKey as C,
|
|
576
604
|
beginRoot = this.root,
|
|
577
605
|
iterationType = this.iterationType
|
|
578
606
|
): boolean {
|
|
607
|
+
if (identifier instanceof BinaryTreeNode) callback = (node => node) as C;
|
|
579
608
|
// TODO may support finding node by value equal
|
|
580
|
-
return this.getNodes(
|
|
609
|
+
return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
|
|
581
610
|
}
|
|
582
611
|
|
|
612
|
+
get<C extends MapCallback<N>>(identifier: ReturnType<C> | N): N | null;
|
|
613
|
+
|
|
614
|
+
get<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C): N | null;
|
|
615
|
+
|
|
616
|
+
get<C extends MapCallback<N>>(identifier: ReturnType<C> | N, beginRoot: N | null): N | null;
|
|
617
|
+
|
|
618
|
+
get<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C, beginRoot: N | null): N | null;
|
|
619
|
+
|
|
620
|
+
get<C extends MapCallback<N>>(
|
|
621
|
+
identifier: ReturnType<C> | N,
|
|
622
|
+
callback: C,
|
|
623
|
+
beginRoot: N | null,
|
|
624
|
+
iterationType: IterationType
|
|
625
|
+
): N | null;
|
|
626
|
+
|
|
583
627
|
/**
|
|
584
628
|
* The function `get` returns the first node in a binary tree that matches the given property or key.
|
|
585
|
-
* @param {BinaryTreeNodeKey | N}
|
|
629
|
+
* @param {BinaryTreeNodeKey | N} identifier - The `identifier` parameter is the key or value of
|
|
586
630
|
* the node that you want to find in the binary tree. It can be either a `BinaryTreeNodeKey` or `N`
|
|
587
631
|
* type.
|
|
588
632
|
* @param callback - The `callback` parameter is a function that is used to determine whether a node
|
|
@@ -595,14 +639,15 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
595
639
|
* performed when searching for a node in the binary tree. It can have one of the following values:
|
|
596
640
|
* @returns either the found node (of type N) or null if no node is found.
|
|
597
641
|
*/
|
|
598
|
-
get<C extends MapCallback<N
|
|
599
|
-
|
|
642
|
+
get<C extends MapCallback<N>>(
|
|
643
|
+
identifier: ReturnType<C> | N,
|
|
600
644
|
callback: C = this._defaultCallbackByKey as C,
|
|
601
645
|
beginRoot = this.root,
|
|
602
646
|
iterationType = this.iterationType
|
|
603
647
|
): N | null {
|
|
648
|
+
if (identifier instanceof BinaryTreeNode) callback = (node => node) as C;
|
|
604
649
|
// TODO may support finding node by value equal
|
|
605
|
-
return this.getNodes(
|
|
650
|
+
return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;
|
|
606
651
|
}
|
|
607
652
|
|
|
608
653
|
/**
|
|
@@ -631,7 +676,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
631
676
|
/**
|
|
632
677
|
* The function `getLeftMost` returns the leftmost node in a binary tree, either using recursive or
|
|
633
678
|
* iterative traversal.
|
|
634
|
-
* @param {
|
|
679
|
+
* @param {BinaryTreeNodeKey | N | null} beginRoot - The `beginRoot` parameter is the starting point
|
|
635
680
|
* for finding the leftmost node in a binary tree. It can be either a node object (`N`), a key value
|
|
636
681
|
* of a node (`BinaryTreeNodeKey`), or `null` if the tree is empty.
|
|
637
682
|
* @param iterationType - The `iterationType` parameter is used to determine the type of iteration to
|
|
@@ -639,7 +684,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
639
684
|
* @returns The function `getLeftMost` returns the leftmost node (`N`) in a binary tree. If there is
|
|
640
685
|
* no leftmost node, it returns `null`.
|
|
641
686
|
*/
|
|
642
|
-
getLeftMost(beginRoot:
|
|
687
|
+
getLeftMost(beginRoot: BinaryTreeNodeKey | N | null = this.root, iterationType = this.iterationType): N | null {
|
|
643
688
|
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
|
|
644
689
|
|
|
645
690
|
if (!beginRoot) return beginRoot;
|
|
@@ -754,16 +799,16 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
754
799
|
* subtree traversal. It takes a single argument, which is the current node being traversed, and
|
|
755
800
|
* returns a value. The return values from each callback invocation will be collected and returned as
|
|
756
801
|
* an array.
|
|
757
|
-
* @param {
|
|
802
|
+
* @param {BinaryTreeNodeKey | N | null} beginRoot - The `beginRoot` parameter is the starting point
|
|
758
803
|
* for traversing the subtree. It can be either a node object, a key value of a node, or `null` to
|
|
759
804
|
* start from the root of the tree.
|
|
760
805
|
* @param iterationType - The `iterationType` parameter determines the type of traversal to be
|
|
761
806
|
* performed on the binary tree. It can have two possible values:
|
|
762
807
|
* @returns The function `subTreeTraverse` returns an array of `MapCallbackReturn<N>`.
|
|
763
808
|
*/
|
|
764
|
-
subTreeTraverse<C extends MapCallback<N
|
|
809
|
+
subTreeTraverse<C extends MapCallback<N>>(
|
|
765
810
|
callback: C = this._defaultCallbackByKey as C,
|
|
766
|
-
beginRoot:
|
|
811
|
+
beginRoot: BinaryTreeNodeKey | N | null = this.root,
|
|
767
812
|
iterationType = this.iterationType
|
|
768
813
|
): ReturnType<C>[] {
|
|
769
814
|
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
|
|
@@ -808,7 +853,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
808
853
|
* iteration used in the depth-first search algorithm. It can have two possible values:
|
|
809
854
|
* @returns The function `dfs` returns an array of `MapCallbackReturn<N>` values.
|
|
810
855
|
*/
|
|
811
|
-
dfs<C extends MapCallback<N
|
|
856
|
+
dfs<C extends MapCallback<N>>(
|
|
812
857
|
callback: C = this._defaultCallbackByKey as C,
|
|
813
858
|
pattern: DFSOrderPattern = 'in',
|
|
814
859
|
beginRoot: N | null = this.root,
|
|
@@ -886,7 +931,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
886
931
|
* breadth-first search. It takes a node of type `N` as its argument and returns a value of type
|
|
887
932
|
* `BFSCallbackReturn<N>`. The default value for this parameter is `this._defaultCallbackByKey
|
|
888
933
|
* @param {boolean} [withLevel=false] - The `withLevel` parameter is a boolean flag that determines
|
|
889
|
-
* whether
|
|
934
|
+
* whether to include the level of each node in the callback function. If `withLevel` is set
|
|
890
935
|
* to `true`, the level of each node will be passed as an argument to the callback function. If
|
|
891
936
|
* `withLevel` is
|
|
892
937
|
* @param {N | null} beginRoot - The `beginRoot` parameter is the starting node for the breadth-first
|
|
@@ -964,7 +1009,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
964
1009
|
* `beginRoot` is `null`, an empty array will be returned.
|
|
965
1010
|
* @returns The `morris` function returns an array of `MapCallbackReturn<N>` values.
|
|
966
1011
|
*/
|
|
967
|
-
morris<C extends MapCallback<N
|
|
1012
|
+
morris<C extends MapCallback<N>>(
|
|
968
1013
|
callback: C = this._defaultCallbackByKey as C,
|
|
969
1014
|
pattern: DFSOrderPattern = 'in',
|
|
970
1015
|
beginRoot: N | null = this.root
|
|
@@ -1077,8 +1122,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|
|
1077
1122
|
* the tree's structure should be restored to its original state to maintain the tree's integrity.
|
|
1078
1123
|
* This is because the purpose of the Morris algorithm is to save space rather than permanently alter the tree's shape.
|
|
1079
1124
|
*/
|
|
1080
|
-
|
|
1081
|
-
protected _defaultCallbackByKey: (node: N) => number = node => node.key;
|
|
1125
|
+
protected _defaultCallbackByKey: DefaultMapCallback<N> = node => node.key;
|
|
1082
1126
|
|
|
1083
1127
|
/**
|
|
1084
1128
|
* The function `_addTo` adds a new node to a binary tree if there is an available position.
|