queue-typed 1.53.9 → 1.54.1
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-counter.d.ts +213 -0
- package/dist/data-structures/binary-tree/avl-tree-counter.js +407 -0
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +71 -189
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +133 -357
- package/dist/data-structures/binary-tree/avl-tree.d.ts +108 -78
- package/dist/data-structures/binary-tree/avl-tree.js +126 -79
- package/dist/data-structures/binary-tree/binary-indexed-tree.d.ts +3 -0
- package/dist/data-structures/binary-tree/binary-indexed-tree.js +3 -0
- package/dist/data-structures/binary-tree/binary-tree.d.ts +243 -190
- package/dist/data-structures/binary-tree/binary-tree.js +273 -229
- package/dist/data-structures/binary-tree/bst.d.ts +141 -122
- package/dist/data-structures/binary-tree/bst.js +170 -134
- package/dist/data-structures/binary-tree/index.d.ts +2 -0
- package/dist/data-structures/binary-tree/index.js +2 -0
- package/dist/data-structures/binary-tree/red-black-tree.d.ts +84 -80
- package/dist/data-structures/binary-tree/red-black-tree.js +101 -79
- package/dist/data-structures/binary-tree/tree-counter.d.ts +212 -0
- package/dist/data-structures/binary-tree/tree-counter.js +444 -0
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +78 -186
- package/dist/data-structures/binary-tree/tree-multi-map.js +140 -388
- package/dist/data-structures/graph/directed-graph.d.ts +3 -0
- package/dist/data-structures/graph/directed-graph.js +3 -0
- package/dist/data-structures/graph/map-graph.d.ts +3 -0
- package/dist/data-structures/graph/map-graph.js +3 -0
- package/dist/data-structures/graph/undirected-graph.d.ts +3 -0
- package/dist/data-structures/graph/undirected-graph.js +3 -0
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +3 -0
- package/dist/data-structures/linked-list/singly-linked-list.js +3 -0
- package/dist/data-structures/linked-list/skip-linked-list.d.ts +3 -0
- package/dist/data-structures/linked-list/skip-linked-list.js +3 -0
- package/dist/data-structures/matrix/matrix.d.ts +3 -0
- package/dist/data-structures/matrix/matrix.js +3 -0
- package/dist/data-structures/matrix/navigator.d.ts +3 -0
- package/dist/data-structures/matrix/navigator.js +3 -0
- package/dist/data-structures/priority-queue/max-priority-queue.d.ts +3 -0
- package/dist/data-structures/priority-queue/max-priority-queue.js +3 -0
- package/dist/data-structures/priority-queue/min-priority-queue.d.ts +3 -0
- package/dist/data-structures/priority-queue/min-priority-queue.js +3 -0
- package/dist/data-structures/trie/trie.d.ts +0 -4
- package/dist/data-structures/trie/trie.js +0 -4
- package/dist/interfaces/binary-tree.d.ts +7 -6
- package/dist/types/data-structures/binary-tree/avl-tree-counter.d.ts +2 -0
- package/dist/types/data-structures/binary-tree/avl-tree-counter.js +2 -0
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -3
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +0 -2
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +0 -2
- package/dist/types/data-structures/binary-tree/bst.d.ts +3 -2
- package/dist/types/data-structures/binary-tree/index.d.ts +2 -0
- package/dist/types/data-structures/binary-tree/index.js +2 -0
- package/dist/types/data-structures/binary-tree/rb-tree.d.ts +1 -3
- package/dist/types/data-structures/binary-tree/tree-counter.d.ts +2 -0
- package/dist/types/data-structures/binary-tree/tree-counter.js +2 -0
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -3
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree-counter.ts +463 -0
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +148 -394
- package/src/data-structures/binary-tree/avl-tree.ts +152 -112
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +3 -0
- package/src/data-structures/binary-tree/binary-tree.ts +446 -379
- package/src/data-structures/binary-tree/bst.ts +224 -201
- package/src/data-structures/binary-tree/index.ts +2 -0
- package/src/data-structures/binary-tree/red-black-tree.ts +138 -114
- package/src/data-structures/binary-tree/tree-counter.ts +504 -0
- package/src/data-structures/binary-tree/tree-multi-map.ts +156 -428
- package/src/data-structures/graph/directed-graph.ts +3 -0
- package/src/data-structures/graph/map-graph.ts +3 -0
- package/src/data-structures/graph/undirected-graph.ts +3 -0
- package/src/data-structures/linked-list/singly-linked-list.ts +3 -0
- package/src/data-structures/linked-list/skip-linked-list.ts +3 -0
- package/src/data-structures/matrix/matrix.ts +3 -0
- package/src/data-structures/matrix/navigator.ts +3 -0
- package/src/data-structures/priority-queue/max-priority-queue.ts +3 -0
- package/src/data-structures/priority-queue/min-priority-queue.ts +3 -0
- package/src/data-structures/trie/trie.ts +0 -4
- package/src/interfaces/binary-tree.ts +10 -11
- package/src/types/data-structures/binary-tree/avl-tree-counter.ts +3 -0
- package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +1 -4
- package/src/types/data-structures/binary-tree/avl-tree.ts +0 -3
- package/src/types/data-structures/binary-tree/binary-tree.ts +0 -5
- package/src/types/data-structures/binary-tree/bst.ts +5 -3
- package/src/types/data-structures/binary-tree/index.ts +2 -0
- package/src/types/data-structures/binary-tree/rb-tree.ts +1 -4
- package/src/types/data-structures/binary-tree/tree-counter.ts +3 -0
- package/src/types/data-structures/binary-tree/tree-multi-map.ts +1 -4
|
@@ -6,9 +6,8 @@
|
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import type {
|
|
10
10
|
BinaryTreeDeleteResult,
|
|
11
|
-
BinaryTreeNodeNested,
|
|
12
11
|
BinaryTreeOptions,
|
|
13
12
|
BinaryTreePrintOptions,
|
|
14
13
|
BTNEntry,
|
|
@@ -22,6 +21,7 @@ import {
|
|
|
22
21
|
NodeDisplayLayout,
|
|
23
22
|
NodePredicate,
|
|
24
23
|
OptNodeOrNull,
|
|
24
|
+
RBTNColor,
|
|
25
25
|
ToEntryFn
|
|
26
26
|
} from '../../types';
|
|
27
27
|
import { IBinaryTree } from '../../interfaces';
|
|
@@ -33,59 +33,92 @@ import { DFSOperation, Range } from '../../common';
|
|
|
33
33
|
/**
|
|
34
34
|
* Represents a node in a binary tree.
|
|
35
35
|
* @template V - The type of data stored in the node.
|
|
36
|
-
* @template
|
|
36
|
+
* @template BinaryTreeNode<K, V> - The type of the family relationship in the binary tree.
|
|
37
37
|
*/
|
|
38
|
-
export class BinaryTreeNode<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
parent?: NODE;
|
|
48
|
-
|
|
38
|
+
export class BinaryTreeNode<K = any, V = any> {
|
|
39
|
+
/**
|
|
40
|
+
* The constructor function initializes an object with a key and an optional value in TypeScript.
|
|
41
|
+
* @param {K} key - The `key` parameter in the constructor function is used to store the key value
|
|
42
|
+
* for the key-value pair.
|
|
43
|
+
* @param {V} [value] - The `value` parameter in the constructor is optional, meaning it does not
|
|
44
|
+
* have to be provided when creating an instance of the class. If a `value` is not provided, it will
|
|
45
|
+
* default to `undefined`.
|
|
46
|
+
*/
|
|
49
47
|
constructor(key: K, value?: V) {
|
|
50
48
|
this.key = key;
|
|
51
49
|
this.value = value;
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
|
|
52
|
+
key: K;
|
|
53
|
+
|
|
54
|
+
value?: V;
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
parent?: BinaryTreeNode<K, V> = undefined;
|
|
57
|
+
|
|
58
|
+
_left?: OptNodeOrNull<BinaryTreeNode<K, V>> = undefined;
|
|
59
|
+
|
|
60
|
+
get left(): OptNodeOrNull<BinaryTreeNode<K, V>> {
|
|
57
61
|
return this._left;
|
|
58
62
|
}
|
|
59
63
|
|
|
60
|
-
set left(v: OptNodeOrNull<
|
|
64
|
+
set left(v: OptNodeOrNull<BinaryTreeNode<K, V>>) {
|
|
61
65
|
if (v) {
|
|
62
|
-
v.parent = this as unknown as
|
|
66
|
+
v.parent = this as unknown as BinaryTreeNode<K, V>;
|
|
63
67
|
}
|
|
64
68
|
this._left = v;
|
|
65
69
|
}
|
|
66
70
|
|
|
67
|
-
|
|
71
|
+
_right?: OptNodeOrNull<BinaryTreeNode<K, V>> = undefined;
|
|
68
72
|
|
|
69
|
-
get right(): OptNodeOrNull<
|
|
73
|
+
get right(): OptNodeOrNull<BinaryTreeNode<K, V>> {
|
|
70
74
|
return this._right;
|
|
71
75
|
}
|
|
72
76
|
|
|
73
|
-
set right(v: OptNodeOrNull<
|
|
77
|
+
set right(v: OptNodeOrNull<BinaryTreeNode<K, V>>) {
|
|
74
78
|
if (v) {
|
|
75
|
-
v.parent = this
|
|
79
|
+
v.parent = this;
|
|
76
80
|
}
|
|
77
81
|
this._right = v;
|
|
78
82
|
}
|
|
79
83
|
|
|
84
|
+
_height: number = 0;
|
|
85
|
+
|
|
86
|
+
get height(): number {
|
|
87
|
+
return this._height;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
set height(value: number) {
|
|
91
|
+
this._height = value;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
_color: RBTNColor = 'BLACK';
|
|
95
|
+
|
|
96
|
+
get color(): RBTNColor {
|
|
97
|
+
return this._color;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
set color(value: RBTNColor) {
|
|
101
|
+
this._color = value;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
_count: number = 1;
|
|
105
|
+
|
|
106
|
+
get count(): number {
|
|
107
|
+
return this._count;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
set count(value: number) {
|
|
111
|
+
this._count = value;
|
|
112
|
+
}
|
|
113
|
+
|
|
80
114
|
get familyPosition(): FamilyPosition {
|
|
81
|
-
const that = this as unknown as NODE;
|
|
82
115
|
if (!this.parent) {
|
|
83
116
|
return this.left || this.right ? 'ROOT' : 'ISOLATED';
|
|
84
117
|
}
|
|
85
118
|
|
|
86
|
-
if (this.parent.left ===
|
|
119
|
+
if (this.parent.left === this) {
|
|
87
120
|
return this.left || this.right ? 'ROOT_LEFT' : 'LEFT';
|
|
88
|
-
} else if (this.parent.right ===
|
|
121
|
+
} else if (this.parent.right === this) {
|
|
89
122
|
return this.left || this.right ? 'ROOT_RIGHT' : 'RIGHT';
|
|
90
123
|
}
|
|
91
124
|
|
|
@@ -100,27 +133,23 @@ export class BinaryTreeNode<
|
|
|
100
133
|
* 4. Subtrees: Each child of a node forms the root of a subtree.
|
|
101
134
|
* 5. Leaf Nodes: Nodes without children are leaves.
|
|
102
135
|
*/
|
|
103
|
-
export class BinaryTree<
|
|
104
|
-
K = any,
|
|
105
|
-
V = any,
|
|
106
|
-
R = object,
|
|
107
|
-
NODE extends BinaryTreeNode<K, V, NODE> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>
|
|
108
|
-
>
|
|
136
|
+
export class BinaryTree<K = any, V = any, R = object, MK = any, MV = any, MR = object>
|
|
109
137
|
extends IterableEntryBase<K, V | undefined>
|
|
110
|
-
implements IBinaryTree<K, V, R,
|
|
138
|
+
implements IBinaryTree<K, V, R, MK, MV, MR>
|
|
111
139
|
{
|
|
112
|
-
iterationType: IterationType = 'ITERATIVE';
|
|
113
|
-
|
|
114
140
|
/**
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the constructor
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
* @param [options] - The `options` parameter in the constructor is an object that can
|
|
121
|
-
* following properties:
|
|
141
|
+
* This TypeScript constructor function initializes a binary tree with optional options and adds
|
|
142
|
+
* elements based on the provided input.
|
|
143
|
+
* @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the constructor is an
|
|
144
|
+
* iterable that can contain either objects of type `BTNRep<K, V, BinaryTreeNode<K, V>>` or `R`. It
|
|
145
|
+
* is used to initialize the binary tree with keys, nodes, entries, or raw data.
|
|
146
|
+
* @param [options] - The `options` parameter in the constructor is an optional object that can
|
|
147
|
+
* contain the following properties:
|
|
122
148
|
*/
|
|
123
|
-
constructor(
|
|
149
|
+
constructor(
|
|
150
|
+
keysNodesEntriesOrRaws: Iterable<BTNRep<K, V, BinaryTreeNode<K, V>> | R> = [],
|
|
151
|
+
options?: BinaryTreeOptions<K, V, R>
|
|
152
|
+
) {
|
|
124
153
|
super();
|
|
125
154
|
if (options) {
|
|
126
155
|
const { iterationType, toEntryFn, isMapMode } = options;
|
|
@@ -133,6 +162,8 @@ export class BinaryTree<
|
|
|
133
162
|
if (keysNodesEntriesOrRaws) this.addMany(keysNodesEntriesOrRaws);
|
|
134
163
|
}
|
|
135
164
|
|
|
165
|
+
iterationType: IterationType = 'ITERATIVE';
|
|
166
|
+
|
|
136
167
|
protected _isMapMode = true;
|
|
137
168
|
|
|
138
169
|
get isMapMode() {
|
|
@@ -145,9 +176,9 @@ export class BinaryTree<
|
|
|
145
176
|
return this._store;
|
|
146
177
|
}
|
|
147
178
|
|
|
148
|
-
protected _root?: OptNodeOrNull<
|
|
179
|
+
protected _root?: OptNodeOrNull<BinaryTreeNode<K, V>>;
|
|
149
180
|
|
|
150
|
-
get root(): OptNodeOrNull<
|
|
181
|
+
get root(): OptNodeOrNull<BinaryTreeNode<K, V>> {
|
|
151
182
|
return this._root;
|
|
152
183
|
}
|
|
153
184
|
|
|
@@ -157,9 +188,9 @@ export class BinaryTree<
|
|
|
157
188
|
return this._size;
|
|
158
189
|
}
|
|
159
190
|
|
|
160
|
-
protected _NIL:
|
|
191
|
+
protected _NIL: BinaryTreeNode<K, V> = new BinaryTreeNode<K, V>(NaN as K) as unknown as BinaryTreeNode<K, V>;
|
|
161
192
|
|
|
162
|
-
get NIL():
|
|
193
|
+
get NIL(): BinaryTreeNode<K, V> {
|
|
163
194
|
return this._NIL;
|
|
164
195
|
}
|
|
165
196
|
|
|
@@ -179,33 +210,30 @@ export class BinaryTree<
|
|
|
179
210
|
* not required to be provided when calling the function. If a `value` is provided, it should be of
|
|
180
211
|
* type `V`, which is the type of the value associated with the node.
|
|
181
212
|
* @returns A new BinaryTreeNode instance with the provided key and value is being returned, casted
|
|
182
|
-
* as
|
|
213
|
+
* as BinaryTreeNode<K, V>.
|
|
183
214
|
*/
|
|
184
|
-
createNode(key: K, value?: V):
|
|
185
|
-
return new BinaryTreeNode<K, V
|
|
215
|
+
createNode(key: K, value?: V): BinaryTreeNode<K, V> {
|
|
216
|
+
return new BinaryTreeNode<K, V>(key, this._isMapMode ? undefined : value);
|
|
186
217
|
}
|
|
187
218
|
|
|
188
219
|
/**
|
|
189
220
|
* Time Complexity: O(1)
|
|
190
221
|
* Space Complexity: O(1)
|
|
191
222
|
*
|
|
192
|
-
* The
|
|
193
|
-
* @param [options] - The `options` parameter in the `createTree`
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
* @returns
|
|
198
|
-
* provided options. The method is creating a new `BinaryTree` object with an empty array as the
|
|
199
|
-
* initial data, and then setting various options such as `iterationType`, `isMapMode`, and
|
|
200
|
-
* `toEntryFn` based on the current object's properties and the provided `options`. Finally, it
|
|
223
|
+
* The function creates a binary tree with the specified options.
|
|
224
|
+
* @param [options] - The `options` parameter in the `createTree` function is an optional parameter
|
|
225
|
+
* that allows you to provide partial configuration options for creating a binary tree. It is of type
|
|
226
|
+
* `Partial<BinaryTreeOptions<K, V, R>>`, which means you can pass in an object containing a subset
|
|
227
|
+
* of properties
|
|
228
|
+
* @returns A new instance of a binary tree with the specified options is being returned.
|
|
201
229
|
*/
|
|
202
|
-
createTree(options?: BinaryTreeOptions<K, V, R>)
|
|
203
|
-
return new BinaryTree<K, V, R>([], {
|
|
230
|
+
createTree(options?: BinaryTreeOptions<K, V, R>) {
|
|
231
|
+
return new BinaryTree<K, V, R, MK, MV, MR>([], {
|
|
204
232
|
iterationType: this.iterationType,
|
|
205
233
|
isMapMode: this._isMapMode,
|
|
206
234
|
toEntryFn: this._toEntryFn,
|
|
207
235
|
...options
|
|
208
|
-
})
|
|
236
|
+
});
|
|
209
237
|
}
|
|
210
238
|
|
|
211
239
|
/**
|
|
@@ -214,8 +242,8 @@ export class BinaryTree<
|
|
|
214
242
|
*
|
|
215
243
|
* The function `ensureNode` in TypeScript checks if a given input is a node, entry, key, or raw
|
|
216
244
|
* value and returns the corresponding node or null.
|
|
217
|
-
* @param {BTNRep<K, V,
|
|
218
|
-
* parameter in the `ensureNode` function can be of type `BTNRep<K, V,
|
|
245
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The `keyNodeOrEntry`
|
|
246
|
+
* parameter in the `ensureNode` function can be of type `BTNRep<K, V, BinaryTreeNode<K, V>>` or `R`. It
|
|
219
247
|
* is used to determine whether the input is a key, node, entry, or raw data. The
|
|
220
248
|
* @param {IterationType} iterationType - The `iterationType` parameter in the `ensureNode` function
|
|
221
249
|
* is used to specify the type of iteration to be performed. It has a default value of
|
|
@@ -224,144 +252,174 @@ export class BinaryTree<
|
|
|
224
252
|
* conditions specified in the code snippet.
|
|
225
253
|
*/
|
|
226
254
|
ensureNode(
|
|
227
|
-
|
|
255
|
+
keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>,
|
|
228
256
|
iterationType: IterationType = this.iterationType
|
|
229
|
-
): OptNodeOrNull<
|
|
230
|
-
if (
|
|
231
|
-
if (
|
|
232
|
-
if (
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
257
|
+
): OptNodeOrNull<BinaryTreeNode<K, V>> {
|
|
258
|
+
if (keyNodeOrEntry === null) return null;
|
|
259
|
+
if (keyNodeOrEntry === undefined) return;
|
|
260
|
+
if (keyNodeOrEntry === this._NIL) return;
|
|
261
|
+
|
|
262
|
+
if (this.isNode(keyNodeOrEntry)) return keyNodeOrEntry;
|
|
263
|
+
|
|
264
|
+
if (this.isEntry(keyNodeOrEntry)) {
|
|
265
|
+
const key = keyNodeOrEntry[0];
|
|
237
266
|
if (key === null) return null;
|
|
238
267
|
if (key === undefined) return;
|
|
239
268
|
return this.getNode(key, this._root, iterationType);
|
|
240
269
|
}
|
|
241
270
|
|
|
242
|
-
|
|
243
|
-
const [key] = this._toEntryFn(keyNodeEntryOrRaw as R);
|
|
244
|
-
if (this.isKey(key)) return this.getNode(key);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
if (this.isKey(keyNodeEntryOrRaw)) return this.getNode(keyNodeEntryOrRaw, this._root, iterationType);
|
|
248
|
-
return;
|
|
271
|
+
return this.getNode(keyNodeOrEntry, this._root, iterationType);
|
|
249
272
|
}
|
|
250
273
|
|
|
251
274
|
/**
|
|
275
|
+
* Time Complexity: O(1)
|
|
276
|
+
* Space Complexity: O(1)
|
|
277
|
+
*
|
|
252
278
|
* The function isNode checks if the input is an instance of BinaryTreeNode.
|
|
253
|
-
* @param {BTNRep<K, V,
|
|
254
|
-
* `
|
|
279
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The parameter
|
|
280
|
+
* `keyNodeOrEntry` can be either a key, a node, an entry, or raw data. The function is
|
|
255
281
|
* checking if the input is an instance of a `BinaryTreeNode` and returning a boolean value
|
|
256
282
|
* accordingly.
|
|
257
|
-
* @returns The function `isNode` is checking if the input `
|
|
283
|
+
* @returns The function `isNode` is checking if the input `keyNodeOrEntry` is an instance of
|
|
258
284
|
* `BinaryTreeNode`. If it is, the function returns `true`, indicating that the input is a node. If
|
|
259
285
|
* it is not an instance of `BinaryTreeNode`, the function returns `false`, indicating that the input
|
|
260
286
|
* is not a node.
|
|
261
287
|
*/
|
|
262
|
-
isNode(
|
|
263
|
-
return
|
|
288
|
+
isNode(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>): keyNodeOrEntry is BinaryTreeNode<K, V> {
|
|
289
|
+
return keyNodeOrEntry instanceof BinaryTreeNode;
|
|
264
290
|
}
|
|
265
291
|
|
|
266
292
|
/**
|
|
293
|
+
* Time Complexity: O(1)
|
|
294
|
+
* Space Complexity: O(1)
|
|
295
|
+
*
|
|
267
296
|
* The function `isRaw` checks if the input parameter is of type `R` by verifying if it is an object.
|
|
268
|
-
* @param {BTNRep<K, V,
|
|
297
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>> | R} keyNodeEntryOrRaw - BTNRep<K, V, BinaryTreeNode<K, V>>
|
|
269
298
|
* @returns The function `isRaw` is checking if the `keyNodeEntryOrRaw` parameter is of type `R` by
|
|
270
299
|
* checking if it is an object. If the parameter is an object, the function will return `true`,
|
|
271
300
|
* indicating that it is of type `R`.
|
|
272
301
|
*/
|
|
273
|
-
isRaw(keyNodeEntryOrRaw: BTNRep<K, V,
|
|
302
|
+
isRaw(keyNodeEntryOrRaw: BTNRep<K, V, BinaryTreeNode<K, V>> | R): keyNodeEntryOrRaw is R {
|
|
274
303
|
return this._toEntryFn !== undefined && typeof keyNodeEntryOrRaw === 'object';
|
|
275
304
|
}
|
|
276
305
|
|
|
277
306
|
/**
|
|
307
|
+
* Time Complexity: O(1)
|
|
308
|
+
* Space Complexity: O(1)
|
|
309
|
+
*
|
|
278
310
|
* The function `isRealNode` checks if a given input is a valid node in a binary tree.
|
|
279
|
-
* @param {BTNRep<K, V,
|
|
280
|
-
* parameter in the `isRealNode` function can be of type `BTNRep<K, V,
|
|
281
|
-
* The function checks if the input parameter is a `
|
|
282
|
-
* @returns The function `isRealNode` is checking if the input `
|
|
311
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The `keyNodeOrEntry`
|
|
312
|
+
* parameter in the `isRealNode` function can be of type `BTNRep<K, V, BinaryTreeNode<K, V>>` or `R`.
|
|
313
|
+
* The function checks if the input parameter is a `BinaryTreeNode<K, V>` type by verifying if it is not equal
|
|
314
|
+
* @returns The function `isRealNode` is checking if the input `keyNodeOrEntry` is a valid
|
|
283
315
|
* node by comparing it to `this._NIL`, `null`, and `undefined`. If the input is not one of these
|
|
284
316
|
* values, it then calls the `isNode` method to further determine if the input is a node. The
|
|
285
317
|
* function will return a boolean value indicating whether the
|
|
286
318
|
*/
|
|
287
|
-
isRealNode(
|
|
288
|
-
if (
|
|
289
|
-
return this.isNode(
|
|
319
|
+
isRealNode(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>): keyNodeOrEntry is BinaryTreeNode<K, V> {
|
|
320
|
+
if (keyNodeOrEntry === this._NIL || keyNodeOrEntry === null || keyNodeOrEntry === undefined) return false;
|
|
321
|
+
return this.isNode(keyNodeOrEntry);
|
|
290
322
|
}
|
|
291
323
|
|
|
292
324
|
/**
|
|
325
|
+
* Time Complexity: O(1)
|
|
326
|
+
* Space Complexity: O(1)
|
|
327
|
+
*
|
|
293
328
|
* The function checks if a given input is a valid node or null.
|
|
294
|
-
* @param {BTNRep<K, V,
|
|
295
|
-
* `
|
|
296
|
-
* V,
|
|
329
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The parameter
|
|
330
|
+
* `keyNodeOrEntry` in the `isRealNodeOrNull` function can be of type `BTNRep<K,
|
|
331
|
+
* V, BinaryTreeNode<K, V>>` or `R`. It is a union type that can either be a key, a node, an entry, or
|
|
297
332
|
* @returns The function `isRealNodeOrNull` is returning a boolean value. It checks if the input
|
|
298
|
-
* `
|
|
333
|
+
* `keyNodeOrEntry` is either `null` or a real node, and returns `true` if it is a node or
|
|
299
334
|
* `null`, and `false` otherwise.
|
|
300
335
|
*/
|
|
301
|
-
isRealNodeOrNull(
|
|
302
|
-
return
|
|
336
|
+
isRealNodeOrNull(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>): keyNodeOrEntry is BinaryTreeNode<K, V> | null {
|
|
337
|
+
return keyNodeOrEntry === null || this.isRealNode(keyNodeOrEntry);
|
|
303
338
|
}
|
|
304
339
|
|
|
305
340
|
/**
|
|
341
|
+
* Time Complexity: O(1)
|
|
342
|
+
* Space Complexity: O(1)
|
|
343
|
+
*
|
|
306
344
|
* The function isNIL checks if a given key, node, entry, or raw value is equal to the _NIL value.
|
|
307
|
-
* @param {BTNRep<K, V,
|
|
308
|
-
*
|
|
309
|
-
* @returns The function is checking if the `
|
|
345
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - BTNRep<K, V,
|
|
346
|
+
* BinaryTreeNode<K, V>>
|
|
347
|
+
* @returns The function is checking if the `keyNodeOrEntry` parameter is equal to the `_NIL`
|
|
310
348
|
* property of the current object and returning a boolean value based on that comparison.
|
|
311
349
|
*/
|
|
312
|
-
isNIL(
|
|
313
|
-
return
|
|
350
|
+
isNIL(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>): boolean {
|
|
351
|
+
return keyNodeOrEntry === this._NIL;
|
|
314
352
|
}
|
|
315
353
|
|
|
354
|
+
/**
|
|
355
|
+
* Time Complexity: O(1)
|
|
356
|
+
* Space Complexity: O(1)
|
|
357
|
+
*
|
|
358
|
+
* The function `isRange` checks if the input parameter is an instance of the `Range` class.
|
|
359
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>> | Range<K>}
|
|
360
|
+
* keyNodeEntryOrPredicate - The `keyNodeEntryOrPredicate` parameter in the `isRange` function can be
|
|
361
|
+
* of type `BTNRep<K, V, BinaryTreeNode<K, V>>`, `NodePredicate<BinaryTreeNode<K, V>>`, or
|
|
362
|
+
* `Range<K>`. The function checks if the `keyNodeEntry
|
|
363
|
+
* @returns The `isRange` function is checking if the `keyNodeEntryOrPredicate` parameter is an
|
|
364
|
+
* instance of the `Range` class. If it is an instance of `Range`, the function will return `true`,
|
|
365
|
+
* indicating that the parameter is a `Range<K>`. If it is not an instance of `Range`, the function
|
|
366
|
+
* will return `false`.
|
|
367
|
+
*/
|
|
316
368
|
isRange(
|
|
317
|
-
|
|
318
|
-
):
|
|
319
|
-
return
|
|
369
|
+
keyNodeEntryOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>> | Range<K>
|
|
370
|
+
): keyNodeEntryOrPredicate is Range<K> {
|
|
371
|
+
return keyNodeEntryOrPredicate instanceof Range;
|
|
320
372
|
}
|
|
321
373
|
|
|
322
374
|
/**
|
|
375
|
+
* Time Complexity: O(1)
|
|
376
|
+
* Space Complexity: O(1)
|
|
377
|
+
*
|
|
323
378
|
* The function determines whether a given key, node, entry, or raw data is a leaf node in a binary
|
|
324
379
|
* tree.
|
|
325
|
-
* @param {BTNRep<K, V,
|
|
326
|
-
* `
|
|
380
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The parameter
|
|
381
|
+
* `keyNodeOrEntry` can be of type `BTNRep<K, V, BinaryTreeNode<K, V>>` or `R`. It represents a
|
|
327
382
|
* key, node, entry, or raw data in a binary tree structure. The function `isLeaf` checks whether the
|
|
328
383
|
* provided
|
|
329
384
|
* @returns The function `isLeaf` returns a boolean value indicating whether the input
|
|
330
|
-
* `
|
|
385
|
+
* `keyNodeOrEntry` is a leaf node in a binary tree.
|
|
331
386
|
*/
|
|
332
|
-
isLeaf(
|
|
333
|
-
|
|
334
|
-
if (
|
|
335
|
-
if (
|
|
336
|
-
return !this.isRealNode(
|
|
387
|
+
isLeaf(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>): boolean {
|
|
388
|
+
keyNodeOrEntry = this.ensureNode(keyNodeOrEntry);
|
|
389
|
+
if (keyNodeOrEntry === undefined) return false;
|
|
390
|
+
if (keyNodeOrEntry === null) return true;
|
|
391
|
+
return !this.isRealNode(keyNodeOrEntry.left) && !this.isRealNode(keyNodeOrEntry.right);
|
|
337
392
|
}
|
|
338
393
|
|
|
339
394
|
/**
|
|
395
|
+
* Time Complexity: O(1)
|
|
396
|
+
* Space Complexity: O(1)
|
|
397
|
+
*
|
|
340
398
|
* The function `isEntry` checks if the input is a BTNEntry object by verifying if it is an array
|
|
341
399
|
* with a length of 2.
|
|
342
|
-
* @param {BTNRep<K, V,
|
|
343
|
-
* parameter in the `isEntry` function can be of type `BTNRep<K, V,
|
|
344
|
-
* The function checks if the provided `
|
|
345
|
-
* @returns The `isEntry` function is checking if the `
|
|
400
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The `keyNodeOrEntry`
|
|
401
|
+
* parameter in the `isEntry` function can be of type `BTNRep<K, V, BinaryTreeNode<K, V>>` or type `R`.
|
|
402
|
+
* The function checks if the provided `keyNodeOrEntry` is of type `BTN
|
|
403
|
+
* @returns The `isEntry` function is checking if the `keyNodeOrEntry` parameter is an array
|
|
346
404
|
* with a length of 2. If it is, then it returns `true`, indicating that the parameter is of type
|
|
347
405
|
* `BTNEntry<K, V>`. If the condition is not met, it returns `false`.
|
|
348
406
|
*/
|
|
349
|
-
isEntry(
|
|
350
|
-
return Array.isArray(
|
|
407
|
+
isEntry(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>): keyNodeOrEntry is BTNEntry<K, V> {
|
|
408
|
+
return Array.isArray(keyNodeOrEntry) && keyNodeOrEntry.length === 2;
|
|
351
409
|
}
|
|
352
410
|
|
|
353
411
|
/**
|
|
354
412
|
* Time Complexity O(1)
|
|
355
413
|
* Space Complexity O(1)
|
|
356
414
|
*
|
|
357
|
-
* The function `
|
|
415
|
+
* The function `isValidKey` checks if a given key is comparable.
|
|
358
416
|
* @param {any} key - The `key` parameter is of type `any`, which means it can be any data type in
|
|
359
417
|
* TypeScript.
|
|
360
|
-
* @returns The function `
|
|
418
|
+
* @returns The function `isValidKey` is checking if the `key` parameter is `null` or if it is comparable.
|
|
361
419
|
* If the `key` is `null`, the function returns `true`. Otherwise, it returns the result of the
|
|
362
420
|
* `isComparable` function, which is not provided in the code snippet.
|
|
363
421
|
*/
|
|
364
|
-
|
|
422
|
+
isValidKey(key: any): key is K {
|
|
365
423
|
if (key === null) return true;
|
|
366
424
|
return isComparable(key);
|
|
367
425
|
}
|
|
@@ -372,8 +430,8 @@ export class BinaryTree<
|
|
|
372
430
|
*
|
|
373
431
|
* The `add` function in TypeScript adds a new node to a binary tree while handling duplicate keys
|
|
374
432
|
* and finding the correct insertion position.
|
|
375
|
-
* @param {BTNRep<K, V,
|
|
376
|
-
* seems to be for adding a new node to a binary tree structure. The `
|
|
433
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The `add` method you provided
|
|
434
|
+
* seems to be for adding a new node to a binary tree structure. The `keyNodeOrEntry`
|
|
377
435
|
* parameter in the method can accept different types of values:
|
|
378
436
|
* @param {V} [value] - The `value` parameter in the `add` method represents the value associated
|
|
379
437
|
* with the key that you want to add to the binary tree. When adding a key-value pair to the binary
|
|
@@ -383,8 +441,8 @@ export class BinaryTree<
|
|
|
383
441
|
* node was successful, and `false` if the insertion position could not be found or if a duplicate
|
|
384
442
|
* key was found and the node was replaced instead of inserted.
|
|
385
443
|
*/
|
|
386
|
-
add(
|
|
387
|
-
const [newNode, newValue] = this.
|
|
444
|
+
add(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>, value?: V): boolean {
|
|
445
|
+
const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
|
|
388
446
|
if (newNode === undefined) return false;
|
|
389
447
|
|
|
390
448
|
// If the tree is empty, directly set the new node as the root node
|
|
@@ -395,8 +453,8 @@ export class BinaryTree<
|
|
|
395
453
|
return true;
|
|
396
454
|
}
|
|
397
455
|
|
|
398
|
-
const queue = new Queue<
|
|
399
|
-
let potentialParent:
|
|
456
|
+
const queue = new Queue<BinaryTreeNode<K, V>>([this._root]);
|
|
457
|
+
let potentialParent: BinaryTreeNode<K, V> | undefined; // Record the parent node of the potential insertion location
|
|
400
458
|
|
|
401
459
|
while (queue.size > 0) {
|
|
402
460
|
const cur = queue.shift();
|
|
@@ -441,14 +499,14 @@ export class BinaryTree<
|
|
|
441
499
|
|
|
442
500
|
/**
|
|
443
501
|
* Time Complexity: O(k * n)
|
|
444
|
-
* Space Complexity: O(
|
|
502
|
+
* Space Complexity: O(k)
|
|
445
503
|
*
|
|
446
504
|
* The `addMany` function takes in multiple keys or nodes or entries or raw values along with
|
|
447
505
|
* optional values, and adds them to a data structure while returning an array indicating whether
|
|
448
506
|
* each insertion was successful.
|
|
449
507
|
* @param keysNodesEntriesOrRaws - `keysNodesEntriesOrRaws` is an iterable that can contain a
|
|
450
508
|
* mix of keys, nodes, entries, or raw values. Each element in this iterable can be of type
|
|
451
|
-
* `BTNRep<K, V,
|
|
509
|
+
* `BTNRep<K, V, BinaryTreeNode<K, V>>` or `R`.
|
|
452
510
|
* @param [values] - The `values` parameter in the `addMany` function is an optional parameter that
|
|
453
511
|
* accepts an iterable of values. These values correspond to the keys or nodes being added in the
|
|
454
512
|
* `keysNodesEntriesOrRaws` parameter. If provided, the function will iterate over the values and
|
|
@@ -457,7 +515,10 @@ export class BinaryTree<
|
|
|
457
515
|
* node, entry, or raw value was successfully added to the data structure. Each boolean value
|
|
458
516
|
* corresponds to the success of adding the corresponding key or value in the input iterable.
|
|
459
517
|
*/
|
|
460
|
-
addMany(
|
|
518
|
+
addMany(
|
|
519
|
+
keysNodesEntriesOrRaws: Iterable<BTNRep<K, V, BinaryTreeNode<K, V>> | R>,
|
|
520
|
+
values?: Iterable<V | undefined>
|
|
521
|
+
): boolean[] {
|
|
461
522
|
// TODO not sure addMany not be run multi times
|
|
462
523
|
const inserted: boolean[] = [];
|
|
463
524
|
|
|
@@ -466,7 +527,7 @@ export class BinaryTree<
|
|
|
466
527
|
valuesIterator = values[Symbol.iterator]();
|
|
467
528
|
}
|
|
468
529
|
|
|
469
|
-
for (
|
|
530
|
+
for (let keyNodeEntryOrRaw of keysNodesEntriesOrRaws) {
|
|
470
531
|
let value: V | undefined | null = undefined;
|
|
471
532
|
|
|
472
533
|
if (valuesIterator) {
|
|
@@ -475,7 +536,7 @@ export class BinaryTree<
|
|
|
475
536
|
value = valueResult.value;
|
|
476
537
|
}
|
|
477
538
|
}
|
|
478
|
-
|
|
539
|
+
if (this.isRaw(keyNodeEntryOrRaw)) keyNodeEntryOrRaw = this._toEntryFn!(keyNodeEntryOrRaw);
|
|
479
540
|
inserted.push(this.add(keyNodeEntryOrRaw, value));
|
|
480
541
|
}
|
|
481
542
|
|
|
@@ -488,9 +549,9 @@ export class BinaryTree<
|
|
|
488
549
|
*
|
|
489
550
|
* The `merge` function in TypeScript merges another binary tree into the current tree by adding all
|
|
490
551
|
* elements from the other tree.
|
|
491
|
-
* @param anotherTree -
|
|
552
|
+
* @param anotherTree - BinaryTree<K, V, R, MK, MV, MR>
|
|
492
553
|
*/
|
|
493
|
-
merge(anotherTree:
|
|
554
|
+
merge(anotherTree: BinaryTree<K, V, R, MK, MV, MR>) {
|
|
494
555
|
this.addMany(anotherTree, []);
|
|
495
556
|
}
|
|
496
557
|
|
|
@@ -501,12 +562,15 @@ export class BinaryTree<
|
|
|
501
562
|
* The `refill` function clears the existing data structure and then adds new key-value pairs based
|
|
502
563
|
* on the provided input.
|
|
503
564
|
* @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the `refill`
|
|
504
|
-
* method can accept an iterable containing a mix of `BTNRep<K, V,
|
|
565
|
+
* method can accept an iterable containing a mix of `BTNRep<K, V, BinaryTreeNode<K, V>>` objects or `R`
|
|
505
566
|
* objects.
|
|
506
567
|
* @param [values] - The `values` parameter in the `refill` method is an optional parameter that
|
|
507
568
|
* accepts an iterable of values of type `V` or `undefined`.
|
|
508
569
|
*/
|
|
509
|
-
refill(
|
|
570
|
+
refill(
|
|
571
|
+
keysNodesEntriesOrRaws: Iterable<BTNRep<K, V, BinaryTreeNode<K, V>> | R>,
|
|
572
|
+
values?: Iterable<V | undefined>
|
|
573
|
+
): void {
|
|
510
574
|
this.clear();
|
|
511
575
|
this.addMany(keysNodesEntriesOrRaws, values);
|
|
512
576
|
}
|
|
@@ -517,7 +581,7 @@ export class BinaryTree<
|
|
|
517
581
|
*
|
|
518
582
|
* The function `delete` in TypeScript implements the deletion of a node in a binary tree and returns
|
|
519
583
|
* the deleted node along with information for tree balancing.
|
|
520
|
-
* @param {BTNRep<K, V,
|
|
584
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry
|
|
521
585
|
* - The `delete` method you provided is used to delete a node from a binary tree based on the key,
|
|
522
586
|
* node, entry or raw data. The method returns an array of
|
|
523
587
|
* `BinaryTreeDeleteResult` objects containing information about the deleted node and whether
|
|
@@ -526,16 +590,16 @@ export class BinaryTree<
|
|
|
526
590
|
* the array contains information about the node that was deleted (`deleted`) and the node that may
|
|
527
591
|
* need to be balanced (`needBalanced`).
|
|
528
592
|
*/
|
|
529
|
-
delete(
|
|
530
|
-
const deletedResult: BinaryTreeDeleteResult<
|
|
593
|
+
delete(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>): BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[] {
|
|
594
|
+
const deletedResult: BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[] = [];
|
|
531
595
|
if (!this._root) return deletedResult;
|
|
532
596
|
|
|
533
|
-
const curr = this.getNode(
|
|
597
|
+
const curr = this.getNode(keyNodeOrEntry);
|
|
534
598
|
if (!curr) return deletedResult;
|
|
535
599
|
|
|
536
|
-
const parent:
|
|
537
|
-
let needBalanced:
|
|
538
|
-
let orgCurrent:
|
|
600
|
+
const parent: BinaryTreeNode<K, V> | undefined = curr?.parent;
|
|
601
|
+
let needBalanced: BinaryTreeNode<K, V> | undefined;
|
|
602
|
+
let orgCurrent: BinaryTreeNode<K, V> | undefined = curr;
|
|
539
603
|
|
|
540
604
|
if (!curr.left && !curr.right && !parent) {
|
|
541
605
|
this._setRoot(undefined);
|
|
@@ -577,15 +641,15 @@ export class BinaryTree<
|
|
|
577
641
|
*
|
|
578
642
|
* The `search` function in TypeScript performs a depth-first or breadth-first search on a tree
|
|
579
643
|
* structure based on a given predicate or key, with options to return multiple results or just one.
|
|
580
|
-
* @param {BTNRep<K, V,
|
|
581
|
-
* `
|
|
644
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate - The
|
|
645
|
+
* `keyNodeEntryOrPredicate` parameter in the `search` function can accept three types of values:
|
|
582
646
|
* @param [onlyOne=false] - The `onlyOne` parameter in the `search` function is a boolean flag that
|
|
583
647
|
* determines whether the search should stop after finding the first matching node. If `onlyOne` is
|
|
584
648
|
* set to `true`, the search will return as soon as a matching node is found. If `onlyOne` is
|
|
585
649
|
* @param {C} callback - The `callback` parameter in the `search` function is a callback function
|
|
586
650
|
* that will be called on each node that matches the search criteria. It is of type `C`, which
|
|
587
|
-
* extends `NodeCallback<
|
|
588
|
-
* @param {BTNRep<K, V,
|
|
651
|
+
* extends `NodeCallback<BinaryTreeNode<K, V>>`. The default value for `callback` is `this._DEFAULT_NODE_CALLBACK` if
|
|
652
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the `search` function is
|
|
589
653
|
* used to specify the node from which the search operation should begin. It represents the starting
|
|
590
654
|
* point in the binary tree where the search will be performed. If no specific `startNode` is
|
|
591
655
|
* provided, the search operation will start from the root
|
|
@@ -595,23 +659,23 @@ export class BinaryTree<
|
|
|
595
659
|
* @returns The `search` function returns an array of values that match the provided criteria based
|
|
596
660
|
* on the search algorithm implemented within the function.
|
|
597
661
|
*/
|
|
598
|
-
search<C extends NodeCallback<
|
|
599
|
-
|
|
662
|
+
search<C extends NodeCallback<BinaryTreeNode<K, V>>>(
|
|
663
|
+
keyNodeEntryOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>,
|
|
600
664
|
onlyOne = false,
|
|
601
665
|
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
602
|
-
startNode: BTNRep<K, V,
|
|
666
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
|
|
603
667
|
iterationType: IterationType = this.iterationType
|
|
604
668
|
): ReturnType<C>[] {
|
|
605
|
-
if (
|
|
606
|
-
if (
|
|
669
|
+
if (keyNodeEntryOrPredicate === undefined) return [];
|
|
670
|
+
if (keyNodeEntryOrPredicate === null) return [];
|
|
607
671
|
startNode = this.ensureNode(startNode);
|
|
608
672
|
if (!startNode) return [];
|
|
609
|
-
const predicate = this._ensurePredicate(
|
|
673
|
+
const predicate = this._ensurePredicate(keyNodeEntryOrPredicate);
|
|
610
674
|
|
|
611
675
|
const ans: ReturnType<C>[] = [];
|
|
612
676
|
|
|
613
677
|
if (iterationType === 'RECURSIVE') {
|
|
614
|
-
const dfs = (cur:
|
|
678
|
+
const dfs = (cur: BinaryTreeNode<K, V>) => {
|
|
615
679
|
if (predicate(cur)) {
|
|
616
680
|
ans.push(callback(cur));
|
|
617
681
|
if (onlyOne) return;
|
|
@@ -646,12 +710,12 @@ export class BinaryTree<
|
|
|
646
710
|
*
|
|
647
711
|
* The function `getNodes` retrieves nodes from a binary tree based on a key, node, entry, raw data,
|
|
648
712
|
* or predicate, with options for recursive or iterative traversal.
|
|
649
|
-
* @param {BTNRep<K, V,
|
|
713
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate
|
|
650
714
|
* - The `getNodes` function you provided takes several parameters:
|
|
651
715
|
* @param [onlyOne=false] - The `onlyOne` parameter in the `getNodes` function is a boolean flag that
|
|
652
716
|
* determines whether to return only the first node that matches the criteria specified by the
|
|
653
|
-
* `
|
|
654
|
-
* @param {BTNRep<K, V,
|
|
717
|
+
* `keyNodeEntryOrPredicate` parameter. If `onlyOne` is set to `true`, the function will
|
|
718
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
|
|
655
719
|
* `getNodes` function is used to specify the starting point for traversing the binary tree. It
|
|
656
720
|
* represents the root node of the binary tree or the node from which the traversal should begin. If
|
|
657
721
|
* not provided, the default value is set to `this._root
|
|
@@ -662,24 +726,24 @@ export class BinaryTree<
|
|
|
662
726
|
* based on the input parameters and the iteration type specified.
|
|
663
727
|
*/
|
|
664
728
|
getNodes(
|
|
665
|
-
|
|
729
|
+
keyNodeEntryOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>,
|
|
666
730
|
onlyOne = false,
|
|
667
|
-
startNode: BTNRep<K, V,
|
|
731
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
|
|
668
732
|
iterationType: IterationType = this.iterationType
|
|
669
|
-
):
|
|
670
|
-
return this.search(
|
|
733
|
+
): BinaryTreeNode<K, V>[] {
|
|
734
|
+
return this.search(keyNodeEntryOrPredicate, onlyOne, node => node, startNode, iterationType);
|
|
671
735
|
}
|
|
672
736
|
|
|
673
737
|
/**
|
|
674
738
|
* Time Complexity: O(n)
|
|
675
|
-
* Space Complexity: O(log n)
|
|
739
|
+
* Space Complexity: O(log n)
|
|
676
740
|
*
|
|
677
741
|
* The `getNode` function retrieves a node based on the provided key, node, entry, raw data, or
|
|
678
742
|
* predicate.
|
|
679
|
-
* @param {BTNRep<K, V,
|
|
680
|
-
* - The `
|
|
743
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate
|
|
744
|
+
* - The `keyNodeEntryOrPredicate` parameter in the `getNode` function can accept a key,
|
|
681
745
|
* node, entry, raw data, or a predicate function.
|
|
682
|
-
* @param {BTNRep<K, V,
|
|
746
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
|
|
683
747
|
* `getNode` function is used to specify the starting point for searching for a node in a binary
|
|
684
748
|
* tree. If no specific starting point is provided, the default value is set to `this._root`, which
|
|
685
749
|
* is typically the root node of the binary tree.
|
|
@@ -691,11 +755,11 @@ export class BinaryTree<
|
|
|
691
755
|
* or `null` if no matching node is found.
|
|
692
756
|
*/
|
|
693
757
|
getNode(
|
|
694
|
-
|
|
695
|
-
startNode: BTNRep<K, V,
|
|
758
|
+
keyNodeEntryOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>,
|
|
759
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
|
|
696
760
|
iterationType: IterationType = this.iterationType
|
|
697
|
-
): OptNodeOrNull<
|
|
698
|
-
return this.search(
|
|
761
|
+
): OptNodeOrNull<BinaryTreeNode<K, V>> {
|
|
762
|
+
return this.search(keyNodeEntryOrPredicate, true, node => node, startNode, iterationType)[0];
|
|
699
763
|
}
|
|
700
764
|
|
|
701
765
|
/**
|
|
@@ -704,10 +768,10 @@ export class BinaryTree<
|
|
|
704
768
|
*
|
|
705
769
|
* This function overrides the `get` method to retrieve the value associated with a specified key,
|
|
706
770
|
* node, entry, raw data, or predicate in a data structure.
|
|
707
|
-
* @param {BTNRep<K, V,
|
|
708
|
-
* - The `
|
|
771
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate
|
|
772
|
+
* - The `keyNodeEntryOrPredicate` parameter in the `get` method can accept one of the
|
|
709
773
|
* following types:
|
|
710
|
-
* @param {BTNRep<K, V,
|
|
774
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the `get`
|
|
711
775
|
* method is used to specify the starting point for searching for a key or node in the binary tree.
|
|
712
776
|
* If no specific starting point is provided, the default starting point is the root of the binary
|
|
713
777
|
* tree (`this._root`).
|
|
@@ -721,16 +785,16 @@ export class BinaryTree<
|
|
|
721
785
|
* `undefined`.
|
|
722
786
|
*/
|
|
723
787
|
override get(
|
|
724
|
-
|
|
725
|
-
startNode: BTNRep<K, V,
|
|
788
|
+
keyNodeEntryOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>>,
|
|
789
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
|
|
726
790
|
iterationType: IterationType = this.iterationType
|
|
727
791
|
): V | undefined {
|
|
728
792
|
if (this._isMapMode) {
|
|
729
|
-
const key = this._extractKey(
|
|
793
|
+
const key = this._extractKey(keyNodeEntryOrPredicate);
|
|
730
794
|
if (key === null || key === undefined) return;
|
|
731
795
|
return this._store.get(key);
|
|
732
796
|
}
|
|
733
|
-
return this.getNode(
|
|
797
|
+
return this.getNode(keyNodeEntryOrPredicate, startNode, iterationType)?.value;
|
|
734
798
|
}
|
|
735
799
|
|
|
736
800
|
/**
|
|
@@ -739,10 +803,10 @@ export class BinaryTree<
|
|
|
739
803
|
*
|
|
740
804
|
* The `has` function in TypeScript checks if a specified key, node, entry, raw data, or predicate
|
|
741
805
|
* exists in the data structure.
|
|
742
|
-
* @param {BTNRep<K, V,
|
|
743
|
-
* - The `
|
|
806
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate
|
|
807
|
+
* - The `keyNodeEntryOrPredicate` parameter in the `override has` method can accept one of
|
|
744
808
|
* the following types:
|
|
745
|
-
* @param {BTNRep<K, V,
|
|
809
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
|
|
746
810
|
* `override` method is used to specify the starting point for the search operation within the data
|
|
747
811
|
* structure. It defaults to `this._root` if not provided explicitly.
|
|
748
812
|
* @param {IterationType} iterationType - The `iterationType` parameter in the `override has` method
|
|
@@ -755,18 +819,18 @@ export class BinaryTree<
|
|
|
755
819
|
* Otherwise, it returns `false`.
|
|
756
820
|
*/
|
|
757
821
|
override has(
|
|
758
|
-
|
|
759
|
-
startNode: BTNRep<K, V,
|
|
822
|
+
keyNodeEntryOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>,
|
|
823
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
|
|
760
824
|
iterationType: IterationType = this.iterationType
|
|
761
825
|
): boolean {
|
|
762
|
-
return this.search(
|
|
826
|
+
return this.search(keyNodeEntryOrPredicate, true, node => node, startNode, iterationType).length > 0;
|
|
763
827
|
}
|
|
764
828
|
|
|
765
829
|
/**
|
|
766
830
|
* Time Complexity: O(1)
|
|
767
831
|
* Space Complexity: O(1)
|
|
768
832
|
*
|
|
769
|
-
* The
|
|
833
|
+
* The clear function removes nodes and values in map mode.
|
|
770
834
|
*/
|
|
771
835
|
clear() {
|
|
772
836
|
this._clearNodes();
|
|
@@ -792,7 +856,7 @@ export class BinaryTree<
|
|
|
792
856
|
*
|
|
793
857
|
* The function checks if a binary tree is perfectly balanced by comparing its minimum height with
|
|
794
858
|
* its height.
|
|
795
|
-
* @param {BTNRep<K, V,
|
|
859
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter is the starting
|
|
796
860
|
* point for checking if the binary tree is perfectly balanced. It represents the root node of the
|
|
797
861
|
* binary tree or a specific node from which the balance check should begin.
|
|
798
862
|
* @returns The method `isPerfectlyBalanced` is returning a boolean value, which indicates whether
|
|
@@ -801,17 +865,17 @@ export class BinaryTree<
|
|
|
801
865
|
* height plus 1 is greater than or equal to the height of the tree, then it is considered perfectly
|
|
802
866
|
* balanced and
|
|
803
867
|
*/
|
|
804
|
-
isPerfectlyBalanced(startNode: BTNRep<K, V,
|
|
868
|
+
isPerfectlyBalanced(startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root): boolean {
|
|
805
869
|
return this.getMinHeight(startNode) + 1 >= this.getHeight(startNode);
|
|
806
870
|
}
|
|
807
871
|
|
|
808
872
|
/**
|
|
809
873
|
* Time Complexity: O(n)
|
|
810
|
-
* Space Complexity: O(
|
|
874
|
+
* Space Complexity: O(log n)
|
|
811
875
|
*
|
|
812
876
|
* The function `isBST` in TypeScript checks if a binary search tree is valid using either recursive
|
|
813
877
|
* or iterative methods.
|
|
814
|
-
* @param {BTNRep<K, V,
|
|
878
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the `isBST`
|
|
815
879
|
* function represents the starting point for checking whether a binary search tree (BST) is valid.
|
|
816
880
|
* It can be a node in the BST or a reference to the root of the BST. If no specific node is
|
|
817
881
|
* provided, the function will default to
|
|
@@ -823,13 +887,16 @@ export class BinaryTree<
|
|
|
823
887
|
* the tree satisfies the BST property, where for every node, all nodes in its left subtree have keys
|
|
824
888
|
* less than the node's key, and all nodes in its right subtree have keys greater than the node's
|
|
825
889
|
*/
|
|
826
|
-
isBST(
|
|
890
|
+
isBST(
|
|
891
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
|
|
892
|
+
iterationType: IterationType = this.iterationType
|
|
893
|
+
): boolean {
|
|
827
894
|
// TODO there is a bug
|
|
828
895
|
startNode = this.ensureNode(startNode);
|
|
829
896
|
if (!startNode) return true;
|
|
830
897
|
|
|
831
898
|
if (iterationType === 'RECURSIVE') {
|
|
832
|
-
const dfs = (cur: OptNodeOrNull<
|
|
899
|
+
const dfs = (cur: OptNodeOrNull<BinaryTreeNode<K, V>>, min: number, max: number): boolean => {
|
|
833
900
|
if (!this.isRealNode(cur)) return true;
|
|
834
901
|
const numKey = Number(cur.key);
|
|
835
902
|
if (numKey <= min || numKey >= max) return false;
|
|
@@ -844,7 +911,7 @@ export class BinaryTree<
|
|
|
844
911
|
const stack = [];
|
|
845
912
|
let prev = checkMax ? Number.MAX_SAFE_INTEGER : Number.MIN_SAFE_INTEGER;
|
|
846
913
|
// @ts-ignore
|
|
847
|
-
let curr: OptNodeOrNull<
|
|
914
|
+
let curr: OptNodeOrNull<BinaryTreeNode<K, V>> = startNode;
|
|
848
915
|
while (this.isRealNode(curr) || stack.length > 0) {
|
|
849
916
|
while (this.isRealNode(curr)) {
|
|
850
917
|
stack.push(curr);
|
|
@@ -866,13 +933,13 @@ export class BinaryTree<
|
|
|
866
933
|
|
|
867
934
|
/**
|
|
868
935
|
* Time Complexity: O(n)
|
|
869
|
-
* Space Complexity: O(
|
|
936
|
+
* Space Complexity: O(log n)
|
|
870
937
|
*
|
|
871
938
|
* The `getDepth` function calculates the depth between two nodes in a binary tree.
|
|
872
|
-
* @param {BTNRep<K, V,
|
|
939
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} dist - The `dist` parameter in the `getDepth`
|
|
873
940
|
* function represents the node or entry in a binary tree map, or a reference to a node in the tree.
|
|
874
941
|
* It is the target node for which you want to calculate the depth from the `startNode` node.
|
|
875
|
-
* @param {BTNRep<K, V,
|
|
942
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
|
|
876
943
|
* `getDepth` function represents the starting point from which you want to calculate the depth of a
|
|
877
944
|
* given node or entry in a binary tree. If no specific starting point is provided, the default value
|
|
878
945
|
* for `startNode` is set to the root of the binary
|
|
@@ -880,7 +947,10 @@ export class BinaryTree<
|
|
|
880
947
|
* `startNode` node in a binary tree. If the `dist` node is not found in the path to the `startNode`
|
|
881
948
|
* node, it returns the depth of the `dist` node from the root of the tree.
|
|
882
949
|
*/
|
|
883
|
-
getDepth(
|
|
950
|
+
getDepth(
|
|
951
|
+
dist: BTNRep<K, V, BinaryTreeNode<K, V>>,
|
|
952
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root
|
|
953
|
+
): number {
|
|
884
954
|
let distEnsured = this.ensureNode(dist);
|
|
885
955
|
const beginRootEnsured = this.ensureNode(startNode);
|
|
886
956
|
let depth = 0;
|
|
@@ -896,11 +966,11 @@ export class BinaryTree<
|
|
|
896
966
|
|
|
897
967
|
/**
|
|
898
968
|
* Time Complexity: O(n)
|
|
899
|
-
* Space Complexity: O(
|
|
969
|
+
* Space Complexity: O(log n)
|
|
900
970
|
*
|
|
901
971
|
* The `getHeight` function calculates the maximum height of a binary tree using either a recursive
|
|
902
972
|
* or iterative approach in TypeScript.
|
|
903
|
-
* @param {BTNRep<K, V,
|
|
973
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter is the starting
|
|
904
974
|
* point from which the height of the binary tree will be calculated. It can be a node in the binary
|
|
905
975
|
* tree or a reference to the root of the tree. If not provided, it defaults to the root of the
|
|
906
976
|
* binary tree data structure.
|
|
@@ -911,12 +981,15 @@ export class BinaryTree<
|
|
|
911
981
|
* root node. The height is calculated based on the maximum depth of the tree, considering either a
|
|
912
982
|
* recursive approach or an iterative approach depending on the `iterationType` parameter.
|
|
913
983
|
*/
|
|
914
|
-
getHeight(
|
|
984
|
+
getHeight(
|
|
985
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
|
|
986
|
+
iterationType: IterationType = this.iterationType
|
|
987
|
+
): number {
|
|
915
988
|
startNode = this.ensureNode(startNode);
|
|
916
989
|
if (!this.isRealNode(startNode)) return -1;
|
|
917
990
|
|
|
918
991
|
if (iterationType === 'RECURSIVE') {
|
|
919
|
-
const _getMaxHeight = (cur: OptNodeOrNull<
|
|
992
|
+
const _getMaxHeight = (cur: OptNodeOrNull<BinaryTreeNode<K, V>>): number => {
|
|
920
993
|
if (!this.isRealNode(cur)) return -1;
|
|
921
994
|
const leftHeight = _getMaxHeight(cur.left);
|
|
922
995
|
const rightHeight = _getMaxHeight(cur.right);
|
|
@@ -925,7 +998,7 @@ export class BinaryTree<
|
|
|
925
998
|
|
|
926
999
|
return _getMaxHeight(startNode);
|
|
927
1000
|
} else {
|
|
928
|
-
const stack: { node:
|
|
1001
|
+
const stack: { node: BinaryTreeNode<K, V>; depth: number }[] = [{ node: startNode, depth: 0 }];
|
|
929
1002
|
let maxHeight = 0;
|
|
930
1003
|
|
|
931
1004
|
while (stack.length > 0) {
|
|
@@ -947,7 +1020,7 @@ export class BinaryTree<
|
|
|
947
1020
|
*
|
|
948
1021
|
* The `getMinHeight` function calculates the minimum height of a binary tree using either a
|
|
949
1022
|
* recursive or iterative approach in TypeScript.
|
|
950
|
-
* @param {BTNRep<K, V,
|
|
1023
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
|
|
951
1024
|
* `getMinHeight` function represents the starting node from which the minimum height of the binary
|
|
952
1025
|
* tree will be calculated. It is either a node in the binary tree or a reference to the root of the
|
|
953
1026
|
* tree. If not provided, the default value is the root
|
|
@@ -960,14 +1033,14 @@ export class BinaryTree<
|
|
|
960
1033
|
* a stack) based on the `iterationType` parameter.
|
|
961
1034
|
*/
|
|
962
1035
|
getMinHeight(
|
|
963
|
-
startNode: BTNRep<K, V,
|
|
1036
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
|
|
964
1037
|
iterationType: IterationType = this.iterationType
|
|
965
1038
|
): number {
|
|
966
1039
|
startNode = this.ensureNode(startNode);
|
|
967
1040
|
if (!startNode) return -1;
|
|
968
1041
|
|
|
969
1042
|
if (iterationType === 'RECURSIVE') {
|
|
970
|
-
const _getMinHeight = (cur: OptNodeOrNull<
|
|
1043
|
+
const _getMinHeight = (cur: OptNodeOrNull<BinaryTreeNode<K, V>>): number => {
|
|
971
1044
|
if (!this.isRealNode(cur)) return 0;
|
|
972
1045
|
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return 0;
|
|
973
1046
|
const leftMinHeight = _getMinHeight(cur.left);
|
|
@@ -977,10 +1050,10 @@ export class BinaryTree<
|
|
|
977
1050
|
|
|
978
1051
|
return _getMinHeight(startNode);
|
|
979
1052
|
} else {
|
|
980
|
-
const stack:
|
|
981
|
-
let node: OptNodeOrNull<
|
|
982
|
-
last: OptNodeOrNull<
|
|
983
|
-
const depths: Map<
|
|
1053
|
+
const stack: BinaryTreeNode<K, V>[] = [];
|
|
1054
|
+
let node: OptNodeOrNull<BinaryTreeNode<K, V>> = startNode,
|
|
1055
|
+
last: OptNodeOrNull<BinaryTreeNode<K, V>> = null;
|
|
1056
|
+
const depths: Map<BinaryTreeNode<K, V>, number> = new Map();
|
|
984
1057
|
|
|
985
1058
|
while (stack.length > 0 || node) {
|
|
986
1059
|
if (this.isRealNode(node)) {
|
|
@@ -1015,7 +1088,7 @@ export class BinaryTree<
|
|
|
1015
1088
|
* the path to the root. It is expected to be a function that takes a node as an argument and returns
|
|
1016
1089
|
* a value based on that node. The return type of the callback function is determined by the generic
|
|
1017
1090
|
* type `C
|
|
1018
|
-
* @param {BTNRep<K, V,
|
|
1091
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} beginNode - The `beginNode` parameter in the
|
|
1019
1092
|
* `getPathToRoot` function can be either a key, a node, an entry, or any other value of type `R`.
|
|
1020
1093
|
* @param [isReverse=true] - The `isReverse` parameter in the `getPathToRoot` function determines
|
|
1021
1094
|
* whether the resulting path from the given `beginNode` to the root should be in reverse order or
|
|
@@ -1025,8 +1098,8 @@ export class BinaryTree<
|
|
|
1025
1098
|
* array is either in reverse order or in the original order based on the value of the `isReverse`
|
|
1026
1099
|
* parameter.
|
|
1027
1100
|
*/
|
|
1028
|
-
getPathToRoot<C extends NodeCallback<OptNodeOrNull<
|
|
1029
|
-
beginNode: BTNRep<K, V,
|
|
1101
|
+
getPathToRoot<C extends NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>>(
|
|
1102
|
+
beginNode: BTNRep<K, V, BinaryTreeNode<K, V>>,
|
|
1030
1103
|
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
1031
1104
|
isReverse = false
|
|
1032
1105
|
): ReturnType<C>[] {
|
|
@@ -1046,14 +1119,14 @@ export class BinaryTree<
|
|
|
1046
1119
|
|
|
1047
1120
|
/**
|
|
1048
1121
|
* Time Complexity: O(log n)
|
|
1049
|
-
* Space Complexity: O(
|
|
1122
|
+
* Space Complexity: O(log n)
|
|
1050
1123
|
*
|
|
1051
1124
|
* The function `getLeftMost` retrieves the leftmost node in a binary tree using either recursive or
|
|
1052
1125
|
* tail-recursive iteration.
|
|
1053
1126
|
* @param {C} callback - The `callback` parameter is a function that will be called with the leftmost
|
|
1054
1127
|
* node of a binary tree or with `undefined` if the tree is empty. It is provided with a default
|
|
1055
1128
|
* value of `_DEFAULT_NODE_CALLBACK` if not specified.
|
|
1056
|
-
* @param {BTNRep<K, V,
|
|
1129
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
|
|
1057
1130
|
* `getLeftMost` function represents the starting point for finding the leftmost node in a binary
|
|
1058
1131
|
* tree. It can be either a key, a node, or an entry in the binary tree structure. If no specific
|
|
1059
1132
|
* starting point is provided, the function will default
|
|
@@ -1065,9 +1138,9 @@ export class BinaryTree<
|
|
|
1065
1138
|
* `NIL`, it returns the result of the callback function applied to `undefined`. If the `startNode`
|
|
1066
1139
|
* node is not a real node, it returns the result of the callback
|
|
1067
1140
|
*/
|
|
1068
|
-
getLeftMost<C extends NodeCallback<OptNodeOrNull<
|
|
1141
|
+
getLeftMost<C extends NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>>(
|
|
1069
1142
|
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
1070
|
-
startNode: BTNRep<K, V,
|
|
1143
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
|
|
1071
1144
|
iterationType: IterationType = this.iterationType
|
|
1072
1145
|
): ReturnType<C> {
|
|
1073
1146
|
if (this.isNIL(startNode)) return callback(undefined);
|
|
@@ -1076,7 +1149,7 @@ export class BinaryTree<
|
|
|
1076
1149
|
if (!this.isRealNode(startNode)) return callback(startNode);
|
|
1077
1150
|
|
|
1078
1151
|
if (iterationType === 'RECURSIVE') {
|
|
1079
|
-
const dfs = (cur:
|
|
1152
|
+
const dfs = (cur: BinaryTreeNode<K, V>): BinaryTreeNode<K, V> => {
|
|
1080
1153
|
if (!this.isRealNode(cur.left)) return cur;
|
|
1081
1154
|
return dfs(cur.left);
|
|
1082
1155
|
};
|
|
@@ -1084,7 +1157,7 @@ export class BinaryTree<
|
|
|
1084
1157
|
return callback(dfs(startNode));
|
|
1085
1158
|
} else {
|
|
1086
1159
|
// Indirect implementation of iteration using tail recursion optimization
|
|
1087
|
-
const dfs = trampoline((cur:
|
|
1160
|
+
const dfs = trampoline((cur: BinaryTreeNode<K, V>): BinaryTreeNode<K, V> => {
|
|
1088
1161
|
if (!this.isRealNode(cur.left)) return cur;
|
|
1089
1162
|
return dfs.cont(cur.left);
|
|
1090
1163
|
});
|
|
@@ -1095,15 +1168,15 @@ export class BinaryTree<
|
|
|
1095
1168
|
|
|
1096
1169
|
/**
|
|
1097
1170
|
* Time Complexity: O(log n)
|
|
1098
|
-
* Space Complexity: O(
|
|
1171
|
+
* Space Complexity: O(log n)
|
|
1099
1172
|
*
|
|
1100
1173
|
* The function `getRightMost` retrieves the rightmost node in a binary tree using either recursive
|
|
1101
1174
|
* or iterative traversal methods.
|
|
1102
1175
|
* @param {C} callback - The `callback` parameter is a function that will be called with the result
|
|
1103
|
-
* of finding the rightmost node in a binary tree. It is of type `NodeCallback<OptNodeOrNull<
|
|
1176
|
+
* of finding the rightmost node in a binary tree. It is of type `NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>`,
|
|
1104
1177
|
* which means it is a callback function that can accept either an optional binary tree node or null
|
|
1105
1178
|
* as
|
|
1106
|
-
* @param {BTNRep<K, V,
|
|
1179
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
|
|
1107
1180
|
* `getRightMost` function represents the starting point for finding the rightmost node in a binary
|
|
1108
1181
|
* tree. It can be either a key, a node, or an entry in the binary tree structure. If no specific
|
|
1109
1182
|
* starting point is provided, the function will default
|
|
@@ -1115,9 +1188,9 @@ export class BinaryTree<
|
|
|
1115
1188
|
* the binary tree structure, determined based on the specified iteration type ('RECURSIVE' or
|
|
1116
1189
|
* other).
|
|
1117
1190
|
*/
|
|
1118
|
-
getRightMost<C extends NodeCallback<OptNodeOrNull<
|
|
1191
|
+
getRightMost<C extends NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>>(
|
|
1119
1192
|
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
1120
|
-
startNode: BTNRep<K, V,
|
|
1193
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
|
|
1121
1194
|
iterationType: IterationType = this.iterationType
|
|
1122
1195
|
): ReturnType<C> {
|
|
1123
1196
|
if (this.isNIL(startNode)) return callback(undefined);
|
|
@@ -1125,7 +1198,7 @@ export class BinaryTree<
|
|
|
1125
1198
|
if (!startNode) return callback(startNode);
|
|
1126
1199
|
|
|
1127
1200
|
if (iterationType === 'RECURSIVE') {
|
|
1128
|
-
const dfs = (cur:
|
|
1201
|
+
const dfs = (cur: BinaryTreeNode<K, V>): BinaryTreeNode<K, V> => {
|
|
1129
1202
|
if (!this.isRealNode(cur.right)) return cur;
|
|
1130
1203
|
return dfs(cur.right);
|
|
1131
1204
|
};
|
|
@@ -1133,7 +1206,7 @@ export class BinaryTree<
|
|
|
1133
1206
|
return callback(dfs(startNode));
|
|
1134
1207
|
} else {
|
|
1135
1208
|
// Indirect implementation of iteration using tail recursion optimization
|
|
1136
|
-
const dfs = trampoline((cur:
|
|
1209
|
+
const dfs = trampoline((cur: BinaryTreeNode<K, V>) => {
|
|
1137
1210
|
if (!this.isRealNode(cur.right)) return cur;
|
|
1138
1211
|
return dfs.cont(cur.right);
|
|
1139
1212
|
});
|
|
@@ -1144,20 +1217,20 @@ export class BinaryTree<
|
|
|
1144
1217
|
|
|
1145
1218
|
/**
|
|
1146
1219
|
* Time Complexity: O(log n)
|
|
1147
|
-
* Space Complexity: O(
|
|
1220
|
+
* Space Complexity: O(log n)
|
|
1148
1221
|
*
|
|
1149
1222
|
* The function `getPredecessor` in TypeScript returns the predecessor node of a given node in a
|
|
1150
1223
|
* binary tree.
|
|
1151
|
-
* @param {
|
|
1224
|
+
* @param {BinaryTreeNode<K, V>} node - The `getPredecessor` function you provided seems to be attempting to find the
|
|
1152
1225
|
* predecessor of a given node in a binary tree. However, there seems to be a logical issue in the
|
|
1153
1226
|
* while loop condition that might cause an infinite loop.
|
|
1154
|
-
* @returns The `getPredecessor` function returns the predecessor node of the input `
|
|
1227
|
+
* @returns The `getPredecessor` function returns the predecessor node of the input `BinaryTreeNode<K, V>` parameter.
|
|
1155
1228
|
* If the left child of the input node exists, it traverses to the rightmost node of the left subtree
|
|
1156
1229
|
* to find the predecessor. If the left child does not exist, it returns the input node itself.
|
|
1157
1230
|
*/
|
|
1158
|
-
getPredecessor(node:
|
|
1231
|
+
getPredecessor(node: BinaryTreeNode<K, V>): BinaryTreeNode<K, V> {
|
|
1159
1232
|
if (this.isRealNode(node.left)) {
|
|
1160
|
-
let predecessor: OptNodeOrNull<
|
|
1233
|
+
let predecessor: OptNodeOrNull<BinaryTreeNode<K, V>> = node.left;
|
|
1161
1234
|
while (!this.isRealNode(predecessor) || (this.isRealNode(predecessor.right) && predecessor.right !== node)) {
|
|
1162
1235
|
if (this.isRealNode(predecessor)) {
|
|
1163
1236
|
predecessor = predecessor.right;
|
|
@@ -1171,18 +1244,18 @@ export class BinaryTree<
|
|
|
1171
1244
|
|
|
1172
1245
|
/**
|
|
1173
1246
|
* Time Complexity: O(log n)
|
|
1174
|
-
* Space Complexity: O(
|
|
1247
|
+
* Space Complexity: O(log n)
|
|
1175
1248
|
*
|
|
1176
1249
|
* The function `getSuccessor` in TypeScript returns the next node in an in-order traversal of a
|
|
1177
1250
|
* binary tree.
|
|
1178
|
-
* @param {K |
|
|
1179
|
-
* type `K`, `
|
|
1251
|
+
* @param {K | BinaryTreeNode<K, V> | null} [x] - The `getSuccessor` function takes a parameter `x`, which can be of
|
|
1252
|
+
* type `K`, `BinaryTreeNode<K, V>`, or `null`.
|
|
1180
1253
|
* @returns The `getSuccessor` function returns the successor node of the input node `x`. If `x` has
|
|
1181
1254
|
* a right child, the function returns the leftmost node in the right subtree of `x`. If `x` does not
|
|
1182
1255
|
* have a right child, the function traverses up the parent nodes until it finds a node that is not
|
|
1183
1256
|
* the right child of its parent, and returns that node
|
|
1184
1257
|
*/
|
|
1185
|
-
getSuccessor(x?: K |
|
|
1258
|
+
getSuccessor(x?: K | BinaryTreeNode<K, V> | null): OptNodeOrNull<BinaryTreeNode<K, V>> {
|
|
1186
1259
|
x = this.ensureNode(x);
|
|
1187
1260
|
if (!this.isRealNode(x)) return undefined;
|
|
1188
1261
|
|
|
@@ -1190,7 +1263,7 @@ export class BinaryTree<
|
|
|
1190
1263
|
return this.getLeftMost(node => node, x.right);
|
|
1191
1264
|
}
|
|
1192
1265
|
|
|
1193
|
-
let y: OptNodeOrNull<
|
|
1266
|
+
let y: OptNodeOrNull<BinaryTreeNode<K, V>> = x.parent;
|
|
1194
1267
|
while (this.isRealNode(y) && x === y.right) {
|
|
1195
1268
|
x = y;
|
|
1196
1269
|
y = y.parent;
|
|
@@ -1198,17 +1271,17 @@ export class BinaryTree<
|
|
|
1198
1271
|
return y;
|
|
1199
1272
|
}
|
|
1200
1273
|
|
|
1201
|
-
dfs<C extends NodeCallback<
|
|
1274
|
+
dfs<C extends NodeCallback<BinaryTreeNode<K, V>>>(
|
|
1202
1275
|
callback?: C,
|
|
1203
1276
|
pattern?: DFSOrderPattern,
|
|
1204
|
-
startNode?: BTNRep<K, V,
|
|
1277
|
+
startNode?: BTNRep<K, V, BinaryTreeNode<K, V>>,
|
|
1205
1278
|
iterationType?: IterationType
|
|
1206
1279
|
): ReturnType<C>[];
|
|
1207
1280
|
|
|
1208
|
-
dfs<C extends NodeCallback<
|
|
1281
|
+
dfs<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(
|
|
1209
1282
|
callback?: C,
|
|
1210
1283
|
pattern?: DFSOrderPattern,
|
|
1211
|
-
startNode?: BTNRep<K, V,
|
|
1284
|
+
startNode?: BTNRep<K, V, BinaryTreeNode<K, V>>,
|
|
1212
1285
|
iterationType?: IterationType,
|
|
1213
1286
|
includeNull?: boolean
|
|
1214
1287
|
): ReturnType<C>[];
|
|
@@ -1220,12 +1293,12 @@ export class BinaryTree<
|
|
|
1220
1293
|
* The function `dfs` performs a depth-first search traversal on a binary tree structure based on the
|
|
1221
1294
|
* specified parameters.
|
|
1222
1295
|
* @param {C} callback - The `callback` parameter is a generic type `C` that extends the
|
|
1223
|
-
* `NodeCallback` interface with a type parameter of `OptNodeOrNull<
|
|
1296
|
+
* `NodeCallback` interface with a type parameter of `OptNodeOrNull<BinaryTreeNode<K, V>>`. It has a default value of
|
|
1224
1297
|
* `this._DEFAULT_NODE_CALLBACK as C`.
|
|
1225
1298
|
* @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `dfs` method specifies the
|
|
1226
1299
|
* order in which the Depth-First Search (DFS) algorithm should traverse the nodes in the tree. The
|
|
1227
1300
|
* possible values for the `pattern` parameter are:
|
|
1228
|
-
* @param {BTNRep<K, V,
|
|
1301
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the `dfs`
|
|
1229
1302
|
* method is used to specify the starting point for the Depth-First Search traversal. It can be
|
|
1230
1303
|
* either a `BTNRep` object representing a key, node, or entry in the binary tree map,
|
|
1231
1304
|
* or it can be a
|
|
@@ -1239,10 +1312,10 @@ export class BinaryTree<
|
|
|
1239
1312
|
* @returns The `dfs` method is returning an array of the return type specified by the generic type
|
|
1240
1313
|
* parameter `C`. The return type is determined by the callback function provided to the method.
|
|
1241
1314
|
*/
|
|
1242
|
-
dfs<C extends NodeCallback<OptNodeOrNull<
|
|
1315
|
+
dfs<C extends NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>>(
|
|
1243
1316
|
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
1244
1317
|
pattern: DFSOrderPattern = 'IN',
|
|
1245
|
-
startNode: BTNRep<K, V,
|
|
1318
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
|
|
1246
1319
|
iterationType: IterationType = this.iterationType,
|
|
1247
1320
|
includeNull = false
|
|
1248
1321
|
): ReturnType<C>[] {
|
|
@@ -1251,16 +1324,16 @@ export class BinaryTree<
|
|
|
1251
1324
|
return this._dfs(callback, pattern, startNode, iterationType, includeNull);
|
|
1252
1325
|
}
|
|
1253
1326
|
|
|
1254
|
-
bfs<C extends NodeCallback<
|
|
1327
|
+
bfs<C extends NodeCallback<BinaryTreeNode<K, V>>>(
|
|
1255
1328
|
callback?: C,
|
|
1256
|
-
startNode?: BTNRep<K, V,
|
|
1329
|
+
startNode?: BTNRep<K, V, BinaryTreeNode<K, V>>,
|
|
1257
1330
|
iterationType?: IterationType,
|
|
1258
1331
|
includeNull?: false
|
|
1259
1332
|
): ReturnType<C>[];
|
|
1260
1333
|
|
|
1261
|
-
bfs<C extends NodeCallback<
|
|
1334
|
+
bfs<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(
|
|
1262
1335
|
callback?: C,
|
|
1263
|
-
startNode?: BTNRep<K, V,
|
|
1336
|
+
startNode?: BTNRep<K, V, BinaryTreeNode<K, V>>,
|
|
1264
1337
|
iterationType?: IterationType,
|
|
1265
1338
|
includeNull?: true
|
|
1266
1339
|
): ReturnType<C>[];
|
|
@@ -1273,8 +1346,8 @@ export class BinaryTree<
|
|
|
1273
1346
|
* tree, executing a specified callback function on each node visited.
|
|
1274
1347
|
* @param {C} callback - The `callback` parameter in the `bfs` function is a function that will be
|
|
1275
1348
|
* called on each node visited during the breadth-first search traversal. It is a generic type `C`
|
|
1276
|
-
* that extends the `NodeCallback` type, which takes a parameter of type `
|
|
1277
|
-
* @param {BTNRep<K, V,
|
|
1349
|
+
* that extends the `NodeCallback` type, which takes a parameter of type `BinaryTreeNode<K, V>` or `null`.
|
|
1350
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the `bfs`
|
|
1278
1351
|
* function represents the starting point for the breadth-first search traversal in a binary tree. It
|
|
1279
1352
|
* can be specified as a key, node, or entry in the binary tree structure. If not provided, the
|
|
1280
1353
|
* default value is the root node of the binary
|
|
@@ -1288,19 +1361,21 @@ export class BinaryTree<
|
|
|
1288
1361
|
* @returns The `bfs` function returns an array of values that are the result of applying the
|
|
1289
1362
|
* provided callback function to each node in the binary tree in a breadth-first search manner.
|
|
1290
1363
|
*/
|
|
1291
|
-
bfs<C extends NodeCallback<
|
|
1364
|
+
bfs<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(
|
|
1292
1365
|
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
1293
|
-
startNode: BTNRep<K, V,
|
|
1366
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
|
|
1294
1367
|
iterationType: IterationType = this.iterationType,
|
|
1295
1368
|
includeNull = false
|
|
1296
1369
|
): ReturnType<C>[] {
|
|
1297
1370
|
startNode = this.ensureNode(startNode);
|
|
1298
1371
|
if (!startNode) return [];
|
|
1299
1372
|
|
|
1300
|
-
const ans: ReturnType<NodeCallback<
|
|
1373
|
+
const ans: ReturnType<NodeCallback<BinaryTreeNode<K, V>>>[] = [];
|
|
1301
1374
|
|
|
1302
1375
|
if (iterationType === 'RECURSIVE') {
|
|
1303
|
-
const queue: Queue<OptNodeOrNull<
|
|
1376
|
+
const queue: Queue<OptNodeOrNull<BinaryTreeNode<K, V>>> = new Queue<OptNodeOrNull<BinaryTreeNode<K, V>>>([
|
|
1377
|
+
startNode
|
|
1378
|
+
]);
|
|
1304
1379
|
|
|
1305
1380
|
const dfs = (level: number) => {
|
|
1306
1381
|
if (queue.size === 0) return;
|
|
@@ -1321,7 +1396,7 @@ export class BinaryTree<
|
|
|
1321
1396
|
|
|
1322
1397
|
dfs(0);
|
|
1323
1398
|
} else {
|
|
1324
|
-
const queue = new Queue<OptNodeOrNull<
|
|
1399
|
+
const queue = new Queue<OptNodeOrNull<BinaryTreeNode<K, V>>>([startNode]);
|
|
1325
1400
|
while (queue.size > 0) {
|
|
1326
1401
|
const levelSize = queue.size;
|
|
1327
1402
|
|
|
@@ -1350,7 +1425,7 @@ export class BinaryTree<
|
|
|
1350
1425
|
* structure based on a specified callback and iteration type.
|
|
1351
1426
|
* @param {C} callback - The `callback` parameter is a function that will be called on each leaf node
|
|
1352
1427
|
* in the binary tree. It is optional and defaults to a default callback function if not provided.
|
|
1353
|
-
* @param {BTNRep<K, V,
|
|
1428
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the `leaves`
|
|
1354
1429
|
* method is used to specify the starting point for finding and processing the leaves of a binary
|
|
1355
1430
|
* tree. It can be provided as either a key, a node, or an entry in the binary tree structure. If not
|
|
1356
1431
|
* explicitly provided, the default value
|
|
@@ -1360,17 +1435,17 @@ export class BinaryTree<
|
|
|
1360
1435
|
* @returns The `leaves` method returns an array of values that are the result of applying the
|
|
1361
1436
|
* provided callback function to each leaf node in the binary tree.
|
|
1362
1437
|
*/
|
|
1363
|
-
leaves<C extends NodeCallback<
|
|
1438
|
+
leaves<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(
|
|
1364
1439
|
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
1365
|
-
startNode: BTNRep<K, V,
|
|
1440
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
|
|
1366
1441
|
iterationType: IterationType = this.iterationType
|
|
1367
1442
|
): ReturnType<C>[] {
|
|
1368
1443
|
startNode = this.ensureNode(startNode);
|
|
1369
|
-
const leaves: ReturnType<NodeCallback<
|
|
1444
|
+
const leaves: ReturnType<NodeCallback<BinaryTreeNode<K, V>>>[] = [];
|
|
1370
1445
|
if (!this.isRealNode(startNode)) return [];
|
|
1371
1446
|
|
|
1372
1447
|
if (iterationType === 'RECURSIVE') {
|
|
1373
|
-
const dfs = (cur:
|
|
1448
|
+
const dfs = (cur: BinaryTreeNode<K, V>) => {
|
|
1374
1449
|
if (this.isLeaf(cur)) {
|
|
1375
1450
|
leaves.push(callback(cur));
|
|
1376
1451
|
}
|
|
@@ -1397,16 +1472,16 @@ export class BinaryTree<
|
|
|
1397
1472
|
return leaves;
|
|
1398
1473
|
}
|
|
1399
1474
|
|
|
1400
|
-
listLevels<C extends NodeCallback<
|
|
1475
|
+
listLevels<C extends NodeCallback<BinaryTreeNode<K, V>>>(
|
|
1401
1476
|
callback?: C,
|
|
1402
|
-
startNode?: BTNRep<K, V,
|
|
1477
|
+
startNode?: BTNRep<K, V, BinaryTreeNode<K, V>>,
|
|
1403
1478
|
iterationType?: IterationType,
|
|
1404
1479
|
includeNull?: false
|
|
1405
1480
|
): ReturnType<C>[][];
|
|
1406
1481
|
|
|
1407
|
-
listLevels<C extends NodeCallback<
|
|
1482
|
+
listLevels<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(
|
|
1408
1483
|
callback?: C,
|
|
1409
|
-
startNode?: BTNRep<K, V,
|
|
1484
|
+
startNode?: BTNRep<K, V, BinaryTreeNode<K, V>>,
|
|
1410
1485
|
iterationType?: IterationType,
|
|
1411
1486
|
includeNull?: true
|
|
1412
1487
|
): ReturnType<C>[][];
|
|
@@ -1420,7 +1495,7 @@ export class BinaryTree<
|
|
|
1420
1495
|
* @param {C} callback - The `callback` parameter is a function that will be applied to each node in
|
|
1421
1496
|
* the binary tree during the traversal. It is used to process each node and determine what
|
|
1422
1497
|
* information to include in the output for each level of the tree.
|
|
1423
|
-
* @param {BTNRep<K, V,
|
|
1498
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
|
|
1424
1499
|
* `listLevels` function represents the starting point for traversing the binary tree. It can be
|
|
1425
1500
|
* either a key, a node, or an entry in the binary tree. If not provided, the default value is the
|
|
1426
1501
|
* root of the binary tree.
|
|
@@ -1435,9 +1510,9 @@ export class BinaryTree<
|
|
|
1435
1510
|
* level in a binary tree. Each inner array contains the return value of the provided callback
|
|
1436
1511
|
* function applied to the nodes at that level.
|
|
1437
1512
|
*/
|
|
1438
|
-
listLevels<C extends NodeCallback<
|
|
1513
|
+
listLevels<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(
|
|
1439
1514
|
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
1440
|
-
startNode: BTNRep<K, V,
|
|
1515
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
|
|
1441
1516
|
iterationType: IterationType = this.iterationType,
|
|
1442
1517
|
includeNull = false
|
|
1443
1518
|
): ReturnType<C>[][] {
|
|
@@ -1446,7 +1521,7 @@ export class BinaryTree<
|
|
|
1446
1521
|
if (!startNode) return levelsNodes;
|
|
1447
1522
|
|
|
1448
1523
|
if (iterationType === 'RECURSIVE') {
|
|
1449
|
-
const _recursive = (node:
|
|
1524
|
+
const _recursive = (node: BinaryTreeNode<K, V> | null, level: number) => {
|
|
1450
1525
|
if (!levelsNodes[level]) levelsNodes[level] = [];
|
|
1451
1526
|
levelsNodes[level].push(callback(node));
|
|
1452
1527
|
if (includeNull) {
|
|
@@ -1460,7 +1535,7 @@ export class BinaryTree<
|
|
|
1460
1535
|
|
|
1461
1536
|
_recursive(startNode, 0);
|
|
1462
1537
|
} else {
|
|
1463
|
-
const stack: [
|
|
1538
|
+
const stack: [BinaryTreeNode<K, V> | null, number][] = [[startNode, 0]];
|
|
1464
1539
|
|
|
1465
1540
|
while (stack.length > 0) {
|
|
1466
1541
|
const head = stack.pop()!;
|
|
@@ -1490,11 +1565,11 @@ export class BinaryTree<
|
|
|
1490
1565
|
* Morris Traversal algorithm with different order patterns.
|
|
1491
1566
|
* @param {C} callback - The `callback` parameter in the `morris` function is a function that will be
|
|
1492
1567
|
* called on each node in the binary tree during the traversal. It is of type `C`, which extends the
|
|
1493
|
-
* `NodeCallback<
|
|
1568
|
+
* `NodeCallback<BinaryTreeNode<K, V>>` type. The default value for `callback` is `this._DEFAULT
|
|
1494
1569
|
* @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `morris` function specifies
|
|
1495
1570
|
* the type of Depth-First Search (DFS) order pattern to traverse the binary tree. The possible
|
|
1496
1571
|
* values for the `pattern` parameter are:
|
|
1497
|
-
* @param {BTNRep<K, V,
|
|
1572
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the `morris`
|
|
1498
1573
|
* function is the starting point for the Morris traversal algorithm. It represents the root node of
|
|
1499
1574
|
* the binary tree or the node from which the traversal should begin. It can be provided as either a
|
|
1500
1575
|
* key, a node, an entry, or a reference
|
|
@@ -1502,19 +1577,19 @@ export class BinaryTree<
|
|
|
1502
1577
|
* provided callback function to each node in the binary tree in the specified order pattern (IN,
|
|
1503
1578
|
* PRE, or POST).
|
|
1504
1579
|
*/
|
|
1505
|
-
morris<C extends NodeCallback<
|
|
1580
|
+
morris<C extends NodeCallback<BinaryTreeNode<K, V>>>(
|
|
1506
1581
|
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
1507
1582
|
pattern: DFSOrderPattern = 'IN',
|
|
1508
|
-
startNode: BTNRep<K, V,
|
|
1583
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root
|
|
1509
1584
|
): ReturnType<C>[] {
|
|
1510
1585
|
startNode = this.ensureNode(startNode);
|
|
1511
1586
|
if (!startNode) return [];
|
|
1512
|
-
const ans: ReturnType<NodeCallback<
|
|
1587
|
+
const ans: ReturnType<NodeCallback<BinaryTreeNode<K, V>>>[] = [];
|
|
1513
1588
|
|
|
1514
|
-
let cur: OptNodeOrNull<
|
|
1515
|
-
const _reverseEdge = (node: OptNodeOrNull<
|
|
1516
|
-
let pre: OptNodeOrNull<
|
|
1517
|
-
let next: OptNodeOrNull<
|
|
1589
|
+
let cur: OptNodeOrNull<BinaryTreeNode<K, V>> = startNode;
|
|
1590
|
+
const _reverseEdge = (node: OptNodeOrNull<BinaryTreeNode<K, V>>) => {
|
|
1591
|
+
let pre: OptNodeOrNull<BinaryTreeNode<K, V>> = null;
|
|
1592
|
+
let next: OptNodeOrNull<BinaryTreeNode<K, V>> = null;
|
|
1518
1593
|
while (node) {
|
|
1519
1594
|
next = node.right;
|
|
1520
1595
|
node.right = pre;
|
|
@@ -1523,9 +1598,9 @@ export class BinaryTree<
|
|
|
1523
1598
|
}
|
|
1524
1599
|
return pre;
|
|
1525
1600
|
};
|
|
1526
|
-
const _printEdge = (node: OptNodeOrNull<
|
|
1527
|
-
const tail: OptNodeOrNull<
|
|
1528
|
-
let cur: OptNodeOrNull<
|
|
1601
|
+
const _printEdge = (node: OptNodeOrNull<BinaryTreeNode<K, V>>) => {
|
|
1602
|
+
const tail: OptNodeOrNull<BinaryTreeNode<K, V>> = _reverseEdge(node);
|
|
1603
|
+
let cur: OptNodeOrNull<BinaryTreeNode<K, V>> = tail;
|
|
1529
1604
|
while (cur) {
|
|
1530
1605
|
ans.push(callback(cur));
|
|
1531
1606
|
cur = cur.right;
|
|
@@ -1601,6 +1676,11 @@ export class BinaryTree<
|
|
|
1601
1676
|
*/
|
|
1602
1677
|
clone() {
|
|
1603
1678
|
const cloned = this.createTree();
|
|
1679
|
+
this._clone(cloned);
|
|
1680
|
+
return cloned;
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
protected _clone(cloned: BinaryTree<K, V, R, MK, MV, MR>) {
|
|
1604
1684
|
this.bfs(
|
|
1605
1685
|
node => {
|
|
1606
1686
|
if (node === null) cloned.add(null);
|
|
@@ -1614,7 +1694,6 @@ export class BinaryTree<
|
|
|
1614
1694
|
true
|
|
1615
1695
|
);
|
|
1616
1696
|
if (this._isMapMode) cloned._store = this._store;
|
|
1617
|
-
return cloned;
|
|
1618
1697
|
}
|
|
1619
1698
|
|
|
1620
1699
|
/**
|
|
@@ -1663,11 +1742,11 @@ export class BinaryTree<
|
|
|
1663
1742
|
* @returns The `map` function is returning a new `BinaryTree` instance filled with entries that are
|
|
1664
1743
|
* the result of applying the provided `callback` function to each entry in the original tree.
|
|
1665
1744
|
*/
|
|
1666
|
-
map
|
|
1745
|
+
map(
|
|
1667
1746
|
callback: EntryCallback<K, V | undefined, [MK, MV]>,
|
|
1668
1747
|
options?: BinaryTreeOptions<MK, MV, MR>,
|
|
1669
1748
|
thisArg?: any
|
|
1670
|
-
) {
|
|
1749
|
+
): BinaryTree<MK, MV, MR> {
|
|
1671
1750
|
const newTree = new BinaryTree<MK, MV, MR>([], options);
|
|
1672
1751
|
let index = 0;
|
|
1673
1752
|
for (const [key, value] of this) {
|
|
@@ -1682,7 +1761,7 @@ export class BinaryTree<
|
|
|
1682
1761
|
*
|
|
1683
1762
|
* The function `toVisual` in TypeScript overrides the visual representation of a binary tree with
|
|
1684
1763
|
* customizable options for displaying undefined, null, and sentinel nodes.
|
|
1685
|
-
* @param {BTNRep<K, V,
|
|
1764
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
|
|
1686
1765
|
* `toVisual` method is used to specify the starting point for visualizing the binary tree structure.
|
|
1687
1766
|
* It can be a node, key, entry, or the root of the tree. If no specific starting point is provided,
|
|
1688
1767
|
* the default is set to the root
|
|
@@ -1694,7 +1773,10 @@ export class BinaryTree<
|
|
|
1694
1773
|
* the lines to the output string. The final output string contains the visual representation of the
|
|
1695
1774
|
* binary tree with the specified options.
|
|
1696
1775
|
*/
|
|
1697
|
-
override toVisual(
|
|
1776
|
+
override toVisual(
|
|
1777
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
|
|
1778
|
+
options?: BinaryTreePrintOptions
|
|
1779
|
+
): string {
|
|
1698
1780
|
const opts = { isShowUndefined: false, isShowNull: true, isShowRedBlackNIL: false, ...options };
|
|
1699
1781
|
startNode = this.ensureNode(startNode);
|
|
1700
1782
|
let output = '';
|
|
@@ -1704,8 +1786,8 @@ export class BinaryTree<
|
|
|
1704
1786
|
if (opts.isShowNull) output += `N for null\n`;
|
|
1705
1787
|
if (opts.isShowRedBlackNIL) output += `S for Sentinel Node(NIL)\n`;
|
|
1706
1788
|
|
|
1707
|
-
const display = (root: OptNodeOrNull<
|
|
1708
|
-
const [lines
|
|
1789
|
+
const display = (root: OptNodeOrNull<BinaryTreeNode<K, V>>): void => {
|
|
1790
|
+
const [lines] = this._displayAux(root, opts);
|
|
1709
1791
|
let paragraph = '';
|
|
1710
1792
|
for (const line of lines) {
|
|
1711
1793
|
paragraph += line + '\n';
|
|
@@ -1727,56 +1809,51 @@ export class BinaryTree<
|
|
|
1727
1809
|
* printing options for the binary tree. It is an optional parameter that allows you to customize how
|
|
1728
1810
|
* the binary tree is printed, such as choosing between different traversal orders or formatting
|
|
1729
1811
|
* options.
|
|
1730
|
-
* @param {BTNRep<K, V,
|
|
1812
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the
|
|
1731
1813
|
* `override print` method is used to specify the starting point for printing the binary tree. It can
|
|
1732
1814
|
* be either a key, a node, an entry, or the root of the tree. If no specific starting point is
|
|
1733
1815
|
* provided, the default value is set to
|
|
1734
1816
|
*/
|
|
1735
|
-
override print(options?: BinaryTreePrintOptions, startNode: BTNRep<K, V,
|
|
1817
|
+
override print(options?: BinaryTreePrintOptions, startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root) {
|
|
1736
1818
|
console.log(this.toVisual(startNode, options));
|
|
1737
1819
|
}
|
|
1738
1820
|
|
|
1739
1821
|
/**
|
|
1822
|
+
* Time Complexity: O(1)
|
|
1823
|
+
* Space Complexity: O(1)
|
|
1824
|
+
*
|
|
1740
1825
|
* The function `keyValueNodeEntryRawToNodeAndValue` converts various input types into a node object
|
|
1741
1826
|
* or returns null.
|
|
1742
|
-
* @param {BTNRep<K, V,
|
|
1743
|
-
* `keyValueNodeEntryRawToNodeAndValue` function takes in a parameter `
|
|
1744
|
-
* can be of type `BTNRep<K, V,
|
|
1827
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The
|
|
1828
|
+
* `keyValueNodeEntryRawToNodeAndValue` function takes in a parameter `keyNodeOrEntry`, which
|
|
1829
|
+
* can be of type `BTNRep<K, V, BinaryTreeNode<K, V>>` or `R`. This parameter represents either a key, a
|
|
1745
1830
|
* node, an entry
|
|
1746
1831
|
* @param {V} [value] - The `value` parameter in the `keyValueNodeEntryRawToNodeAndValue` function is
|
|
1747
1832
|
* an optional parameter of type `V`. It represents the value associated with the key in the node
|
|
1748
1833
|
* being created. If a `value` is provided, it will be used when creating the node. If
|
|
1749
1834
|
* @returns The `keyValueNodeEntryRawToNodeAndValue` function returns an optional node
|
|
1750
|
-
* (`OptNodeOrNull<
|
|
1751
|
-
* input parameter (`
|
|
1835
|
+
* (`OptNodeOrNull<BinaryTreeNode<K, V>>`) based on the input parameters provided. The function checks the type of the
|
|
1836
|
+
* input parameter (`keyNodeOrEntry`) and processes it accordingly to return a node or null
|
|
1752
1837
|
* value.
|
|
1753
1838
|
*/
|
|
1754
|
-
protected
|
|
1755
|
-
|
|
1839
|
+
protected _keyValueNodeOrEntryToNodeAndValue(
|
|
1840
|
+
keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>,
|
|
1756
1841
|
value?: V
|
|
1757
|
-
): [OptNodeOrNull<
|
|
1758
|
-
if (
|
|
1759
|
-
if (
|
|
1842
|
+
): [OptNodeOrNull<BinaryTreeNode<K, V>>, V | undefined] {
|
|
1843
|
+
if (keyNodeOrEntry === undefined) return [undefined, undefined];
|
|
1844
|
+
if (keyNodeOrEntry === null) return [null, undefined];
|
|
1760
1845
|
|
|
1761
|
-
if (this.isNode(
|
|
1846
|
+
if (this.isNode(keyNodeOrEntry)) return [keyNodeOrEntry, value];
|
|
1762
1847
|
|
|
1763
|
-
if (this.isEntry(
|
|
1764
|
-
const [key, entryValue] =
|
|
1848
|
+
if (this.isEntry(keyNodeOrEntry)) {
|
|
1849
|
+
const [key, entryValue] = keyNodeOrEntry;
|
|
1765
1850
|
if (key === undefined) return [undefined, undefined];
|
|
1766
1851
|
else if (key === null) return [null, undefined];
|
|
1767
1852
|
const finalValue = value ?? entryValue;
|
|
1768
1853
|
return [this.createNode(key, finalValue), finalValue];
|
|
1769
1854
|
}
|
|
1770
1855
|
|
|
1771
|
-
|
|
1772
|
-
const [key, entryValue] = this._toEntryFn!(keyNodeEntryOrRaw);
|
|
1773
|
-
const finalValue = value ?? entryValue;
|
|
1774
|
-
if (this.isKey(key)) return [this.createNode(key, finalValue), finalValue];
|
|
1775
|
-
}
|
|
1776
|
-
|
|
1777
|
-
if (this.isKey(keyNodeEntryOrRaw)) return [this.createNode(keyNodeEntryOrRaw, value), value];
|
|
1778
|
-
|
|
1779
|
-
return [undefined, undefined];
|
|
1856
|
+
return [this.createNode(keyNodeOrEntry, value), value];
|
|
1780
1857
|
}
|
|
1781
1858
|
|
|
1782
1859
|
/**
|
|
@@ -1787,11 +1864,11 @@ export class BinaryTree<
|
|
|
1787
1864
|
* the specified order pattern and callback function.
|
|
1788
1865
|
* @param {C} callback - The `callback` parameter in the `_dfs` method is a function that will be
|
|
1789
1866
|
* called on each node visited during the depth-first search traversal. It is of type `C`, which
|
|
1790
|
-
* extends `NodeCallback<OptNodeOrNull<
|
|
1867
|
+
* extends `NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>`. The default value for this parameter is `this._DEFAULT
|
|
1791
1868
|
* @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `_dfs` method specifies the
|
|
1792
1869
|
* order in which the nodes are visited during the Depth-First Search traversal. It can have one of
|
|
1793
1870
|
* the following values:
|
|
1794
|
-
* @param {BTNRep<K, V,
|
|
1871
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} startNode - The `startNode` parameter in the `_dfs`
|
|
1795
1872
|
* method is used to specify the starting point for the depth-first search traversal in a binary
|
|
1796
1873
|
* tree. It can be provided as either a `BTNRep` object or a reference to the root node
|
|
1797
1874
|
* of the tree. If no specific
|
|
@@ -1821,26 +1898,26 @@ export class BinaryTree<
|
|
|
1821
1898
|
* @returns The function `_dfs` returns an array of the return type of the callback function provided
|
|
1822
1899
|
* as input.
|
|
1823
1900
|
*/
|
|
1824
|
-
protected _dfs<C extends NodeCallback<OptNodeOrNull<
|
|
1901
|
+
protected _dfs<C extends NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>>(
|
|
1825
1902
|
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
1826
1903
|
pattern: DFSOrderPattern = 'IN',
|
|
1827
|
-
startNode: BTNRep<K, V,
|
|
1904
|
+
startNode: BTNRep<K, V, BinaryTreeNode<K, V>> = this._root,
|
|
1828
1905
|
iterationType: IterationType = this.iterationType,
|
|
1829
1906
|
includeNull = false,
|
|
1830
|
-
shouldVisitLeft: (node: OptNodeOrNull<
|
|
1831
|
-
shouldVisitRight: (node: OptNodeOrNull<
|
|
1832
|
-
shouldVisitRoot: (node: OptNodeOrNull<
|
|
1907
|
+
shouldVisitLeft: (node: OptNodeOrNull<BinaryTreeNode<K, V>>) => boolean = node => !!node,
|
|
1908
|
+
shouldVisitRight: (node: OptNodeOrNull<BinaryTreeNode<K, V>>) => boolean = node => !!node,
|
|
1909
|
+
shouldVisitRoot: (node: OptNodeOrNull<BinaryTreeNode<K, V>>) => boolean = node => {
|
|
1833
1910
|
if (includeNull) return this.isRealNodeOrNull(node);
|
|
1834
1911
|
return this.isRealNode(node);
|
|
1835
1912
|
},
|
|
1836
|
-
shouldProcessRoot: (node: OptNodeOrNull<
|
|
1913
|
+
shouldProcessRoot: (node: OptNodeOrNull<BinaryTreeNode<K, V>>) => boolean = node => this.isRealNodeOrNull(node)
|
|
1837
1914
|
): ReturnType<C>[] {
|
|
1838
1915
|
startNode = this.ensureNode(startNode);
|
|
1839
1916
|
if (!startNode) return [];
|
|
1840
1917
|
const ans: ReturnType<C>[] = [];
|
|
1841
1918
|
|
|
1842
1919
|
if (iterationType === 'RECURSIVE') {
|
|
1843
|
-
const dfs = (node: OptNodeOrNull<
|
|
1920
|
+
const dfs = (node: OptNodeOrNull<BinaryTreeNode<K, V>>) => {
|
|
1844
1921
|
if (!shouldVisitRoot(node)) return;
|
|
1845
1922
|
|
|
1846
1923
|
const visitLeft = () => {
|
|
@@ -1871,15 +1948,15 @@ export class BinaryTree<
|
|
|
1871
1948
|
|
|
1872
1949
|
dfs(startNode);
|
|
1873
1950
|
} else {
|
|
1874
|
-
const stack: DFSStackItem<
|
|
1951
|
+
const stack: DFSStackItem<BinaryTreeNode<K, V>>[] = [{ opt: DFSOperation.VISIT, node: startNode }];
|
|
1875
1952
|
|
|
1876
|
-
const pushLeft = (cur: DFSStackItem<
|
|
1953
|
+
const pushLeft = (cur: DFSStackItem<BinaryTreeNode<K, V>>) => {
|
|
1877
1954
|
if (shouldVisitLeft(cur.node)) stack.push({ opt: DFSOperation.VISIT, node: cur.node?.left });
|
|
1878
1955
|
};
|
|
1879
|
-
const pushRight = (cur: DFSStackItem<
|
|
1956
|
+
const pushRight = (cur: DFSStackItem<BinaryTreeNode<K, V>>) => {
|
|
1880
1957
|
if (shouldVisitRight(cur.node)) stack.push({ opt: DFSOperation.VISIT, node: cur.node?.right });
|
|
1881
1958
|
};
|
|
1882
|
-
const pushRoot = (cur: DFSStackItem<
|
|
1959
|
+
const pushRoot = (cur: DFSStackItem<BinaryTreeNode<K, V>>) => {
|
|
1883
1960
|
if (shouldVisitRoot(cur.node)) stack.push({ opt: DFSOperation.PROCESS, node: cur.node });
|
|
1884
1961
|
};
|
|
1885
1962
|
|
|
@@ -1933,8 +2010,8 @@ export class BinaryTree<
|
|
|
1933
2010
|
if (!node) return;
|
|
1934
2011
|
|
|
1935
2012
|
if (this.iterationType === 'ITERATIVE') {
|
|
1936
|
-
const stack: OptNodeOrNull<
|
|
1937
|
-
let current: OptNodeOrNull<
|
|
2013
|
+
const stack: OptNodeOrNull<BinaryTreeNode<K, V>>[] = [];
|
|
2014
|
+
let current: OptNodeOrNull<BinaryTreeNode<K, V>> = node;
|
|
1938
2015
|
|
|
1939
2016
|
while (current || stack.length > 0) {
|
|
1940
2017
|
while (this.isRealNode(current)) {
|
|
@@ -1977,7 +2054,7 @@ export class BinaryTree<
|
|
|
1977
2054
|
* information about how to display a node in a binary tree. The `NodeDisplayLayout` consists of four
|
|
1978
2055
|
* elements:
|
|
1979
2056
|
*/
|
|
1980
|
-
protected _displayAux(node: OptNodeOrNull<
|
|
2057
|
+
protected _displayAux(node: OptNodeOrNull<BinaryTreeNode<K, V>>, options: BinaryTreePrintOptions): NodeDisplayLayout {
|
|
1981
2058
|
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
1982
2059
|
const emptyDisplayLayout = <NodeDisplayLayout>[['─'], 1, 0, 0];
|
|
1983
2060
|
|
|
@@ -2045,24 +2122,27 @@ export class BinaryTree<
|
|
|
2045
2122
|
}
|
|
2046
2123
|
}
|
|
2047
2124
|
|
|
2048
|
-
protected _DEFAULT_NODE_CALLBACK = (node: OptNodeOrNull<
|
|
2125
|
+
protected _DEFAULT_NODE_CALLBACK = (node: OptNodeOrNull<BinaryTreeNode<K, V>>) => (node ? node.key : undefined);
|
|
2049
2126
|
|
|
2050
2127
|
/**
|
|
2051
2128
|
* Time Complexity: O(1)
|
|
2052
2129
|
* Space Complexity: O(1)
|
|
2053
2130
|
*
|
|
2054
2131
|
* The _swapProperties function swaps key and value properties between two nodes in a binary tree.
|
|
2055
|
-
* @param {BTNRep<K, V,
|
|
2132
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} srcNode - The `srcNode` parameter in the
|
|
2056
2133
|
* `_swapProperties` method can be either a BTNRep object containing key and value
|
|
2057
2134
|
* properties, or it can be of type R.
|
|
2058
|
-
* @param {BTNRep<K, V,
|
|
2135
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} destNode - The `destNode` parameter in the
|
|
2059
2136
|
* `_swapProperties` method represents the node or entry where the properties will be swapped with
|
|
2060
|
-
* the `srcNode`. It can be of type `BTNRep<K, V,
|
|
2137
|
+
* the `srcNode`. It can be of type `BTNRep<K, V, BinaryTreeNode<K, V>>` or `R`. The method ensures that
|
|
2061
2138
|
* both `srcNode
|
|
2062
2139
|
* @returns The `_swapProperties` method returns either the `destNode` with its key and value swapped
|
|
2063
2140
|
* with the `srcNode`, or `undefined` if either `srcNode` or `destNode` is falsy.
|
|
2064
2141
|
*/
|
|
2065
|
-
protected _swapProperties(
|
|
2142
|
+
protected _swapProperties(
|
|
2143
|
+
srcNode: BTNRep<K, V, BinaryTreeNode<K, V>>,
|
|
2144
|
+
destNode: BTNRep<K, V, BinaryTreeNode<K, V>>
|
|
2145
|
+
): BinaryTreeNode<K, V> | undefined {
|
|
2066
2146
|
srcNode = this.ensureNode(srcNode);
|
|
2067
2147
|
destNode = this.ensureNode(destNode);
|
|
2068
2148
|
|
|
@@ -2088,16 +2168,16 @@ export class BinaryTree<
|
|
|
2088
2168
|
* Space Complexity: O(1)
|
|
2089
2169
|
*
|
|
2090
2170
|
* The _replaceNode function replaces an old node with a new node in a binary tree structure.
|
|
2091
|
-
* @param {
|
|
2171
|
+
* @param {BinaryTreeNode<K, V>} oldNode - The `oldNode` parameter represents the node that you want to replace in a
|
|
2092
2172
|
* tree data structure.
|
|
2093
|
-
* @param {
|
|
2173
|
+
* @param {BinaryTreeNode<K, V>} newNode - The `newNode` parameter in the `_replaceNode` function represents the node
|
|
2094
2174
|
* that will replace the `oldNode` in a tree data structure. This function is responsible for
|
|
2095
2175
|
* updating the parent, left child, right child, and root (if necessary) references when replacing a
|
|
2096
2176
|
* node in the tree.
|
|
2097
2177
|
* @returns The method `_replaceNode` is returning the `newNode` that was passed as a parameter after
|
|
2098
2178
|
* replacing the `oldNode` with it in the binary tree structure.
|
|
2099
2179
|
*/
|
|
2100
|
-
protected _replaceNode(oldNode:
|
|
2180
|
+
protected _replaceNode(oldNode: BinaryTreeNode<K, V>, newNode: BinaryTreeNode<K, V>): BinaryTreeNode<K, V> {
|
|
2101
2181
|
if (oldNode.parent) {
|
|
2102
2182
|
if (oldNode.parent.left === oldNode) {
|
|
2103
2183
|
oldNode.parent.left = newNode;
|
|
@@ -2121,10 +2201,10 @@ export class BinaryTree<
|
|
|
2121
2201
|
*
|
|
2122
2202
|
* The function _setRoot sets the root node of a data structure while updating the parent reference
|
|
2123
2203
|
* of the previous root node.
|
|
2124
|
-
* @param v - The parameter `v` in the `_setRoot` method is of type `OptNodeOrNull<
|
|
2125
|
-
* it can either be an optional `
|
|
2204
|
+
* @param v - The parameter `v` in the `_setRoot` method is of type `OptNodeOrNull<BinaryTreeNode<K, V>>`, which means
|
|
2205
|
+
* it can either be an optional `BinaryTreeNode<K, V>` type or `null`.
|
|
2126
2206
|
*/
|
|
2127
|
-
protected _setRoot(v: OptNodeOrNull<
|
|
2207
|
+
protected _setRoot(v: OptNodeOrNull<BinaryTreeNode<K, V>>) {
|
|
2128
2208
|
if (v) {
|
|
2129
2209
|
v.parent = undefined;
|
|
2130
2210
|
}
|
|
@@ -2137,34 +2217,29 @@ export class BinaryTree<
|
|
|
2137
2217
|
*
|
|
2138
2218
|
* The function `_ensurePredicate` in TypeScript ensures that the input is converted into a valid
|
|
2139
2219
|
* predicate function for a binary tree node.
|
|
2140
|
-
* @param {BTNRep<K, V,
|
|
2220
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>} keyNodeEntryOrPredicate - The
|
|
2141
2221
|
* `_ensurePredicate` method in the provided code snippet is responsible for ensuring that the input
|
|
2142
|
-
* parameter `
|
|
2222
|
+
* parameter `keyNodeEntryOrPredicate` is transformed into a valid predicate function that can be
|
|
2143
2223
|
* used for filtering nodes in a binary tree.
|
|
2144
|
-
* @returns A NodePredicate<
|
|
2224
|
+
* @returns A NodePredicate<BinaryTreeNode<K, V>> function is being returned.
|
|
2145
2225
|
*/
|
|
2146
2226
|
protected _ensurePredicate(
|
|
2147
|
-
|
|
2148
|
-
): NodePredicate<
|
|
2149
|
-
if (
|
|
2150
|
-
return (node:
|
|
2227
|
+
keyNodeEntryOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>
|
|
2228
|
+
): NodePredicate<BinaryTreeNode<K, V>> {
|
|
2229
|
+
if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === undefined)
|
|
2230
|
+
return (node: BinaryTreeNode<K, V>) => (node ? false : false);
|
|
2151
2231
|
|
|
2152
|
-
if (this._isPredicate(
|
|
2232
|
+
if (this._isPredicate(keyNodeEntryOrPredicate)) return keyNodeEntryOrPredicate;
|
|
2153
2233
|
|
|
2154
|
-
if (this.isRealNode(
|
|
2234
|
+
if (this.isRealNode(keyNodeEntryOrPredicate))
|
|
2235
|
+
return (node: BinaryTreeNode<K, V>) => node === keyNodeEntryOrPredicate;
|
|
2155
2236
|
|
|
2156
|
-
if (this.isEntry(
|
|
2157
|
-
const [key] =
|
|
2158
|
-
return (node:
|
|
2237
|
+
if (this.isEntry(keyNodeEntryOrPredicate)) {
|
|
2238
|
+
const [key] = keyNodeEntryOrPredicate;
|
|
2239
|
+
return (node: BinaryTreeNode<K, V>) => node.key === key;
|
|
2159
2240
|
}
|
|
2160
2241
|
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
if (this._toEntryFn) {
|
|
2164
|
-
const [key] = this._toEntryFn(keyNodeEntryRawOrPredicate);
|
|
2165
|
-
return (node: NODE) => node.key === key;
|
|
2166
|
-
}
|
|
2167
|
-
return (node: NODE) => node.key === keyNodeEntryRawOrPredicate;
|
|
2242
|
+
return (node: BinaryTreeNode<K, V>) => node.key === keyNodeEntryOrPredicate;
|
|
2168
2243
|
}
|
|
2169
2244
|
|
|
2170
2245
|
/**
|
|
@@ -2174,12 +2249,12 @@ export class BinaryTree<
|
|
|
2174
2249
|
* The function `_isPredicate` checks if a given parameter is a function.
|
|
2175
2250
|
* @param {any} p - The parameter `p` is a variable of type `any`, which means it can hold any type
|
|
2176
2251
|
* of value. In this context, the function `_isPredicate` is checking if `p` is a function that
|
|
2177
|
-
* satisfies the type `NodePredicate<
|
|
2252
|
+
* satisfies the type `NodePredicate<BinaryTreeNode<K, V>>`.
|
|
2178
2253
|
* @returns The function is checking if the input `p` is a function and returning a boolean value
|
|
2179
2254
|
* based on that check. If `p` is a function, it will return `true`, indicating that `p` is a
|
|
2180
2255
|
* predicate function for a binary tree node. If `p` is not a function, it will return `false`.
|
|
2181
2256
|
*/
|
|
2182
|
-
protected _isPredicate(p: any): p is NodePredicate<
|
|
2257
|
+
protected _isPredicate(p: any): p is NodePredicate<BinaryTreeNode<K, V>> {
|
|
2183
2258
|
return typeof p === 'function';
|
|
2184
2259
|
}
|
|
2185
2260
|
|
|
@@ -2189,30 +2264,22 @@ export class BinaryTree<
|
|
|
2189
2264
|
*
|
|
2190
2265
|
* The function `_extractKey` in TypeScript returns the key from a given input, which can be a node,
|
|
2191
2266
|
* entry, raw data, or null/undefined.
|
|
2192
|
-
* @param {BTNRep<K, V,
|
|
2193
|
-
* TypeScript method that takes in a parameter `
|
|
2194
|
-
* where `BTNRep` is a generic type with keys `K`, `V`, and `
|
|
2195
|
-
* @returns The `_extractKey` method returns the key value extracted from the `
|
|
2267
|
+
* @param {BTNRep<K, V, BinaryTreeNode<K, V>>} keyNodeOrEntry - The `_extractKey` method you provided is a
|
|
2268
|
+
* TypeScript method that takes in a parameter `keyNodeOrEntry` of type `BTNRep<K, V, BinaryTreeNode<K, V>>`,
|
|
2269
|
+
* where `BTNRep` is a generic type with keys `K`, `V`, and `BinaryTreeNode<K, V>`, and `
|
|
2270
|
+
* @returns The `_extractKey` method returns the key value extracted from the `keyNodeOrEntry`
|
|
2196
2271
|
* parameter. The return value can be a key value of type `K`, `null`, or `undefined`, depending on
|
|
2197
2272
|
* the conditions checked in the method.
|
|
2198
2273
|
*/
|
|
2199
|
-
protected _extractKey(
|
|
2200
|
-
if (
|
|
2201
|
-
if (
|
|
2202
|
-
if (
|
|
2203
|
-
if (this.isNode(
|
|
2204
|
-
|
|
2205
|
-
if (this.isEntry(
|
|
2206
|
-
|
|
2207
|
-
if (this.isRaw(keyNodeEntryOrRaw)) {
|
|
2208
|
-
if (this._toEntryFn) {
|
|
2209
|
-
const [key] = this._toEntryFn(keyNodeEntryOrRaw);
|
|
2210
|
-
return key;
|
|
2211
|
-
}
|
|
2212
|
-
return;
|
|
2213
|
-
}
|
|
2274
|
+
protected _extractKey(keyNodeOrEntry: BTNRep<K, V, BinaryTreeNode<K, V>>): K | null | undefined {
|
|
2275
|
+
if (keyNodeOrEntry === null) return null;
|
|
2276
|
+
if (keyNodeOrEntry === undefined) return;
|
|
2277
|
+
if (keyNodeOrEntry === this._NIL) return;
|
|
2278
|
+
if (this.isNode(keyNodeOrEntry)) return keyNodeOrEntry.key;
|
|
2279
|
+
|
|
2280
|
+
if (this.isEntry(keyNodeOrEntry)) return keyNodeOrEntry[0];
|
|
2214
2281
|
|
|
2215
|
-
return
|
|
2282
|
+
return keyNodeOrEntry;
|
|
2216
2283
|
}
|
|
2217
2284
|
|
|
2218
2285
|
/**
|