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