undirected-graph-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
|
@@ -5,9 +5,7 @@
|
|
|
5
5
|
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
9
|
-
BSTNested,
|
|
10
|
-
BSTNodeNested,
|
|
8
|
+
import type {
|
|
11
9
|
BSTNOptKeyOrNode,
|
|
12
10
|
BSTOptions,
|
|
13
11
|
BTNRep,
|
|
@@ -28,61 +26,44 @@ import { Queue } from '../queue';
|
|
|
28
26
|
import { isComparable } from '../../utils';
|
|
29
27
|
import { Range } from '../../common';
|
|
30
28
|
|
|
31
|
-
export class BSTNode<K = any, V = any
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
export class BSTNode<K = any, V = any> extends BinaryTreeNode<K, V> {
|
|
30
|
+
/**
|
|
31
|
+
* This TypeScript constructor function initializes an instance with a key and an optional value.
|
|
32
|
+
* @param {K} key - The `key` parameter is typically used to uniquely identify an object or element
|
|
33
|
+
* within a data structure. It serves as a reference or identifier for accessing or manipulating the
|
|
34
|
+
* associated value.
|
|
35
|
+
* @param {V} [value] - The `value` parameter in the constructor is optional, meaning it does not
|
|
36
|
+
* have to be provided when creating an instance of the class. If a value is not provided, it will
|
|
37
|
+
* default to `undefined`.
|
|
38
|
+
*/
|
|
38
39
|
constructor(key: K, value?: V) {
|
|
39
40
|
super(key, value);
|
|
40
|
-
this.parent = undefined;
|
|
41
|
-
this._left = undefined;
|
|
42
|
-
this._right = undefined;
|
|
43
41
|
}
|
|
44
42
|
|
|
45
|
-
override
|
|
43
|
+
override parent?: BSTNode<K, V> = undefined;
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
*/
|
|
51
|
-
override get left(): OptNodeOrNull<NODE> {
|
|
45
|
+
override _left?: OptNodeOrNull<BSTNode<K, V>> = undefined;
|
|
46
|
+
|
|
47
|
+
override get left(): OptNodeOrNull<BSTNode<K, V>> {
|
|
52
48
|
return this._left;
|
|
53
49
|
}
|
|
54
50
|
|
|
55
|
-
|
|
56
|
-
* The function sets the left child of a node and updates the parent reference of the child.
|
|
57
|
-
* @param {OptNode<NODE>} v - The parameter `v` is of type `OptNode<NODE>`. It can either be an
|
|
58
|
-
* instance of the `NODE` class or `undefined`.
|
|
59
|
-
*/
|
|
60
|
-
override set left(v: OptNodeOrNull<NODE>) {
|
|
51
|
+
override set left(v: OptNodeOrNull<BSTNode<K, V>>) {
|
|
61
52
|
if (v) {
|
|
62
|
-
v.parent = this
|
|
53
|
+
v.parent = this;
|
|
63
54
|
}
|
|
64
55
|
this._left = v;
|
|
65
56
|
}
|
|
66
57
|
|
|
67
|
-
override _right?: OptNodeOrNull<
|
|
58
|
+
override _right?: OptNodeOrNull<BSTNode<K, V>> = undefined;
|
|
68
59
|
|
|
69
|
-
|
|
70
|
-
* The function returns the right node of a binary tree or undefined if there is no right node.
|
|
71
|
-
* @returns The method is returning the value of the `_right` property, which is of type `NODE` or
|
|
72
|
-
* `undefined`.
|
|
73
|
-
*/
|
|
74
|
-
override get right(): OptNodeOrNull<NODE> {
|
|
60
|
+
override get right(): OptNodeOrNull<BSTNode<K, V>> {
|
|
75
61
|
return this._right;
|
|
76
62
|
}
|
|
77
63
|
|
|
78
|
-
|
|
79
|
-
* The function sets the right child of a node and updates the parent reference of the child.
|
|
80
|
-
* @param {OptNode<NODE>} v - The parameter `v` is of type `OptNode<NODE>`. It can either be a
|
|
81
|
-
* `NODE` object or `undefined`.
|
|
82
|
-
*/
|
|
83
|
-
override set right(v: OptNodeOrNull<NODE>) {
|
|
64
|
+
override set right(v: OptNodeOrNull<BSTNode<K, V>>) {
|
|
84
65
|
if (v) {
|
|
85
|
-
v.parent = this
|
|
66
|
+
v.parent = this;
|
|
86
67
|
}
|
|
87
68
|
this._right = v;
|
|
88
69
|
}
|
|
@@ -153,37 +134,20 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
|
|
|
153
134
|
* console.log(findLCA(5, 35)); // 15
|
|
154
135
|
* console.log(findLCA(20, 30)); // 25
|
|
155
136
|
*/
|
|
156
|
-
export class BST<
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
R = object,
|
|
160
|
-
MK = any,
|
|
161
|
-
MV = any,
|
|
162
|
-
MR = object,
|
|
163
|
-
NODE extends BSTNode<K, V, NODE> = BSTNode<K, V, BSTNodeNested<K, V>>,
|
|
164
|
-
TREE extends BST<K, V, R, MK, MV, MR, NODE, TREE> = BST<
|
|
165
|
-
K,
|
|
166
|
-
V,
|
|
167
|
-
R,
|
|
168
|
-
MK,
|
|
169
|
-
MV,
|
|
170
|
-
MR,
|
|
171
|
-
NODE,
|
|
172
|
-
BSTNested<K, V, R, MK, MV, MR, NODE>
|
|
173
|
-
>
|
|
174
|
-
>
|
|
175
|
-
extends BinaryTree<K, V, R, MK, MV, MR, NODE, TREE>
|
|
176
|
-
implements IBinaryTree<K, V, R, MK, MV, MR, NODE, TREE>
|
|
137
|
+
export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
|
|
138
|
+
extends BinaryTree<K, V, R, MK, MV, MR>
|
|
139
|
+
implements IBinaryTree<K, V, R, MK, MV, MR>
|
|
177
140
|
{
|
|
178
141
|
/**
|
|
179
|
-
* This
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
142
|
+
* This TypeScript constructor initializes a binary search tree with optional options and adds
|
|
143
|
+
* elements if provided.
|
|
144
|
+
* @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the constructor is an
|
|
145
|
+
* iterable that can contain elements of type `BTNRep<K, V, BSTNode<K, V>>` or `R`. It is used to
|
|
146
|
+
* initialize the binary search tree with keys, nodes, entries, or raw data.
|
|
147
|
+
* @param [options] - The `options` parameter is an optional object that can contain the following
|
|
148
|
+
* properties:
|
|
185
149
|
*/
|
|
186
|
-
constructor(keysNodesEntriesOrRaws: Iterable<
|
|
150
|
+
constructor(keysNodesEntriesOrRaws: Iterable<BTNRep<K, V, BSTNode<K, V>> | R> = [], options?: BSTOptions<K, V, R>) {
|
|
187
151
|
super([], options);
|
|
188
152
|
|
|
189
153
|
if (options) {
|
|
@@ -195,73 +159,82 @@ export class BST<
|
|
|
195
159
|
if (keysNodesEntriesOrRaws) this.addMany(keysNodesEntriesOrRaws);
|
|
196
160
|
}
|
|
197
161
|
|
|
198
|
-
protected override _root?:
|
|
162
|
+
protected override _root?: BSTNode<K, V> = undefined;
|
|
199
163
|
|
|
200
|
-
|
|
201
|
-
* The function returns the root node of a tree structure.
|
|
202
|
-
* @returns The `_root` property of the object, which is of type `NODE` or `undefined`.
|
|
203
|
-
*/
|
|
204
|
-
override get root(): OptNode<NODE> {
|
|
164
|
+
override get root(): OptNode<BSTNode<K, V>> {
|
|
205
165
|
return this._root;
|
|
206
166
|
}
|
|
207
167
|
|
|
208
168
|
protected _isReverse: boolean = false;
|
|
209
169
|
|
|
210
|
-
/**
|
|
211
|
-
* The above function is a getter method in TypeScript that returns the value of the private property
|
|
212
|
-
* `_isReverse`.
|
|
213
|
-
* @returns The `isReverse` property of the object, which is a boolean value.
|
|
214
|
-
*/
|
|
215
170
|
get isReverse(): boolean {
|
|
216
171
|
return this._isReverse;
|
|
217
172
|
}
|
|
218
173
|
|
|
174
|
+
protected _comparator: Comparator<K> = (a: K, b: K): number => {
|
|
175
|
+
if (isComparable(a) && isComparable(b)) {
|
|
176
|
+
if (a > b) return 1;
|
|
177
|
+
if (a < b) return -1;
|
|
178
|
+
return 0;
|
|
179
|
+
}
|
|
180
|
+
if (this._specifyComparable) {
|
|
181
|
+
if (this._specifyComparable(a) > this._specifyComparable(b)) return 1;
|
|
182
|
+
if (this._specifyComparable(a) < this._specifyComparable(b)) return -1;
|
|
183
|
+
return 0;
|
|
184
|
+
}
|
|
185
|
+
if (typeof a === 'object' || typeof b === 'object') {
|
|
186
|
+
throw TypeError(
|
|
187
|
+
`When comparing object types, a custom specifyComparable must be defined in the constructor's options parameter.`
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return 0;
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
get comparator() {
|
|
195
|
+
return this._comparator;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
protected _specifyComparable?: (key: K) => Comparable;
|
|
199
|
+
|
|
200
|
+
get specifyComparable() {
|
|
201
|
+
return this._specifyComparable;
|
|
202
|
+
}
|
|
203
|
+
|
|
219
204
|
/**
|
|
205
|
+
* Time Complexity: O(1)
|
|
206
|
+
* Space Complexity: O(1)
|
|
207
|
+
*
|
|
220
208
|
* The function creates a new BSTNode with the given key and value and returns it.
|
|
221
209
|
* @param {K} key - The key parameter is of type K, which represents the type of the key for the node
|
|
222
210
|
* being created.
|
|
223
211
|
* @param {V} [value] - The "value" parameter is an optional parameter of type V. It represents the
|
|
224
212
|
* value associated with the key in the node being created.
|
|
225
|
-
* @returns The method is returning a new instance of the BSTNode class, casted as the
|
|
213
|
+
* @returns The method is returning a new instance of the BSTNode class, casted as the BSTNode<K, V> type.
|
|
226
214
|
*/
|
|
227
|
-
override createNode(key: K, value?: V):
|
|
228
|
-
return new BSTNode<K, V
|
|
215
|
+
override createNode(key: K, value?: V): BSTNode<K, V> {
|
|
216
|
+
return new BSTNode<K, V>(key, this._isMapMode ? undefined : value);
|
|
229
217
|
}
|
|
230
218
|
|
|
231
219
|
/**
|
|
220
|
+
* Time Complexity: O(1)
|
|
221
|
+
* Space Complexity: O(1)
|
|
222
|
+
*
|
|
232
223
|
* The function creates a new binary search tree with the specified options.
|
|
233
224
|
* @param [options] - The `options` parameter is an optional object that allows you to customize the
|
|
234
225
|
* behavior of the `createTree` method. It accepts a partial `BSTOptions` object, which has the
|
|
235
226
|
* following properties:
|
|
236
227
|
* @returns a new instance of the BST class with the provided options.
|
|
237
228
|
*/
|
|
238
|
-
override createTree(options?: BSTOptions<K, V, R>)
|
|
239
|
-
return new BST<K, V, R, MK, MV, MR
|
|
229
|
+
override createTree(options?: BSTOptions<K, V, R>) {
|
|
230
|
+
return new BST<K, V, R, MK, MV, MR>([], {
|
|
240
231
|
iterationType: this.iterationType,
|
|
241
232
|
isMapMode: this._isMapMode,
|
|
242
233
|
specifyComparable: this._specifyComparable,
|
|
243
234
|
toEntryFn: this._toEntryFn,
|
|
244
235
|
isReverse: this._isReverse,
|
|
245
236
|
...options
|
|
246
|
-
})
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* The function overrides a method and converts a key, value pair or entry or raw element to a node.
|
|
251
|
-
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - A variable that can be of
|
|
252
|
-
* type R or BTNRep<K, V, NODE>. It represents either a key, a node, an entry, or a raw
|
|
253
|
-
* element.
|
|
254
|
-
* @param {V} [value] - The `value` parameter is an optional value of type `V`. It represents the
|
|
255
|
-
* value associated with a key in a key-value pair.
|
|
256
|
-
* @returns either a NODE object or undefined.
|
|
257
|
-
*/
|
|
258
|
-
protected override _keyValueNodeEntryRawToNodeAndValue(
|
|
259
|
-
keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
|
|
260
|
-
value?: V
|
|
261
|
-
): [OptNode<NODE>, V | undefined] {
|
|
262
|
-
const [node, entryValue] = super._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
|
|
263
|
-
if (node === null) return [undefined, undefined];
|
|
264
|
-
return [node, value ?? entryValue];
|
|
237
|
+
});
|
|
265
238
|
}
|
|
266
239
|
|
|
267
240
|
/**
|
|
@@ -270,8 +243,8 @@ export class BST<
|
|
|
270
243
|
*
|
|
271
244
|
* The function ensures the existence of a node in a data structure and returns it, or undefined if
|
|
272
245
|
* it doesn't exist.
|
|
273
|
-
* @param {BTNRep<K, V,
|
|
274
|
-
* `
|
|
246
|
+
* @param {BTNRep<K, V, BSTNode<K, V>>} keyNodeOrEntry - The parameter
|
|
247
|
+
* `keyNodeOrEntry` can accept a value of type `R`, which represents the key, node,
|
|
275
248
|
* entry, or raw element that needs to be ensured in the tree.
|
|
276
249
|
* @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional
|
|
277
250
|
* parameter that specifies the type of iteration to be used when ensuring a node. It has a default
|
|
@@ -280,48 +253,54 @@ export class BST<
|
|
|
280
253
|
* not be ensured.
|
|
281
254
|
*/
|
|
282
255
|
override ensureNode(
|
|
283
|
-
|
|
256
|
+
keyNodeOrEntry: BTNRep<K, V, BSTNode<K, V>>,
|
|
284
257
|
iterationType: IterationType = this.iterationType
|
|
285
|
-
): OptNode<
|
|
286
|
-
return super.ensureNode(
|
|
258
|
+
): OptNode<BSTNode<K, V>> {
|
|
259
|
+
return super.ensureNode(keyNodeOrEntry, iterationType) ?? undefined;
|
|
287
260
|
}
|
|
288
261
|
|
|
289
262
|
/**
|
|
263
|
+
* Time Complexity: O(1)
|
|
264
|
+
* Space Complexity: O(1)
|
|
265
|
+
*
|
|
290
266
|
* The function checks if the input is an instance of the BSTNode class.
|
|
291
|
-
* @param {BTNRep<K, V,
|
|
292
|
-
* `
|
|
293
|
-
* @returns a boolean value indicating whether the input parameter `
|
|
267
|
+
* @param {BTNRep<K, V, BSTNode<K, V>>} keyNodeOrEntry - The parameter
|
|
268
|
+
* `keyNodeOrEntry` can be of type `R` or `BTNRep<K, V, BSTNode<K, V>>`.
|
|
269
|
+
* @returns a boolean value indicating whether the input parameter `keyNodeOrEntry` is
|
|
294
270
|
* an instance of the `BSTNode` class.
|
|
295
271
|
*/
|
|
296
|
-
override isNode(
|
|
297
|
-
return
|
|
272
|
+
override isNode(keyNodeOrEntry: BTNRep<K, V, BSTNode<K, V>>): keyNodeOrEntry is BSTNode<K, V> {
|
|
273
|
+
return keyNodeOrEntry instanceof BSTNode;
|
|
298
274
|
}
|
|
299
275
|
|
|
300
276
|
/**
|
|
301
|
-
*
|
|
277
|
+
* Time Complexity: O(1)
|
|
278
|
+
* Space Complexity: O(1)
|
|
279
|
+
*
|
|
280
|
+
* The function "override isValidKey" checks if a key is comparable based on a given comparator.
|
|
302
281
|
* @param {any} key - The `key` parameter is a value that will be checked to determine if it is of
|
|
303
282
|
* type `K`.
|
|
304
|
-
* @returns The `override
|
|
283
|
+
* @returns The `override isValidKey(key: any): key is K` function is returning a boolean value based on
|
|
305
284
|
* the result of the `isComparable` function with the condition `this._compare !==
|
|
306
285
|
* this._DEFAULT_COMPARATOR`.
|
|
307
286
|
*/
|
|
308
|
-
override
|
|
287
|
+
override isValidKey(key: any): key is K {
|
|
309
288
|
return isComparable(key, this._specifyComparable !== undefined);
|
|
310
289
|
}
|
|
311
290
|
|
|
312
291
|
/**
|
|
313
292
|
* Time Complexity: O(log n)
|
|
314
|
-
* Space Complexity: O(
|
|
293
|
+
* Space Complexity: O(log n)
|
|
315
294
|
*
|
|
316
295
|
* The `add` function in TypeScript adds a new node to a binary search tree based on the key value.
|
|
317
|
-
* @param {BTNRep<K, V,
|
|
318
|
-
* `
|
|
296
|
+
* @param {BTNRep<K, V, BSTNode<K, V>>} keyNodeOrEntry - The parameter
|
|
297
|
+
* `keyNodeOrEntry` can accept a value of type `R` or `BTNRep<K, V, BSTNode<K, V>>`.
|
|
319
298
|
* @param {V} [value] - The `value` parameter is an optional value that can be associated with the
|
|
320
299
|
* key in the binary search tree. If provided, it will be stored in the node along with the key.
|
|
321
300
|
* @returns a boolean value.
|
|
322
301
|
*/
|
|
323
|
-
override add(
|
|
324
|
-
const [newNode, newValue] = this.
|
|
302
|
+
override add(keyNodeOrEntry: BTNRep<K, V, BSTNode<K, V>>, value?: V): boolean {
|
|
303
|
+
const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
|
|
325
304
|
if (newNode === undefined) return false;
|
|
326
305
|
|
|
327
306
|
if (this._root === undefined) {
|
|
@@ -381,7 +360,7 @@ export class BST<
|
|
|
381
360
|
* successfully inserted into the data structure.
|
|
382
361
|
*/
|
|
383
362
|
override addMany(
|
|
384
|
-
keysNodesEntriesOrRaws: Iterable<R | BTNRep<K, V,
|
|
363
|
+
keysNodesEntriesOrRaws: Iterable<R | BTNRep<K, V, BSTNode<K, V>>>,
|
|
385
364
|
values?: Iterable<V | undefined>,
|
|
386
365
|
isBalanceAdd = true,
|
|
387
366
|
iterationType: IterationType = this.iterationType
|
|
@@ -395,15 +374,16 @@ export class BST<
|
|
|
395
374
|
}
|
|
396
375
|
|
|
397
376
|
if (!isBalanceAdd) {
|
|
398
|
-
for (
|
|
377
|
+
for (let kve of keysNodesEntriesOrRaws) {
|
|
399
378
|
const value = valuesIterator?.next().value;
|
|
379
|
+
if (this.isRaw(kve)) kve = this._toEntryFn!(kve);
|
|
400
380
|
inserted.push(this.add(kve, value));
|
|
401
381
|
}
|
|
402
382
|
return inserted;
|
|
403
383
|
}
|
|
404
384
|
|
|
405
385
|
const realBTNExemplars: {
|
|
406
|
-
key: R | BTNRep<K, V,
|
|
386
|
+
key: R | BTNRep<K, V, BSTNode<K, V>>;
|
|
407
387
|
value: V | undefined;
|
|
408
388
|
orgIndex: number;
|
|
409
389
|
}[] = [];
|
|
@@ -414,23 +394,21 @@ export class BST<
|
|
|
414
394
|
i++;
|
|
415
395
|
}
|
|
416
396
|
|
|
417
|
-
let sorted: { key: R | BTNRep<K, V,
|
|
397
|
+
let sorted: { key: R | BTNRep<K, V, BSTNode<K, V>>; value: V | undefined; orgIndex: number }[] = [];
|
|
418
398
|
|
|
419
399
|
sorted = realBTNExemplars.sort(({ key: a }, { key: b }) => {
|
|
420
400
|
let keyA: K | undefined | null, keyB: K | undefined | null;
|
|
421
|
-
if (this.
|
|
401
|
+
if (this.isRaw(a)) keyA = this._toEntryFn!(a)[0];
|
|
402
|
+
else if (this.isEntry(a)) keyA = a[0];
|
|
422
403
|
else if (this.isRealNode(a)) keyA = a.key;
|
|
423
|
-
else
|
|
424
|
-
keyA = this._toEntryFn(a as R)[0];
|
|
425
|
-
} else {
|
|
404
|
+
else {
|
|
426
405
|
keyA = a as K;
|
|
427
406
|
}
|
|
428
407
|
|
|
429
|
-
if (this.
|
|
408
|
+
if (this.isRaw(b)) keyB = this._toEntryFn!(b)[0];
|
|
409
|
+
else if (this.isEntry(b)) keyB = b[0];
|
|
430
410
|
else if (this.isRealNode(b)) keyB = b.key;
|
|
431
|
-
else
|
|
432
|
-
keyB = this._toEntryFn(b as R)[0];
|
|
433
|
-
} else {
|
|
411
|
+
else {
|
|
434
412
|
keyB = b as K;
|
|
435
413
|
}
|
|
436
414
|
|
|
@@ -440,11 +418,17 @@ export class BST<
|
|
|
440
418
|
return 0;
|
|
441
419
|
});
|
|
442
420
|
|
|
443
|
-
const _dfs = (arr: { key: R | BTNRep<K, V,
|
|
421
|
+
const _dfs = (arr: { key: R | BTNRep<K, V, BSTNode<K, V>>; value: V | undefined; orgIndex: number }[]) => {
|
|
444
422
|
if (arr.length === 0) return;
|
|
445
423
|
|
|
446
424
|
const mid = Math.floor((arr.length - 1) / 2);
|
|
447
|
-
|
|
425
|
+
let { key, value } = arr[mid];
|
|
426
|
+
const { orgIndex } = arr[mid];
|
|
427
|
+
if (this.isRaw(key)) {
|
|
428
|
+
const entry = this._toEntryFn!(key);
|
|
429
|
+
key = entry[0];
|
|
430
|
+
value = entry[1] ?? value;
|
|
431
|
+
}
|
|
448
432
|
inserted[orgIndex] = this.add(key, value);
|
|
449
433
|
_dfs(arr.slice(0, mid));
|
|
450
434
|
_dfs(arr.slice(mid + 1));
|
|
@@ -459,7 +443,13 @@ export class BST<
|
|
|
459
443
|
const [l, r] = popped;
|
|
460
444
|
if (l <= r) {
|
|
461
445
|
const m = l + Math.floor((r - l) / 2);
|
|
462
|
-
|
|
446
|
+
let { key, value } = sorted[m];
|
|
447
|
+
const { orgIndex } = sorted[m];
|
|
448
|
+
if (this.isRaw(key)) {
|
|
449
|
+
const entry = this._toEntryFn!(key);
|
|
450
|
+
key = entry[0];
|
|
451
|
+
value = entry[1] ?? value;
|
|
452
|
+
}
|
|
463
453
|
inserted[orgIndex] = this.add(key, value);
|
|
464
454
|
stack.push([m + 1, r]);
|
|
465
455
|
stack.push([l, m - 1]);
|
|
@@ -483,17 +473,17 @@ export class BST<
|
|
|
483
473
|
*
|
|
484
474
|
* The function `search` in TypeScript overrides the search behavior in a binary tree structure based
|
|
485
475
|
* on specified criteria.
|
|
486
|
-
* @param {BTNRep<K, V,
|
|
487
|
-
* `
|
|
476
|
+
* @param {BTNRep<K, V, BSTNode<K, V>> | NodePredicate<BSTNode<K, V>>} keyNodeEntryOrPredicate - The
|
|
477
|
+
* `keyNodeEntryOrPredicate` parameter in the `override search` method can accept one of the
|
|
488
478
|
* following types:
|
|
489
479
|
* @param [onlyOne=false] - The `onlyOne` parameter is a boolean flag that determines whether the
|
|
490
480
|
* search should stop after finding the first matching node. If `onlyOne` is set to `true`, the
|
|
491
481
|
* search will return as soon as a matching node is found. If `onlyOne` is set to `false`, the
|
|
492
482
|
* @param {C} callback - The `callback` parameter in the `override search` function is a function
|
|
493
483
|
* that will be called on each node that matches the search criteria. It is of type `C`, which
|
|
494
|
-
* extends `NodeCallback<
|
|
484
|
+
* extends `NodeCallback<BSTNode<K, V>>`. The callback function should accept a node of type `BSTNode<K, V>` as its
|
|
495
485
|
* argument and
|
|
496
|
-
* @param {BTNRep<K, V,
|
|
486
|
+
* @param {BTNRep<K, V, BSTNode<K, V>>} startNode - The `startNode` parameter in the `override search`
|
|
497
487
|
* method represents the node from which the search operation will begin. It is the starting point
|
|
498
488
|
* for searching within the tree data structure. The method ensures that the `startNode` is a valid
|
|
499
489
|
* node before proceeding with the search operation. If the `
|
|
@@ -505,29 +495,29 @@ export class BST<
|
|
|
505
495
|
* structure based on the provided key, predicate, and other options. The search results are
|
|
506
496
|
* collected in an array and returned as the output of the method.
|
|
507
497
|
*/
|
|
508
|
-
override search<C extends NodeCallback<
|
|
509
|
-
|
|
498
|
+
override search<C extends NodeCallback<BSTNode<K, V>>>(
|
|
499
|
+
keyNodeEntryOrPredicate: BTNRep<K, V, BSTNode<K, V>> | NodePredicate<BSTNode<K, V>> | Range<K>,
|
|
510
500
|
onlyOne = false,
|
|
511
501
|
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
512
|
-
startNode: BTNRep<K, V,
|
|
502
|
+
startNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
|
|
513
503
|
iterationType: IterationType = this.iterationType
|
|
514
504
|
): ReturnType<C>[] {
|
|
515
|
-
if (
|
|
516
|
-
if (
|
|
505
|
+
if (keyNodeEntryOrPredicate === undefined) return [];
|
|
506
|
+
if (keyNodeEntryOrPredicate === null) return [];
|
|
517
507
|
startNode = this.ensureNode(startNode);
|
|
518
508
|
if (!startNode) return [];
|
|
519
|
-
let predicate: NodePredicate<
|
|
509
|
+
let predicate: NodePredicate<BSTNode<K, V>>;
|
|
520
510
|
|
|
521
|
-
const isRange = this.isRange(
|
|
511
|
+
const isRange = this.isRange(keyNodeEntryOrPredicate);
|
|
522
512
|
// Set predicate based on parameter type
|
|
523
513
|
if (isRange) {
|
|
524
|
-
predicate = node =>
|
|
514
|
+
predicate = node => keyNodeEntryOrPredicate.isInRange(node.key, this._comparator);
|
|
525
515
|
} else {
|
|
526
|
-
predicate = this._ensurePredicate(
|
|
516
|
+
predicate = this._ensurePredicate(keyNodeEntryOrPredicate);
|
|
527
517
|
}
|
|
528
|
-
const isToLeftByRange = (cur:
|
|
518
|
+
const isToLeftByRange = (cur: BSTNode<K, V>) => {
|
|
529
519
|
if (isRange) {
|
|
530
|
-
const range =
|
|
520
|
+
const range = keyNodeEntryOrPredicate;
|
|
531
521
|
const leftS = this.isReverse ? range.high : range.low;
|
|
532
522
|
const leftI = this.isReverse ? range.includeHigh : range.includeLow;
|
|
533
523
|
return (leftI && this._compare(cur.key, leftS) >= 0) || (!leftI && this._compare(cur.key, leftS) > 0);
|
|
@@ -535,9 +525,9 @@ export class BST<
|
|
|
535
525
|
return false;
|
|
536
526
|
};
|
|
537
527
|
|
|
538
|
-
const isToRightByRange = (cur:
|
|
528
|
+
const isToRightByRange = (cur: BSTNode<K, V>) => {
|
|
539
529
|
if (isRange) {
|
|
540
|
-
const range =
|
|
530
|
+
const range = keyNodeEntryOrPredicate;
|
|
541
531
|
const rightS = this.isReverse ? range.low : range.high;
|
|
542
532
|
const rightI = this.isReverse ? range.includeLow : range.includeLow;
|
|
543
533
|
|
|
@@ -547,7 +537,7 @@ export class BST<
|
|
|
547
537
|
};
|
|
548
538
|
const ans: ReturnType<C>[] = [];
|
|
549
539
|
if (iterationType === 'RECURSIVE') {
|
|
550
|
-
const dfs = (cur:
|
|
540
|
+
const dfs = (cur: BSTNode<K, V>) => {
|
|
551
541
|
if (predicate(cur)) {
|
|
552
542
|
ans.push(callback(cur));
|
|
553
543
|
if (onlyOne) return;
|
|
@@ -558,8 +548,8 @@ export class BST<
|
|
|
558
548
|
if (isRange) {
|
|
559
549
|
if (this.isRealNode(cur.left) && isToLeftByRange(cur)) dfs(cur.left);
|
|
560
550
|
if (this.isRealNode(cur.right) && isToRightByRange(cur)) dfs(cur.right);
|
|
561
|
-
} else if (!this._isPredicate(
|
|
562
|
-
const benchmarkKey = this._extractKey(
|
|
551
|
+
} else if (!this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
552
|
+
const benchmarkKey = this._extractKey(keyNodeEntryOrPredicate);
|
|
563
553
|
if (
|
|
564
554
|
this.isRealNode(cur.left) &&
|
|
565
555
|
benchmarkKey !== null &&
|
|
@@ -592,8 +582,8 @@ export class BST<
|
|
|
592
582
|
if (isRange) {
|
|
593
583
|
if (this.isRealNode(cur.left) && isToLeftByRange(cur)) stack.push(cur.left);
|
|
594
584
|
if (this.isRealNode(cur.right) && isToRightByRange(cur)) stack.push(cur.right);
|
|
595
|
-
} else if (!this._isPredicate(
|
|
596
|
-
const benchmarkKey = this._extractKey(
|
|
585
|
+
} else if (!this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
586
|
+
const benchmarkKey = this._extractKey(keyNodeEntryOrPredicate);
|
|
597
587
|
if (
|
|
598
588
|
this.isRealNode(cur.right) &&
|
|
599
589
|
benchmarkKey !== null &&
|
|
@@ -620,16 +610,16 @@ export class BST<
|
|
|
620
610
|
|
|
621
611
|
/**
|
|
622
612
|
* Time Complexity: O(log n)
|
|
623
|
-
* Space Complexity: O(n)
|
|
613
|
+
* Space Complexity: O(k + log n)
|
|
624
614
|
*
|
|
625
615
|
* The `rangeSearch` function searches for nodes within a specified range in a binary search tree.
|
|
626
616
|
* @param {Range<K> | [K, K]} range - The `range` parameter in the `rangeSearch` function can be
|
|
627
617
|
* either a `Range` object or an array of two elements representing the range boundaries.
|
|
628
618
|
* @param {C} callback - The `callback` parameter in the `rangeSearch` function is a callback
|
|
629
619
|
* function that is used to process each node that is found within the specified range during the
|
|
630
|
-
* search operation. It is of type `NodeCallback<
|
|
620
|
+
* search operation. It is of type `NodeCallback<BSTNode<K, V>>`, where `BSTNode<K, V>` is the type of nodes in the
|
|
631
621
|
* data structure.
|
|
632
|
-
* @param {BTNRep<K, V,
|
|
622
|
+
* @param {BTNRep<K, V, BSTNode<K, V>>} startNode - The `startNode` parameter in the `rangeSearch`
|
|
633
623
|
* function represents the node from which the search for nodes within the specified range will
|
|
634
624
|
* begin. It is the starting point for the range search operation.
|
|
635
625
|
* @param {IterationType} iterationType - The `iterationType` parameter in the `rangeSearch` function
|
|
@@ -639,10 +629,10 @@ export class BST<
|
|
|
639
629
|
* @returns The `rangeSearch` function is returning the result of calling the `search` method with
|
|
640
630
|
* the specified parameters.
|
|
641
631
|
*/
|
|
642
|
-
rangeSearch<C extends NodeCallback<
|
|
632
|
+
rangeSearch<C extends NodeCallback<BSTNode<K, V>>>(
|
|
643
633
|
range: Range<K> | [K, K],
|
|
644
634
|
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
645
|
-
startNode: BTNRep<K, V,
|
|
635
|
+
startNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
|
|
646
636
|
iterationType: IterationType = this.iterationType
|
|
647
637
|
) {
|
|
648
638
|
const searchRange: Range<K> = range instanceof Range ? range : new Range(range[0], range[1]);
|
|
@@ -651,12 +641,12 @@ export class BST<
|
|
|
651
641
|
|
|
652
642
|
/**
|
|
653
643
|
* Time Complexity: O(log n)
|
|
654
|
-
* Space Complexity: O(
|
|
644
|
+
* Space Complexity: O(log n)
|
|
655
645
|
*
|
|
656
|
-
* This function retrieves a node based on a given
|
|
657
|
-
* @param {BTNRep<K, V,
|
|
658
|
-
* parameter can be of type `BTNRep<K, V,
|
|
659
|
-
* @param {
|
|
646
|
+
* This function retrieves a node based on a given keyNodeEntryOrPredicate within a binary search tree structure.
|
|
647
|
+
* @param {BTNRep<K, V, BSTNode<K, V>> | NodePredicate<BSTNode<K, V>>} keyNodeEntryOrPredicate - The `keyNodeEntryOrPredicate`
|
|
648
|
+
* parameter can be of type `BTNRep<K, V, BSTNode<K, V>>`, `R`, or `NodePredicate<BSTNode<K, V>>`.
|
|
649
|
+
* @param {BSTNOptKeyOrNode<K, BSTNode<K, V>>} startNode - The `startNode` parameter in the `getNode` method
|
|
660
650
|
* is used to specify the starting point for searching nodes in the binary search tree. If no
|
|
661
651
|
* specific starting point is provided, the default value is set to `this._root`, which is the root
|
|
662
652
|
* node of the binary search tree.
|
|
@@ -664,17 +654,17 @@ export class BST<
|
|
|
664
654
|
* parameter that specifies the type of iteration to be used. It has a default value of
|
|
665
655
|
* `this.iterationType`, which means it will use the iteration type defined in the class instance if
|
|
666
656
|
* no value is provided when calling the method.
|
|
667
|
-
* @returns The `getNode` method is returning an optional binary search tree node (`OptNode<
|
|
668
|
-
* It is using the `getNodes` method to find the node based on the provided
|
|
657
|
+
* @returns The `getNode` method is returning an optional binary search tree node (`OptNode<BSTNode<K, V>>`).
|
|
658
|
+
* It is using the `getNodes` method to find the node based on the provided keyNodeEntryOrPredicate, beginning at
|
|
669
659
|
* the specified root node (`startNode`) and using the specified iteration type. The method then
|
|
670
660
|
* returns the first node found or `undefined` if no node is found.
|
|
671
661
|
*/
|
|
672
662
|
override getNode(
|
|
673
|
-
|
|
674
|
-
startNode:
|
|
663
|
+
keyNodeEntryOrPredicate: BTNRep<K, V, BSTNode<K, V>> | NodePredicate<BSTNode<K, V>>,
|
|
664
|
+
startNode: BSTNOptKeyOrNode<K, BSTNode<K, V>> = this._root,
|
|
675
665
|
iterationType: IterationType = this.iterationType
|
|
676
|
-
): OptNode<
|
|
677
|
-
return this.getNodes(
|
|
666
|
+
): OptNode<BSTNode<K, V>> {
|
|
667
|
+
return this.getNodes(keyNodeEntryOrPredicate, true, startNode, iterationType)[0] ?? undefined;
|
|
678
668
|
}
|
|
679
669
|
|
|
680
670
|
/**
|
|
@@ -689,7 +679,7 @@ export class BST<
|
|
|
689
679
|
* @param {DFSOrderPattern} [pattern=IN] - The "pattern" parameter in the code snippet refers to the
|
|
690
680
|
* order in which the Depth-First Search (DFS) algorithm visits the nodes in a tree or graph. It can
|
|
691
681
|
* take one of the following values:
|
|
692
|
-
* @param {BTNRep<K, V,
|
|
682
|
+
* @param {BTNRep<K, V, BSTNode<K, V>>} startNode - The `startNode` parameter is the starting
|
|
693
683
|
* point for the depth-first search traversal. It can be either a root node, a key-value pair, or a
|
|
694
684
|
* node entry. If not specified, the default value is the root of the tree.
|
|
695
685
|
* @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter specifies the
|
|
@@ -697,10 +687,10 @@ export class BST<
|
|
|
697
687
|
* following values:
|
|
698
688
|
* @returns The method is returning an array of the return type of the callback function.
|
|
699
689
|
*/
|
|
700
|
-
override dfs<C extends NodeCallback<
|
|
690
|
+
override dfs<C extends NodeCallback<BSTNode<K, V>>>(
|
|
701
691
|
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
702
692
|
pattern: DFSOrderPattern = 'IN',
|
|
703
|
-
startNode: BTNRep<K, V,
|
|
693
|
+
startNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
|
|
704
694
|
iterationType: IterationType = this.iterationType
|
|
705
695
|
): ReturnType<C>[] {
|
|
706
696
|
return super.dfs(callback, pattern, startNode, iterationType);
|
|
@@ -715,7 +705,7 @@ export class BST<
|
|
|
715
705
|
* @param {C} callback - The `callback` parameter is a function that will be called for each node
|
|
716
706
|
* visited during the breadth-first search. It should take a single argument, which is the current
|
|
717
707
|
* node being visited, and it can return a value of any type.
|
|
718
|
-
* @param {BTNRep<K, V,
|
|
708
|
+
* @param {BTNRep<K, V, BSTNode<K, V>>} startNode - The `startNode` parameter is the starting
|
|
719
709
|
* point for the breadth-first search. It can be either a root node, a key-value pair, or an entry
|
|
720
710
|
* object. If no value is provided, the default value is the root of the tree.
|
|
721
711
|
* @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type
|
|
@@ -723,9 +713,9 @@ export class BST<
|
|
|
723
713
|
* the following values:
|
|
724
714
|
* @returns an array of the return type of the callback function.
|
|
725
715
|
*/
|
|
726
|
-
override bfs<C extends NodeCallback<
|
|
716
|
+
override bfs<C extends NodeCallback<BSTNode<K, V>>>(
|
|
727
717
|
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
728
|
-
startNode: BTNRep<K, V,
|
|
718
|
+
startNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
|
|
729
719
|
iterationType: IterationType = this.iterationType
|
|
730
720
|
): ReturnType<C>[] {
|
|
731
721
|
return super.bfs(callback, startNode, iterationType, false);
|
|
@@ -738,9 +728,9 @@ export class BST<
|
|
|
738
728
|
* The function overrides the listLevels method from the superclass and returns an array of arrays
|
|
739
729
|
* containing the results of the callback function applied to each level of the tree.
|
|
740
730
|
* @param {C} callback - The `callback` parameter is a generic type `C` that extends
|
|
741
|
-
* `NodeCallback<
|
|
731
|
+
* `NodeCallback<BSTNode<K, V>>`. It represents a callback function that will be called for each node in the
|
|
742
732
|
* tree during the iteration process.
|
|
743
|
-
* @param {BTNRep<K, V,
|
|
733
|
+
* @param {BTNRep<K, V, BSTNode<K, V>>} startNode - The `startNode` parameter is the starting
|
|
744
734
|
* point for listing the levels of the binary tree. It can be either a root node of the tree, a
|
|
745
735
|
* key-value pair representing a node in the tree, or a key representing a node in the tree. If no
|
|
746
736
|
* value is provided, the root of
|
|
@@ -749,9 +739,9 @@ export class BST<
|
|
|
749
739
|
* @returns The method is returning a two-dimensional array of the return type of the callback
|
|
750
740
|
* function.
|
|
751
741
|
*/
|
|
752
|
-
override listLevels<C extends NodeCallback<
|
|
742
|
+
override listLevels<C extends NodeCallback<BSTNode<K, V>>>(
|
|
753
743
|
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
754
|
-
startNode: BTNRep<K, V,
|
|
744
|
+
startNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
|
|
755
745
|
iterationType: IterationType = this.iterationType
|
|
756
746
|
): ReturnType<C>[][] {
|
|
757
747
|
return super.listLevels(callback, startNode, iterationType, false);
|
|
@@ -769,7 +759,7 @@ export class BST<
|
|
|
769
759
|
* @param {CP} lesserOrGreater - The `lesserOrGreater` parameter is used to determine whether to
|
|
770
760
|
* traverse nodes that are lesser, greater, or both than the `targetNode`. It accepts the values -1,
|
|
771
761
|
* 0, or 1, where:
|
|
772
|
-
* @param {BTNRep<K, V,
|
|
762
|
+
* @param {BTNRep<K, V, BSTNode<K, V>>} targetNode - The `targetNode` parameter is the node in
|
|
773
763
|
* the binary tree that you want to start traversing from. It can be specified either by providing
|
|
774
764
|
* the key of the node, the node itself, or an entry containing the key and value of the node. If no
|
|
775
765
|
* `targetNode` is provided,
|
|
@@ -778,21 +768,21 @@ export class BST<
|
|
|
778
768
|
* @returns The function `lesserOrGreaterTraverse` returns an array of values of type
|
|
779
769
|
* `ReturnType<C>`, which is the return type of the callback function passed as an argument.
|
|
780
770
|
*/
|
|
781
|
-
lesserOrGreaterTraverse<C extends NodeCallback<
|
|
771
|
+
lesserOrGreaterTraverse<C extends NodeCallback<BSTNode<K, V>>>(
|
|
782
772
|
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
783
773
|
lesserOrGreater: CP = -1,
|
|
784
|
-
targetNode: BTNRep<K, V,
|
|
774
|
+
targetNode: BTNRep<K, V, BSTNode<K, V>> = this._root,
|
|
785
775
|
iterationType: IterationType = this.iterationType
|
|
786
776
|
): ReturnType<C>[] {
|
|
787
777
|
const targetNodeEnsured = this.ensureNode(targetNode);
|
|
788
|
-
const ans: ReturnType<NodeCallback<
|
|
778
|
+
const ans: ReturnType<NodeCallback<BSTNode<K, V>>>[] = [];
|
|
789
779
|
if (!this._root) return ans;
|
|
790
780
|
if (!targetNodeEnsured) return ans;
|
|
791
781
|
|
|
792
782
|
const targetKey = targetNodeEnsured.key;
|
|
793
783
|
|
|
794
784
|
if (iterationType === 'RECURSIVE') {
|
|
795
|
-
const dfs = (cur:
|
|
785
|
+
const dfs = (cur: BSTNode<K, V>) => {
|
|
796
786
|
const compared = this._compare(cur.key, targetKey);
|
|
797
787
|
if (Math.sign(compared) === lesserOrGreater) ans.push(callback(cur));
|
|
798
788
|
// TODO here can be optimized to O(log n)
|
|
@@ -803,7 +793,7 @@ export class BST<
|
|
|
803
793
|
dfs(this._root);
|
|
804
794
|
return ans;
|
|
805
795
|
} else {
|
|
806
|
-
const queue = new Queue<
|
|
796
|
+
const queue = new Queue<BSTNode<K, V>>([this._root]);
|
|
807
797
|
while (queue.size > 0) {
|
|
808
798
|
const cur = queue.shift();
|
|
809
799
|
if (this.isRealNode(cur)) {
|
|
@@ -887,7 +877,7 @@ export class BST<
|
|
|
887
877
|
let balanced = true;
|
|
888
878
|
|
|
889
879
|
if (iterationType === 'RECURSIVE') {
|
|
890
|
-
const _height = (cur: OptNodeOrNull<
|
|
880
|
+
const _height = (cur: OptNodeOrNull<BSTNode<K, V>>): number => {
|
|
891
881
|
if (!cur) return 0;
|
|
892
882
|
const leftHeight = _height(cur.left),
|
|
893
883
|
rightHeight = _height(cur.right);
|
|
@@ -896,10 +886,10 @@ export class BST<
|
|
|
896
886
|
};
|
|
897
887
|
_height(this._root);
|
|
898
888
|
} else {
|
|
899
|
-
const stack:
|
|
900
|
-
let node: OptNode<
|
|
901
|
-
last: OptNode<
|
|
902
|
-
const depths: Map<
|
|
889
|
+
const stack: BSTNode<K, V>[] = [];
|
|
890
|
+
let node: OptNode<BSTNode<K, V>> = this._root,
|
|
891
|
+
last: OptNode<BSTNode<K, V>> = undefined;
|
|
892
|
+
const depths: Map<BSTNode<K, V>, number> = new Map();
|
|
903
893
|
|
|
904
894
|
while (stack.length > 0 || node) {
|
|
905
895
|
if (node) {
|
|
@@ -925,71 +915,103 @@ export class BST<
|
|
|
925
915
|
return balanced;
|
|
926
916
|
}
|
|
927
917
|
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
918
|
+
/**
|
|
919
|
+
* Time complexity: O(n)
|
|
920
|
+
* Space complexity: O(n)
|
|
921
|
+
*
|
|
922
|
+
* The `map` function in TypeScript overrides the default map behavior for a binary search tree by
|
|
923
|
+
* applying a callback function to each entry and creating a new tree with the results.
|
|
924
|
+
* @param callback - A function that will be called for each entry in the BST. It takes four
|
|
925
|
+
* arguments: the key, the value (which can be undefined), the index of the entry, and a reference to
|
|
926
|
+
* the BST itself.
|
|
927
|
+
* @param [options] - The `options` parameter in the `override map` method is of type `BSTOptions<MK,
|
|
928
|
+
* MV, MR>`. It is an optional parameter that allows you to specify additional options for the Binary
|
|
929
|
+
* Search Tree (BST) being created in the `map` method. These options could include configuration
|
|
930
|
+
* @param {any} [thisArg] - The `thisArg` parameter in the `override map` method is used to specify
|
|
931
|
+
* the value of `this` that should be used when executing the `callback` function. It allows you to
|
|
932
|
+
* set the context or scope in which the callback function will be called. This can be useful when
|
|
933
|
+
* you want
|
|
934
|
+
* @returns The `map` method is returning a new Binary Search Tree (`BST`) instance with the entries
|
|
935
|
+
* transformed by the provided callback function.
|
|
936
|
+
*/
|
|
937
|
+
override map(
|
|
938
|
+
callback: EntryCallback<K, V | undefined, [MK, MV]>,
|
|
939
|
+
options?: BSTOptions<MK, MV, MR>,
|
|
940
|
+
thisArg?: any
|
|
941
|
+
): BST<MK, MV, MR> {
|
|
942
|
+
const newTree = new BST<MK, MV, MR>([], options);
|
|
943
|
+
let index = 0;
|
|
944
|
+
for (const [key, value] of this) {
|
|
945
|
+
newTree.add(callback.call(thisArg, key, value, index++, this));
|
|
943
946
|
}
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
};
|
|
947
|
+
return newTree;
|
|
948
|
+
}
|
|
947
949
|
|
|
948
950
|
/**
|
|
949
|
-
*
|
|
950
|
-
*
|
|
951
|
+
* Time complexity: O(n)
|
|
952
|
+
* Space complexity: O(n)
|
|
953
|
+
*
|
|
954
|
+
* The function `clone` overrides the default cloning behavior to create a deep copy of a tree
|
|
955
|
+
* structure.
|
|
956
|
+
* @returns The `cloned` object is being returned.
|
|
951
957
|
*/
|
|
952
|
-
|
|
953
|
-
|
|
958
|
+
override clone() {
|
|
959
|
+
const cloned = this.createTree();
|
|
960
|
+
this._clone(cloned);
|
|
961
|
+
return cloned;
|
|
954
962
|
}
|
|
955
963
|
|
|
956
|
-
protected _specifyComparable?: (key: K) => Comparable;
|
|
957
|
-
|
|
958
964
|
/**
|
|
959
|
-
*
|
|
960
|
-
*
|
|
961
|
-
*
|
|
965
|
+
* Time Complexity: O(1)
|
|
966
|
+
* Space Complexity: O(1)
|
|
967
|
+
*
|
|
968
|
+
* The function overrides a method and converts a key, value pair or entry or raw element to a node.
|
|
969
|
+
* @param {BTNRep<K, V, BSTNode<K, V>>} keyNodeOrEntry - A variable that can be of
|
|
970
|
+
* type R or BTNRep<K, V, BSTNode<K, V>>. It represents either a key, a node, an entry, or a raw
|
|
971
|
+
* element.
|
|
972
|
+
* @param {V} [value] - The `value` parameter is an optional value of type `V`. It represents the
|
|
973
|
+
* value associated with a key in a key-value pair.
|
|
974
|
+
* @returns either a BSTNode<K, V> object or undefined.
|
|
962
975
|
*/
|
|
963
|
-
|
|
964
|
-
|
|
976
|
+
protected override _keyValueNodeOrEntryToNodeAndValue(
|
|
977
|
+
keyNodeOrEntry: BTNRep<K, V, BSTNode<K, V>>,
|
|
978
|
+
value?: V
|
|
979
|
+
): [OptNode<BSTNode<K, V>>, V | undefined] {
|
|
980
|
+
const [node, entryValue] = super._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
|
|
981
|
+
if (node === null) return [undefined, undefined];
|
|
982
|
+
return [node, value ?? entryValue];
|
|
965
983
|
}
|
|
966
984
|
|
|
967
985
|
/**
|
|
986
|
+
* Time Complexity: O(1)
|
|
987
|
+
* Space Complexity: O(1)
|
|
988
|
+
*
|
|
968
989
|
* The function sets the root of a tree-like structure and updates the parent property of the new
|
|
969
990
|
* root.
|
|
970
|
-
* @param {OptNode<
|
|
991
|
+
* @param {OptNode<BSTNode<K, V>>} v - v is a parameter of type BSTNode<K, V> or undefined.
|
|
971
992
|
*/
|
|
972
|
-
protected override _setRoot(v: OptNode<
|
|
993
|
+
protected override _setRoot(v: OptNode<BSTNode<K, V>>) {
|
|
973
994
|
if (v) {
|
|
974
995
|
v.parent = undefined;
|
|
975
996
|
}
|
|
976
997
|
this._root = v;
|
|
977
998
|
}
|
|
978
999
|
|
|
1000
|
+
/**
|
|
1001
|
+
* Time Complexity: O(1)
|
|
1002
|
+
* Space Complexity: O(1)
|
|
1003
|
+
*
|
|
1004
|
+
* The _compare function compares two values using a specified comparator function and optionally
|
|
1005
|
+
* reverses the result.
|
|
1006
|
+
* @param {K} a - The parameter `a` is of type `K`, which is used as an input for comparison in the
|
|
1007
|
+
* `_compare` method.
|
|
1008
|
+
* @param {K} b - The parameter `b` in the `_compare` function is of type `K`.
|
|
1009
|
+
* @returns The `_compare` method is returning the result of the ternary expression. If `_isReverse`
|
|
1010
|
+
* is true, it returns the negation of the result of calling the `_comparator` function with
|
|
1011
|
+
* arguments `a` and `b`. If `_isReverse` is false, it returns the result of calling the
|
|
1012
|
+
* `_comparator` function with arguments `a` and `b`.
|
|
1013
|
+
*/
|
|
979
1014
|
protected _compare(a: K, b: K) {
|
|
980
1015
|
return this._isReverse ? -this._comparator(a, b) : this._comparator(a, b);
|
|
981
1016
|
}
|
|
982
|
-
|
|
983
|
-
override map(
|
|
984
|
-
callback: EntryCallback<K, V | undefined, [MK, MV]>,
|
|
985
|
-
options?: BSTOptions<MK, MV, MR>,
|
|
986
|
-
thisArg?: any
|
|
987
|
-
): BST<MK, MV, MR> {
|
|
988
|
-
const newTree = new BST<MK, MV, MR>([], options);
|
|
989
|
-
let index = 0;
|
|
990
|
-
for (const [key, value] of this) {
|
|
991
|
-
newTree.add(callback.call(thisArg, key, value, index++, this));
|
|
992
|
-
}
|
|
993
|
-
return newTree;
|
|
994
|
-
}
|
|
995
1017
|
}
|