graph-typed 1.51.7 → 1.51.9
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-multi-map.d.ts +103 -74
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +116 -93
- package/dist/data-structures/binary-tree/avl-tree.d.ts +82 -62
- package/dist/data-structures/binary-tree/avl-tree.js +90 -71
- package/dist/data-structures/binary-tree/binary-tree.d.ts +318 -233
- package/dist/data-structures/binary-tree/binary-tree.js +492 -392
- package/dist/data-structures/binary-tree/bst.d.ts +204 -251
- package/dist/data-structures/binary-tree/bst.js +256 -358
- package/dist/data-structures/binary-tree/rb-tree.d.ts +74 -85
- package/dist/data-structures/binary-tree/rb-tree.js +111 -119
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +92 -76
- package/dist/data-structures/binary-tree/tree-multi-map.js +105 -93
- package/dist/data-structures/graph/abstract-graph.d.ts +10 -15
- package/dist/data-structures/graph/abstract-graph.js +10 -15
- package/dist/data-structures/hash/hash-map.d.ts +31 -38
- package/dist/data-structures/hash/hash-map.js +40 -55
- package/dist/data-structures/heap/heap.d.ts +1 -3
- package/dist/data-structures/queue/deque.d.ts +2 -3
- package/dist/data-structures/queue/deque.js +2 -3
- package/dist/data-structures/trie/trie.d.ts +1 -1
- package/dist/data-structures/trie/trie.js +1 -1
- package/dist/interfaces/binary-tree.d.ts +7 -7
- package/dist/types/common.d.ts +2 -3
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +4 -3
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +4 -3
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +6 -5
- package/dist/types/data-structures/binary-tree/bst.d.ts +6 -5
- package/dist/types/data-structures/binary-tree/rb-tree.d.ts +4 -3
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +4 -3
- package/dist/types/utils/utils.d.ts +10 -1
- package/dist/utils/utils.d.ts +2 -1
- package/dist/utils/utils.js +27 -1
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +142 -100
- package/src/data-structures/binary-tree/avl-tree.ts +109 -80
- package/src/data-structures/binary-tree/binary-tree.ts +556 -433
- package/src/data-structures/binary-tree/bst.ts +286 -375
- package/src/data-structures/binary-tree/rb-tree.ts +132 -125
- package/src/data-structures/binary-tree/tree-multi-map.ts +129 -102
- package/src/data-structures/graph/abstract-graph.ts +10 -10
- package/src/data-structures/hash/hash-map.ts +42 -49
- package/src/data-structures/heap/heap.ts +1 -1
- package/src/data-structures/queue/deque.ts +2 -2
- package/src/data-structures/queue/queue.ts +1 -1
- package/src/data-structures/trie/trie.ts +2 -2
- package/src/interfaces/binary-tree.ts +11 -9
- package/src/types/common.ts +2 -3
- package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +4 -3
- package/src/types/data-structures/binary-tree/avl-tree.ts +4 -3
- package/src/types/data-structures/binary-tree/binary-tree.ts +7 -6
- package/src/types/data-structures/binary-tree/bst.ts +6 -5
- package/src/types/data-structures/binary-tree/rb-tree.ts +4 -3
- package/src/types/data-structures/binary-tree/tree-multi-map.ts +4 -3
- package/src/types/utils/utils.ts +14 -1
- package/src/utils/utils.ts +20 -1
|
@@ -7,22 +7,28 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type {
|
|
9
9
|
BSTNested,
|
|
10
|
+
BSTNKeyOrNode,
|
|
10
11
|
BSTNodeNested,
|
|
11
12
|
BSTOptions,
|
|
12
13
|
BTNCallback,
|
|
13
|
-
|
|
14
|
+
BTNPureKeyOrNodeOrEntry,
|
|
15
|
+
Comparable,
|
|
16
|
+
Comparator,
|
|
17
|
+
CP,
|
|
18
|
+
DFSOrderPattern,
|
|
19
|
+
IterationType,
|
|
14
20
|
KeyOrNodeOrEntry
|
|
15
21
|
} from '../../types';
|
|
16
|
-
import {
|
|
22
|
+
import { BTNEntry } from '../../types';
|
|
17
23
|
import { BinaryTree, BinaryTreeNode } from './binary-tree';
|
|
18
24
|
import { IBinaryTree } from '../../interfaces';
|
|
19
25
|
import { Queue } from '../queue';
|
|
20
26
|
|
|
21
|
-
export class BSTNode<
|
|
22
|
-
K,
|
|
23
|
-
V,
|
|
24
|
-
NODE
|
|
25
|
-
> {
|
|
27
|
+
export class BSTNode<
|
|
28
|
+
K extends Comparable,
|
|
29
|
+
V = any,
|
|
30
|
+
NODE extends BSTNode<K, V, NODE> = BSTNodeNested<K, V>
|
|
31
|
+
> extends BinaryTreeNode<K, V, NODE> {
|
|
26
32
|
override parent?: NODE;
|
|
27
33
|
|
|
28
34
|
constructor(key: K, value?: V) {
|
|
@@ -88,35 +94,37 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
|
|
|
88
94
|
* 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.
|
|
89
95
|
*/
|
|
90
96
|
export class BST<
|
|
91
|
-
K
|
|
97
|
+
K extends Comparable,
|
|
92
98
|
V = any,
|
|
99
|
+
R = BTNEntry<K, V>,
|
|
93
100
|
NODE extends BSTNode<K, V, NODE> = BSTNode<K, V, BSTNodeNested<K, V>>,
|
|
94
|
-
TREE extends BST<K, V, NODE, TREE> = BST<K, V, NODE, BSTNested<K, V, NODE>>
|
|
101
|
+
TREE extends BST<K, V, R, NODE, TREE> = BST<K, V, R, NODE, BSTNested<K, V, R, NODE>>
|
|
95
102
|
>
|
|
96
|
-
extends BinaryTree<K, V, NODE, TREE>
|
|
97
|
-
implements IBinaryTree<K, V, NODE, TREE> {
|
|
98
|
-
/**
|
|
99
|
-
* This is the constructor function for a
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* to
|
|
103
|
-
* @param [options] -
|
|
104
|
-
*
|
|
105
|
-
*/
|
|
106
|
-
constructor(
|
|
103
|
+
extends BinaryTree<K, V, R, NODE, TREE>
|
|
104
|
+
implements IBinaryTree<K, V, R, NODE, TREE> {
|
|
105
|
+
/**
|
|
106
|
+
* This is the constructor function for a Binary Search Tree class in TypeScript.
|
|
107
|
+
* @param keysOrNodesOrEntriesOrRawElements - The `keysOrNodesOrEntriesOrRawElements` parameter is an
|
|
108
|
+
* iterable that can contain either keys, nodes, entries, or raw elements. These elements will be
|
|
109
|
+
* added to the binary search tree during the construction of the object.
|
|
110
|
+
* @param [options] - An optional object that contains additional options for the Binary Search Tree.
|
|
111
|
+
* It can include a comparator function that defines the order of the elements in the tree.
|
|
112
|
+
*/
|
|
113
|
+
constructor(
|
|
114
|
+
keysOrNodesOrEntriesOrRawElements: Iterable<R | KeyOrNodeOrEntry<K, V, NODE>> = [],
|
|
115
|
+
options?: BSTOptions<K, V, R>
|
|
116
|
+
) {
|
|
107
117
|
super([], options);
|
|
108
118
|
|
|
109
119
|
if (options) {
|
|
110
|
-
const {
|
|
111
|
-
if (
|
|
120
|
+
const { comparator } = options;
|
|
121
|
+
if (comparator) this._comparator = comparator;
|
|
112
122
|
}
|
|
113
123
|
|
|
114
|
-
this.
|
|
115
|
-
|
|
116
|
-
if (keysOrNodesOrEntries) this.addMany(keysOrNodesOrEntries);
|
|
124
|
+
if (keysOrNodesOrEntriesOrRawElements) this.addMany(keysOrNodesOrEntriesOrRawElements);
|
|
117
125
|
}
|
|
118
126
|
|
|
119
|
-
protected override _root?: NODE;
|
|
127
|
+
protected override _root?: NODE = undefined;
|
|
120
128
|
|
|
121
129
|
/**
|
|
122
130
|
* The function returns the root node of a tree structure.
|
|
@@ -126,16 +134,6 @@ export class BST<
|
|
|
126
134
|
return this._root;
|
|
127
135
|
}
|
|
128
136
|
|
|
129
|
-
protected _variant: BSTVariant = 'STANDARD';
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* The function returns the value of the _variant property.
|
|
133
|
-
* @returns The value of the `_variant` property.
|
|
134
|
-
*/
|
|
135
|
-
get variant() {
|
|
136
|
-
return this._variant;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
137
|
/**
|
|
140
138
|
* The function creates a new BSTNode with the given key and value and returns it.
|
|
141
139
|
* @param {K} key - The key parameter is of type K, which represents the type of the key for the node
|
|
@@ -151,113 +149,82 @@ export class BST<
|
|
|
151
149
|
/**
|
|
152
150
|
* The function creates a new binary search tree with the specified options.
|
|
153
151
|
* @param [options] - The `options` parameter is an optional object that allows you to customize the
|
|
154
|
-
* behavior of the `createTree` method. It
|
|
155
|
-
*
|
|
156
|
-
* @returns a new instance of the BST class
|
|
157
|
-
* options. The returned value is casted as TREE.
|
|
152
|
+
* behavior of the `createTree` method. It accepts a partial `BSTOptions` object, which has the
|
|
153
|
+
* following properties:
|
|
154
|
+
* @returns a new instance of the BST class with the provided options.
|
|
158
155
|
*/
|
|
159
|
-
override createTree(options?: Partial<BSTOptions<K>>): TREE {
|
|
160
|
-
return new BST<K, V, NODE, TREE>([], {
|
|
156
|
+
override createTree(options?: Partial<BSTOptions<K, V, R>>): TREE {
|
|
157
|
+
return new BST<K, V, R, NODE, TREE>([], {
|
|
161
158
|
iterationType: this.iterationType,
|
|
162
|
-
|
|
159
|
+
comparator: this.comparator,
|
|
163
160
|
...options
|
|
164
161
|
}) as TREE;
|
|
165
162
|
}
|
|
166
163
|
|
|
167
164
|
/**
|
|
168
|
-
* The function
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
* `
|
|
173
|
-
*
|
|
174
|
-
|
|
175
|
-
override keyValueOrEntryToNode(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>, value?: V): NODE | undefined {
|
|
176
|
-
let node: NODE | undefined;
|
|
177
|
-
if (keyOrNodeOrEntry === null || keyOrNodeOrEntry === undefined) {
|
|
178
|
-
return;
|
|
179
|
-
} else if (this.isNode(keyOrNodeOrEntry)) {
|
|
180
|
-
node = keyOrNodeOrEntry;
|
|
181
|
-
} else if (this.isEntry(keyOrNodeOrEntry)) {
|
|
182
|
-
const [key, value] = keyOrNodeOrEntry;
|
|
183
|
-
if (key === undefined || key === null) {
|
|
184
|
-
return;
|
|
185
|
-
} else {
|
|
186
|
-
node = this.createNode(key, value);
|
|
187
|
-
}
|
|
188
|
-
} else if (!this.isNode(keyOrNodeOrEntry)) {
|
|
189
|
-
node = this.createNode(keyOrNodeOrEntry, value);
|
|
190
|
-
} else {
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
return node;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* Time Complexity: O(log n)
|
|
198
|
-
* Space Complexity: O(log n)
|
|
165
|
+
* The function overrides a method and converts a key, value pair or entry or raw element to a node.
|
|
166
|
+
* @param {R | KeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - A variable that can be of
|
|
167
|
+
* type R or KeyOrNodeOrEntry<K, V, NODE>. It represents either a key, a node, an entry, or a raw
|
|
168
|
+
* element.
|
|
169
|
+
* @param {V} [value] - The `value` parameter is an optional value of type `V`. It represents the
|
|
170
|
+
* value associated with a key in a key-value pair.
|
|
171
|
+
* @returns either a NODE object or undefined.
|
|
199
172
|
*/
|
|
173
|
+
override keyValueOrEntryOrRawElementToNode(
|
|
174
|
+
keyOrNodeOrEntryOrRawElement: R | KeyOrNodeOrEntry<K, V, NODE>,
|
|
175
|
+
value?: V
|
|
176
|
+
): NODE | undefined {
|
|
177
|
+
return super.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement, value) ?? undefined;
|
|
178
|
+
}
|
|
200
179
|
|
|
201
180
|
/**
|
|
202
181
|
* Time Complexity: O(log n)
|
|
203
182
|
* Space Complexity: O(log n)
|
|
204
183
|
*
|
|
205
|
-
* The function
|
|
206
|
-
*
|
|
207
|
-
* @param {
|
|
208
|
-
* `
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
*
|
|
184
|
+
* The function ensures the existence of a node in a data structure and returns it, or undefined if
|
|
185
|
+
* it doesn't exist.
|
|
186
|
+
* @param {R | KeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The parameter
|
|
187
|
+
* `keyOrNodeOrEntryOrRawElement` can accept a value of type `R`, which represents the key, node,
|
|
188
|
+
* entry, or raw element that needs to be ensured in the tree.
|
|
189
|
+
* @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional
|
|
190
|
+
* parameter that specifies the type of iteration to be used when ensuring a node. It has a default
|
|
191
|
+
* value of `'ITERATIVE'`.
|
|
192
|
+
* @returns The method is returning either the node that was ensured or `undefined` if the node could
|
|
193
|
+
* not be ensured.
|
|
212
194
|
*/
|
|
213
195
|
override ensureNode(
|
|
214
|
-
|
|
196
|
+
keyOrNodeOrEntryOrRawElement: R | KeyOrNodeOrEntry<K, V, NODE>,
|
|
215
197
|
iterationType: IterationType = 'ITERATIVE'
|
|
216
198
|
): NODE | undefined {
|
|
217
|
-
|
|
218
|
-
if (this.isRealNode(keyOrNodeOrEntry)) {
|
|
219
|
-
return keyOrNodeOrEntry;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
if (this.isEntry(keyOrNodeOrEntry)) {
|
|
223
|
-
const key = keyOrNodeOrEntry[0];
|
|
224
|
-
if (key === null || key === undefined) return;
|
|
225
|
-
return this.getNodeByKey(key, iterationType);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const key = keyOrNodeOrEntry;
|
|
229
|
-
if (key === null || key === undefined) return;
|
|
230
|
-
return this.getNodeByKey(key, iterationType);
|
|
199
|
+
return super.ensureNode(keyOrNodeOrEntryOrRawElement, iterationType) ?? undefined;
|
|
231
200
|
}
|
|
232
201
|
|
|
233
202
|
/**
|
|
234
|
-
* The function checks if
|
|
235
|
-
* @param
|
|
236
|
-
*
|
|
203
|
+
* The function checks if the input is an instance of the BSTNode class.
|
|
204
|
+
* @param {R | KeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The parameter
|
|
205
|
+
* `keyOrNodeOrEntryOrRawElement` can be of type `R` or `KeyOrNodeOrEntry<K, V, NODE>`.
|
|
206
|
+
* @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRawElement` is
|
|
207
|
+
* an instance of the `BSTNode` class.
|
|
237
208
|
*/
|
|
238
|
-
override isNode(
|
|
239
|
-
|
|
209
|
+
override isNode(
|
|
210
|
+
keyOrNodeOrEntryOrRawElement: R | KeyOrNodeOrEntry<K, V, NODE>
|
|
211
|
+
): keyOrNodeOrEntryOrRawElement is NODE {
|
|
212
|
+
return keyOrNodeOrEntryOrRawElement instanceof BSTNode;
|
|
240
213
|
}
|
|
241
214
|
|
|
242
|
-
/**
|
|
243
|
-
* Time Complexity: O(log n)
|
|
244
|
-
* Space Complexity: O(1)
|
|
245
|
-
*/
|
|
246
|
-
|
|
247
215
|
/**
|
|
248
216
|
* Time Complexity: O(log n)
|
|
249
217
|
* Space Complexity: O(1)
|
|
250
218
|
*
|
|
251
|
-
* The `add` function adds a new node to a binary tree
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
* @param {V} [value] - The `value` parameter
|
|
255
|
-
*
|
|
256
|
-
* @returns
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
const newNode = this.keyValueOrEntryToNode(keyOrNodeOrEntry, value);
|
|
219
|
+
* The `add` function in TypeScript adds a new node to a binary search tree based on the key value.
|
|
220
|
+
* @param {R | KeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The parameter
|
|
221
|
+
* `keyOrNodeOrEntryOrRawElement` can accept a value of type `R` or `KeyOrNodeOrEntry<K, V, NODE>`.
|
|
222
|
+
* @param {V} [value] - The `value` parameter is an optional value that can be associated with the
|
|
223
|
+
* key in the binary search tree. If provided, it will be stored in the node along with the key.
|
|
224
|
+
* @returns a boolean value.
|
|
225
|
+
*/
|
|
226
|
+
override add(keyOrNodeOrEntryOrRawElement: R | KeyOrNodeOrEntry<K, V, NODE>, value?: V): boolean {
|
|
227
|
+
const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement, value);
|
|
261
228
|
if (newNode === undefined) return false;
|
|
262
229
|
|
|
263
230
|
if (this.root === undefined) {
|
|
@@ -268,19 +235,10 @@ export class BST<
|
|
|
268
235
|
|
|
269
236
|
let current = this.root;
|
|
270
237
|
while (current !== undefined) {
|
|
271
|
-
if (this.
|
|
272
|
-
// if (current !== newNode) {
|
|
273
|
-
// The key value is the same but the reference is different, update the value of the existing node
|
|
238
|
+
if (this.comparator(current.key, newNode.key) === 0) {
|
|
274
239
|
this._replaceNode(current, newNode);
|
|
275
240
|
return true;
|
|
276
|
-
|
|
277
|
-
// } else {
|
|
278
|
-
// The key value is the same and the reference is the same, replace the entire node
|
|
279
|
-
// this._replaceNode(current, newNode);
|
|
280
|
-
|
|
281
|
-
// return;
|
|
282
|
-
// }
|
|
283
|
-
} else if (this._compare(current.key, newNode.key) === 'GT') {
|
|
241
|
+
} else if (this.comparator(current.key, newNode.key) > 0) {
|
|
284
242
|
if (current.left === undefined) {
|
|
285
243
|
current.left = newNode;
|
|
286
244
|
this._size++;
|
|
@@ -301,32 +259,33 @@ export class BST<
|
|
|
301
259
|
}
|
|
302
260
|
|
|
303
261
|
/**
|
|
304
|
-
* Time Complexity: O(
|
|
305
|
-
* Space Complexity: O(
|
|
262
|
+
* Time Complexity: O(log n)
|
|
263
|
+
* Space Complexity: O(log n)
|
|
306
264
|
*/
|
|
307
265
|
|
|
308
266
|
/**
|
|
309
267
|
* Time Complexity: O(k log n)
|
|
310
268
|
* Space Complexity: O(k + log n)
|
|
311
269
|
*
|
|
312
|
-
* The `addMany` function in TypeScript adds multiple keys or nodes to a
|
|
313
|
-
*
|
|
314
|
-
* @param
|
|
315
|
-
* the
|
|
270
|
+
* The `addMany` function in TypeScript adds multiple keys or nodes to a data structure and returns
|
|
271
|
+
* an array indicating whether each key or node was successfully inserted.
|
|
272
|
+
* @param keysOrNodesOrEntriesOrRawElements - An iterable containing keys, nodes, entries, or raw
|
|
273
|
+
* elements to be added to the data structure.
|
|
316
274
|
* @param [values] - An optional iterable of values to be associated with the keys or nodes being
|
|
317
275
|
* added. If provided, the values will be assigned to the corresponding keys or nodes in the same
|
|
318
276
|
* order. If not provided, undefined will be assigned as the value for each key or node.
|
|
319
|
-
* @param [isBalanceAdd=true] - A boolean flag indicating whether the
|
|
320
|
-
*
|
|
321
|
-
* algorithm. If set to false, the
|
|
322
|
-
*
|
|
323
|
-
* @param iterationType - The `iterationType` parameter is an optional parameter that
|
|
324
|
-
* type of iteration to use when adding multiple keys or nodes
|
|
325
|
-
*
|
|
326
|
-
* @returns The function `addMany` returns an array of
|
|
277
|
+
* @param [isBalanceAdd=true] - A boolean flag indicating whether the tree should be balanced after
|
|
278
|
+
* adding the elements. If set to true, the tree will be balanced using a binary search tree
|
|
279
|
+
* algorithm. If set to false, the elements will be added without balancing the tree. The default
|
|
280
|
+
* value is true.
|
|
281
|
+
* @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that
|
|
282
|
+
* specifies the type of iteration to use when adding multiple keys or nodes to the binary search
|
|
283
|
+
* tree. It can have two possible values:
|
|
284
|
+
* @returns The function `addMany` returns an array of booleans indicating whether each element was
|
|
285
|
+
* successfully inserted into the data structure.
|
|
327
286
|
*/
|
|
328
287
|
override addMany(
|
|
329
|
-
|
|
288
|
+
keysOrNodesOrEntriesOrRawElements: Iterable<R | KeyOrNodeOrEntry<K, V, NODE>>,
|
|
330
289
|
values?: Iterable<V | undefined>,
|
|
331
290
|
isBalanceAdd = true,
|
|
332
291
|
iterationType: IterationType = this.iterationType
|
|
@@ -340,7 +299,7 @@ export class BST<
|
|
|
340
299
|
}
|
|
341
300
|
|
|
342
301
|
if (!isBalanceAdd) {
|
|
343
|
-
for (const kve of
|
|
302
|
+
for (const kve of keysOrNodesOrEntriesOrRawElements) {
|
|
344
303
|
const value = valuesIterator?.next().value;
|
|
345
304
|
const nn = this.add(kve, value);
|
|
346
305
|
inserted.push(nn);
|
|
@@ -348,33 +307,44 @@ export class BST<
|
|
|
348
307
|
return inserted;
|
|
349
308
|
}
|
|
350
309
|
|
|
351
|
-
const realBTNExemplars:
|
|
310
|
+
const realBTNExemplars: (R | BTNPureKeyOrNodeOrEntry<K, V, NODE>)[] = [];
|
|
352
311
|
|
|
353
|
-
const isRealBTNExemplar = (kve: KeyOrNodeOrEntry<K, V, NODE>): kve is
|
|
312
|
+
const isRealBTNExemplar = (kve: R | KeyOrNodeOrEntry<K, V, NODE>): kve is BTNPureKeyOrNodeOrEntry<K, V, NODE> => {
|
|
354
313
|
if (kve === undefined || kve === null) return false;
|
|
355
314
|
return !(this.isEntry(kve) && (kve[0] === undefined || kve[0] === null));
|
|
356
315
|
};
|
|
357
316
|
|
|
358
|
-
for (const kve of
|
|
317
|
+
for (const kve of keysOrNodesOrEntriesOrRawElements) {
|
|
359
318
|
isRealBTNExemplar(kve) && realBTNExemplars.push(kve);
|
|
360
319
|
}
|
|
361
320
|
|
|
362
|
-
let sorted:
|
|
321
|
+
let sorted: (R | BTNPureKeyOrNodeOrEntry<K, V, NODE>)[] = [];
|
|
363
322
|
|
|
364
323
|
sorted = realBTNExemplars.sort((a, b) => {
|
|
365
|
-
let
|
|
366
|
-
if (this.isEntry(a))
|
|
367
|
-
else if (this.isRealNode(a))
|
|
368
|
-
else
|
|
324
|
+
let keyA: K | undefined | null, keyB: K | undefined | null;
|
|
325
|
+
if (this.isEntry(a)) keyA = a[0];
|
|
326
|
+
else if (this.isRealNode(a)) keyA = a.key;
|
|
327
|
+
else if (this.toEntryFn) {
|
|
328
|
+
keyA = this.toEntryFn(a as R)[0];
|
|
329
|
+
} else {
|
|
330
|
+
keyA = a as K;
|
|
331
|
+
}
|
|
369
332
|
|
|
370
|
-
if (this.isEntry(b))
|
|
371
|
-
else if (this.isRealNode(b))
|
|
372
|
-
else
|
|
333
|
+
if (this.isEntry(b)) keyB = b[0];
|
|
334
|
+
else if (this.isRealNode(b)) keyB = b.key;
|
|
335
|
+
else if (this.toEntryFn) {
|
|
336
|
+
keyB = this.toEntryFn(b as R)[0];
|
|
337
|
+
} else {
|
|
338
|
+
keyB = b as K;
|
|
339
|
+
}
|
|
373
340
|
|
|
374
|
-
|
|
341
|
+
if (keyA !== undefined && keyA !== null && keyB !== undefined && keyB !== null) {
|
|
342
|
+
return this.comparator(keyA, keyB);
|
|
343
|
+
}
|
|
344
|
+
return 0;
|
|
375
345
|
});
|
|
376
346
|
|
|
377
|
-
const _dfs = (arr:
|
|
347
|
+
const _dfs = (arr: (R | BTNPureKeyOrNodeOrEntry<K, V, NODE>)[]) => {
|
|
378
348
|
if (arr.length === 0) return;
|
|
379
349
|
|
|
380
350
|
const mid = Math.floor((arr.length - 1) / 2);
|
|
@@ -412,38 +382,32 @@ export class BST<
|
|
|
412
382
|
}
|
|
413
383
|
|
|
414
384
|
/**
|
|
415
|
-
* Time Complexity: O(log n)
|
|
416
|
-
* Space Complexity: O(k + log n)
|
|
417
|
-
* /
|
|
418
|
-
|
|
419
|
-
/**
|
|
420
385
|
* Time Complexity: O(log n)
|
|
421
386
|
* Space Complexity: O(k + log n)
|
|
422
387
|
*
|
|
423
|
-
* The
|
|
424
|
-
*
|
|
388
|
+
* The `getNodes` function in TypeScript retrieves nodes from a binary tree based on a given
|
|
389
|
+
* identifier and callback function.
|
|
425
390
|
* @param {ReturnType<C> | undefined} identifier - The `identifier` parameter is the value that you
|
|
426
|
-
* want to search for in the
|
|
427
|
-
*
|
|
428
|
-
* @param {C} callback - The `callback` parameter is a function that takes a node
|
|
429
|
-
*
|
|
430
|
-
* function
|
|
431
|
-
* @param [onlyOne=false] - A boolean
|
|
432
|
-
*
|
|
433
|
-
*
|
|
434
|
-
*
|
|
435
|
-
*
|
|
436
|
-
*
|
|
437
|
-
*
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
* @returns The method returns an array of nodes (`NODE[]`).
|
|
391
|
+
* want to search for in the binary tree. It can be of any type that is returned by the callback
|
|
392
|
+
* function.
|
|
393
|
+
* @param {C} callback - The `callback` parameter is a function that takes a node as input and
|
|
394
|
+
* returns a value. This value is used to identify the nodes that match the given identifier. The
|
|
395
|
+
* `callback` function is optional and defaults to `this._DEFAULT_CALLBACK`.
|
|
396
|
+
* @param [onlyOne=false] - A boolean value indicating whether to return only the first matching node
|
|
397
|
+
* or all matching nodes. If set to true, only the first matching node will be returned. If set to
|
|
398
|
+
* false, all matching nodes will be returned. The default value is false.
|
|
399
|
+
* @param {R | KeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter is the starting
|
|
400
|
+
* point for the search in the binary tree. It can be either a node object, a key-value pair, or an
|
|
401
|
+
* entry object. If it is not provided, the `root` of the binary tree is used as the starting point.
|
|
402
|
+
* @param {IterationType} iterationType - The `iterationType` parameter determines the type of
|
|
403
|
+
* iteration to be performed. It can have two possible values:
|
|
404
|
+
* @returns The method `getNodes` returns an array of `NODE` objects.
|
|
441
405
|
*/
|
|
442
406
|
override getNodes<C extends BTNCallback<NODE>>(
|
|
443
407
|
identifier: ReturnType<C> | undefined,
|
|
444
408
|
callback: C = this._DEFAULT_CALLBACK as C,
|
|
445
409
|
onlyOne = false,
|
|
446
|
-
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
410
|
+
beginRoot: R | KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
447
411
|
iterationType: IterationType = this.iterationType
|
|
448
412
|
): NODE[] {
|
|
449
413
|
beginRoot = this.ensureNode(beginRoot);
|
|
@@ -462,8 +426,8 @@ export class BST<
|
|
|
462
426
|
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
|
|
463
427
|
// TODO potential bug
|
|
464
428
|
if (callback === this._DEFAULT_CALLBACK) {
|
|
465
|
-
if (this.isRealNode(cur.left) && this.
|
|
466
|
-
if (this.isRealNode(cur.right) && this.
|
|
429
|
+
if (this.isRealNode(cur.left) && this.comparator(cur.key, identifier as K) > 0) dfs(cur.left);
|
|
430
|
+
if (this.isRealNode(cur.right) && this.comparator(cur.key, identifier as K) < 0) dfs(cur.right);
|
|
467
431
|
} else {
|
|
468
432
|
this.isRealNode(cur.left) && dfs(cur.left);
|
|
469
433
|
this.isRealNode(cur.right) && dfs(cur.right);
|
|
@@ -482,8 +446,8 @@ export class BST<
|
|
|
482
446
|
}
|
|
483
447
|
// TODO potential bug
|
|
484
448
|
if (callback === this._DEFAULT_CALLBACK) {
|
|
485
|
-
if (this.isRealNode(cur.right) && this.
|
|
486
|
-
if (this.isRealNode(cur.left) && this.
|
|
449
|
+
if (this.isRealNode(cur.right) && this.comparator(cur.key, identifier as K) < 0) stack.push(cur.right);
|
|
450
|
+
if (this.isRealNode(cur.left) && this.comparator(cur.key, identifier as K) > 0) stack.push(cur.left);
|
|
487
451
|
|
|
488
452
|
// if (this.isRealNode(cur.right) && this._lt(cur.key, identifier as K)) stack.push(cur.right);
|
|
489
453
|
// if (this.isRealNode(cur.left) && this._gt(cur.key, identifier as K)) stack.push(cur.left);
|
|
@@ -511,58 +475,57 @@ export class BST<
|
|
|
511
475
|
* Time Complexity: O(log n)
|
|
512
476
|
* Space Complexity: O(1)
|
|
513
477
|
*
|
|
514
|
-
* The `getNode`
|
|
515
|
-
*
|
|
516
|
-
* @param {ReturnType<C> | undefined} identifier - The `identifier` parameter is the value
|
|
517
|
-
*
|
|
518
|
-
*
|
|
519
|
-
* @param {C} callback - The `callback` parameter is a function that will be
|
|
520
|
-
* the
|
|
521
|
-
*
|
|
522
|
-
*
|
|
478
|
+
* The function `getNode` returns the first node that matches the given identifier and callback
|
|
479
|
+
* function in a binary search tree.
|
|
480
|
+
* @param {ReturnType<C> | undefined} identifier - The `identifier` parameter is the value that you
|
|
481
|
+
* want to search for in the binary search tree. It can be of any type that is compatible with the
|
|
482
|
+
* type returned by the callback function.
|
|
483
|
+
* @param {C} callback - The `callback` parameter is a function that will be used to determine if a
|
|
484
|
+
* node matches the desired criteria. It should be a function that takes a node as an argument and
|
|
485
|
+
* returns a boolean value indicating whether the node matches the criteria or not. If no callback is
|
|
486
|
+
* provided, the default callback will be
|
|
523
487
|
* @param beginRoot - The `beginRoot` parameter is the starting point for the search in the binary
|
|
524
|
-
* search tree. It can be either a key or a node. If it is a key,
|
|
525
|
-
*
|
|
526
|
-
* @param iterationType - The `iterationType` parameter is used to specify the type
|
|
527
|
-
* be performed when searching for nodes in the binary search tree. It
|
|
528
|
-
*
|
|
529
|
-
* @returns The method is returning a
|
|
488
|
+
* search tree. It can be either a key or a node. If it is a key, the search will start from the node
|
|
489
|
+
* with that key. If it is a node, the search will start from that node.
|
|
490
|
+
* @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type
|
|
491
|
+
* of iteration to be performed when searching for nodes in the binary search tree. It can have one
|
|
492
|
+
* of the following values:
|
|
493
|
+
* @returns The method is returning a NODE object or undefined.
|
|
530
494
|
*/
|
|
531
495
|
override getNode<C extends BTNCallback<NODE>>(
|
|
532
496
|
identifier: ReturnType<C> | undefined,
|
|
533
497
|
callback: C = this._DEFAULT_CALLBACK as C,
|
|
534
|
-
beginRoot: BSTNKeyOrNode<K, NODE> = this.root,
|
|
498
|
+
beginRoot: R | BSTNKeyOrNode<K, NODE> = this.root,
|
|
535
499
|
iterationType: IterationType = this.iterationType
|
|
536
500
|
): NODE | undefined {
|
|
537
501
|
return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined;
|
|
538
502
|
}
|
|
539
503
|
|
|
540
504
|
/**
|
|
541
|
-
* Time Complexity: O(log n)
|
|
542
|
-
* Space Complexity: O(
|
|
505
|
+
* Time Complexity: O(k log n)
|
|
506
|
+
* Space Complexity: O(k + log n)
|
|
543
507
|
*/
|
|
544
508
|
|
|
545
509
|
/**
|
|
546
510
|
* Time Complexity: O(log n)
|
|
547
511
|
* Space Complexity: O(1)
|
|
548
512
|
*
|
|
549
|
-
* The function `getNodeByKey`
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
*
|
|
553
|
-
* @param iterationType - The `iterationType` parameter is an optional
|
|
554
|
-
* type of iteration to
|
|
555
|
-
*
|
|
556
|
-
* @returns The
|
|
557
|
-
* found in the binary tree. If no node is found, it returns `undefined`.
|
|
513
|
+
* The function `getNodeByKey` returns a node with a specific key from a tree data structure.
|
|
514
|
+
* @param {K} key - The key parameter is the value used to search for a specific node in the tree. It
|
|
515
|
+
* is typically a unique identifier or a value that can be used to determine the position of the node
|
|
516
|
+
* in the tree structure.
|
|
517
|
+
* @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional
|
|
518
|
+
* parameter that specifies the type of iteration to be used when searching for a node in the tree.
|
|
519
|
+
* It has a default value of `'ITERATIVE'`.
|
|
520
|
+
* @returns The method is returning a NODE object or undefined.
|
|
558
521
|
*/
|
|
559
522
|
override getNodeByKey(key: K, iterationType: IterationType = 'ITERATIVE'): NODE | undefined {
|
|
560
523
|
return this.getNode(key, this._DEFAULT_CALLBACK, this.root, iterationType);
|
|
561
524
|
}
|
|
562
525
|
|
|
563
526
|
/**
|
|
564
|
-
* Time
|
|
565
|
-
* Space
|
|
527
|
+
* Time Complexity: O(log n)
|
|
528
|
+
* Space Complexity: O(k + log n)
|
|
566
529
|
*/
|
|
567
530
|
|
|
568
531
|
/**
|
|
@@ -572,30 +535,31 @@ export class BST<
|
|
|
572
535
|
* The function overrides the depth-first search method and returns an array of the return types of
|
|
573
536
|
* the callback function.
|
|
574
537
|
* @param {C} callback - The `callback` parameter is a function that will be called for each node
|
|
575
|
-
* during the depth-first search traversal. It is an optional parameter and
|
|
576
|
-
*
|
|
577
|
-
* @param {DFSOrderPattern} [pattern=
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
*
|
|
583
|
-
*
|
|
538
|
+
* during the depth-first search traversal. It is an optional parameter and defaults to
|
|
539
|
+
* `this._DEFAULT_CALLBACK`. The type `C` represents the type of the callback function.
|
|
540
|
+
* @param {DFSOrderPattern} [pattern=IN] - The "pattern" parameter in the code snippet refers to the
|
|
541
|
+
* order in which the Depth-First Search (DFS) algorithm visits the nodes in a tree or graph. It can
|
|
542
|
+
* take one of the following values:
|
|
543
|
+
* @param {R | KeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter is the starting
|
|
544
|
+
* point for the depth-first search traversal. It can be either a root node, a key-value pair, or a
|
|
545
|
+
* node entry. If not specified, the default value is the root of the tree.
|
|
546
|
+
* @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter specifies the
|
|
547
|
+
* type of iteration to be used during the Depth-First Search (DFS) traversal. It can have one of the
|
|
584
548
|
* following values:
|
|
585
549
|
* @returns The method is returning an array of the return type of the callback function.
|
|
586
550
|
*/
|
|
587
551
|
override dfs<C extends BTNCallback<NODE>>(
|
|
588
552
|
callback: C = this._DEFAULT_CALLBACK as C,
|
|
589
553
|
pattern: DFSOrderPattern = 'IN',
|
|
590
|
-
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
554
|
+
beginRoot: R | KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
591
555
|
iterationType: IterationType = 'ITERATIVE'
|
|
592
556
|
): ReturnType<C>[] {
|
|
593
557
|
return super.dfs(callback, pattern, beginRoot, iterationType, false);
|
|
594
558
|
}
|
|
595
559
|
|
|
596
560
|
/**
|
|
597
|
-
* Time
|
|
598
|
-
* Space
|
|
561
|
+
* Time Complexity: O(log n)
|
|
562
|
+
* Space Complexity: O(1)
|
|
599
563
|
*/
|
|
600
564
|
|
|
601
565
|
/**
|
|
@@ -605,134 +569,98 @@ export class BST<
|
|
|
605
569
|
* The function overrides the breadth-first search method and returns an array of the return types of
|
|
606
570
|
* the callback function.
|
|
607
571
|
* @param {C} callback - The `callback` parameter is a function that will be called for each node
|
|
608
|
-
* visited during the breadth-first search
|
|
609
|
-
*
|
|
610
|
-
* @param beginRoot - The `beginRoot` parameter is the starting
|
|
611
|
-
*
|
|
612
|
-
* the
|
|
613
|
-
* @param iterationType - The `iterationType` parameter is used to specify the type
|
|
614
|
-
* be performed during the breadth-first search (BFS) traversal. It
|
|
615
|
-
*
|
|
616
|
-
* @returns
|
|
572
|
+
* visited during the breadth-first search. It should take a single argument, which is the current
|
|
573
|
+
* node being visited, and it can return a value of any type.
|
|
574
|
+
* @param {R | KeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter is the starting
|
|
575
|
+
* point for the breadth-first search. It can be either a root node, a key-value pair, or an entry
|
|
576
|
+
* object. If no value is provided, the default value is the root of the tree.
|
|
577
|
+
* @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type
|
|
578
|
+
* of iteration to be performed during the breadth-first search (BFS) traversal. It can have one of
|
|
579
|
+
* the following values:
|
|
580
|
+
* @returns an array of the return type of the callback function.
|
|
617
581
|
*/
|
|
618
582
|
override bfs<C extends BTNCallback<NODE>>(
|
|
619
583
|
callback: C = this._DEFAULT_CALLBACK as C,
|
|
620
|
-
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
584
|
+
beginRoot: R | KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
621
585
|
iterationType: IterationType = this.iterationType
|
|
622
586
|
): ReturnType<C>[] {
|
|
623
587
|
return super.bfs(callback, beginRoot, iterationType, false);
|
|
624
588
|
}
|
|
625
589
|
|
|
626
590
|
/**
|
|
627
|
-
* Time
|
|
628
|
-
* Space
|
|
591
|
+
* Time Complexity: O(log n)
|
|
592
|
+
* Space Complexity: O(1)
|
|
629
593
|
*/
|
|
630
594
|
|
|
631
595
|
/**
|
|
632
596
|
* Time complexity: O(n)
|
|
633
597
|
* Space complexity: O(n)
|
|
634
598
|
*
|
|
635
|
-
* The function overrides the listLevels method and returns an array of arrays
|
|
636
|
-
*
|
|
599
|
+
* The function overrides the listLevels method from the superclass and returns an array of arrays
|
|
600
|
+
* containing the results of the callback function applied to each level of the tree.
|
|
637
601
|
* @param {C} callback - The `callback` parameter is a generic type `C` that extends
|
|
638
|
-
* `BTNCallback<NODE>`. It represents a callback function that will be called for each node in the
|
|
639
|
-
* during the
|
|
640
|
-
* @param beginRoot - The `beginRoot` parameter is
|
|
641
|
-
* levels of
|
|
642
|
-
*
|
|
643
|
-
*
|
|
644
|
-
*
|
|
645
|
-
* iteration.
|
|
602
|
+
* `BTNCallback<NODE>`. It represents a callback function that will be called for each node in the
|
|
603
|
+
* tree during the iteration process.
|
|
604
|
+
* @param {R | KeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter is the starting
|
|
605
|
+
* point for listing the levels of the binary tree. It can be either a root node of the tree, a
|
|
606
|
+
* key-value pair representing a node in the tree, or a key representing a node in the tree. If no
|
|
607
|
+
* value is provided, the root of
|
|
608
|
+
* @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type
|
|
609
|
+
* of iteration to be performed on the tree. It can have one of the following values:
|
|
646
610
|
* @returns The method is returning a two-dimensional array of the return type of the callback
|
|
647
611
|
* function.
|
|
648
612
|
*/
|
|
649
613
|
override listLevels<C extends BTNCallback<NODE>>(
|
|
650
614
|
callback: C = this._DEFAULT_CALLBACK as C,
|
|
651
|
-
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
615
|
+
beginRoot: R | KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
652
616
|
iterationType: IterationType = this.iterationType
|
|
653
617
|
): ReturnType<C>[][] {
|
|
654
618
|
return super.listLevels(callback, beginRoot, iterationType, false);
|
|
655
619
|
}
|
|
656
620
|
|
|
657
621
|
/**
|
|
658
|
-
* Time
|
|
659
|
-
* Space
|
|
660
|
-
*/
|
|
661
|
-
|
|
662
|
-
/**
|
|
663
|
-
* Time Complexity: O(log n)
|
|
664
|
-
* Space Complexity: O(1)
|
|
665
|
-
*
|
|
666
|
-
* The `lastKey` function returns the key of the rightmost node in a binary tree, or the key of the
|
|
667
|
-
* leftmost node if the comparison result is greater than.
|
|
668
|
-
* @param {K | NODE | undefined} beginRoot - The `beginRoot` parameter is optional and can be of
|
|
669
|
-
* type `K`, `NODE`, or `undefined`. It represents the starting point for finding the last key in
|
|
670
|
-
* the binary tree. If not provided, it defaults to the root of the binary tree (`this.root`).
|
|
671
|
-
* @returns the key of the rightmost node in the binary tree if the comparison result is less than,
|
|
672
|
-
* the key of the leftmost node if the comparison result is greater than, and the key of the
|
|
673
|
-
* rightmost node otherwise. If no node is found, it returns 0.
|
|
674
|
-
*/
|
|
675
|
-
lastKey(beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root): K | undefined {
|
|
676
|
-
let current = this.ensureNode(beginRoot);
|
|
677
|
-
if (!current) return undefined;
|
|
678
|
-
|
|
679
|
-
if (this._variant === 'STANDARD') {
|
|
680
|
-
// For 'STANDARD', find the rightmost node
|
|
681
|
-
while (current.right !== undefined) {
|
|
682
|
-
current = current.right;
|
|
683
|
-
}
|
|
684
|
-
} else {
|
|
685
|
-
// For BSTVariant.MAX, find the leftmost node
|
|
686
|
-
while (current.left !== undefined) {
|
|
687
|
-
current = current.left;
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
return current.key;
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
/**
|
|
694
|
-
* Time Complexity: O(log n)
|
|
695
|
-
* Space Complexity: O(log n)
|
|
622
|
+
* Time complexity: O(n)
|
|
623
|
+
* Space complexity: O(n)
|
|
696
624
|
*/
|
|
697
625
|
|
|
698
626
|
/**
|
|
699
|
-
* Time
|
|
700
|
-
* Space
|
|
627
|
+
* Time complexity: O(n)
|
|
628
|
+
* Space complexity: O(n)
|
|
701
629
|
*
|
|
702
|
-
* The `lesserOrGreaterTraverse` function traverses a binary tree and
|
|
703
|
-
*
|
|
630
|
+
* The `lesserOrGreaterTraverse` function traverses a binary tree and applies a callback function to
|
|
631
|
+
* each node that meets a certain condition based on a target node and a comparison value.
|
|
704
632
|
* @param {C} callback - The `callback` parameter is a function that will be called for each node
|
|
705
|
-
* that
|
|
706
|
-
*
|
|
633
|
+
* that meets the condition specified by the `lesserOrGreater` parameter. It takes a single argument,
|
|
634
|
+
* which is the current node being traversed, and returns a value of any type.
|
|
707
635
|
* @param {CP} lesserOrGreater - The `lesserOrGreater` parameter is used to determine whether to
|
|
708
|
-
* traverse nodes that are lesser
|
|
709
|
-
*
|
|
710
|
-
* `
|
|
711
|
-
*
|
|
712
|
-
*
|
|
713
|
-
*
|
|
714
|
-
* @param iterationType - The `iterationType` parameter determines the type of
|
|
715
|
-
* performed on the binary tree. It can have two possible values:
|
|
636
|
+
* traverse nodes that are lesser, greater, or both than the `targetNode`. It accepts the values -1,
|
|
637
|
+
* 0, or 1, where:
|
|
638
|
+
* @param {R | KeyOrNodeOrEntry<K, V, NODE>} targetNode - The `targetNode` parameter is the node in
|
|
639
|
+
* the binary tree that you want to start traversing from. It can be specified either by providing
|
|
640
|
+
* the key of the node, the node itself, or an entry containing the key and value of the node. If no
|
|
641
|
+
* `targetNode` is provided,
|
|
642
|
+
* @param {IterationType} iterationType - The `iterationType` parameter determines the type of
|
|
643
|
+
* traversal to be performed on the binary tree. It can have two possible values:
|
|
716
644
|
* @returns The function `lesserOrGreaterTraverse` returns an array of values of type
|
|
717
645
|
* `ReturnType<C>`, which is the return type of the callback function passed as an argument.
|
|
718
646
|
*/
|
|
719
647
|
lesserOrGreaterTraverse<C extends BTNCallback<NODE>>(
|
|
720
648
|
callback: C = this._DEFAULT_CALLBACK as C,
|
|
721
|
-
lesserOrGreater: CP =
|
|
722
|
-
targetNode: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
649
|
+
lesserOrGreater: CP = -1,
|
|
650
|
+
targetNode: R | KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
723
651
|
iterationType: IterationType = this.iterationType
|
|
724
652
|
): ReturnType<C>[] {
|
|
725
|
-
|
|
653
|
+
const targetNodeEnsured = this.ensureNode(targetNode);
|
|
726
654
|
const ans: ReturnType<BTNCallback<NODE>>[] = [];
|
|
727
|
-
if (!
|
|
655
|
+
if (!targetNodeEnsured) return ans;
|
|
728
656
|
if (!this.root) return ans;
|
|
729
657
|
|
|
730
|
-
const targetKey =
|
|
658
|
+
const targetKey = targetNodeEnsured.key;
|
|
731
659
|
|
|
732
660
|
if (iterationType === 'RECURSIVE') {
|
|
733
661
|
const dfs = (cur: NODE) => {
|
|
734
|
-
const compared = this.
|
|
735
|
-
if (compared === lesserOrGreater) ans.push(callback(cur));
|
|
662
|
+
const compared = this.comparator(cur.key, targetKey);
|
|
663
|
+
if (Math.sign(compared) === lesserOrGreater) ans.push(callback(cur));
|
|
736
664
|
|
|
737
665
|
if (this.isRealNode(cur.left)) dfs(cur.left);
|
|
738
666
|
if (this.isRealNode(cur.right)) dfs(cur.right);
|
|
@@ -745,8 +673,8 @@ export class BST<
|
|
|
745
673
|
while (queue.size > 0) {
|
|
746
674
|
const cur = queue.shift();
|
|
747
675
|
if (this.isRealNode(cur)) {
|
|
748
|
-
const compared = this.
|
|
749
|
-
if (compared === lesserOrGreater) ans.push(callback(cur));
|
|
676
|
+
const compared = this.comparator(cur.key, targetKey);
|
|
677
|
+
if (Math.sign(compared) === lesserOrGreater) ans.push(callback(cur));
|
|
750
678
|
|
|
751
679
|
if (this.isRealNode(cur.left)) queue.push(cur.left);
|
|
752
680
|
if (this.isRealNode(cur.right)) queue.push(cur.right);
|
|
@@ -757,19 +685,20 @@ export class BST<
|
|
|
757
685
|
}
|
|
758
686
|
|
|
759
687
|
/**
|
|
760
|
-
* Time
|
|
761
|
-
* Space
|
|
688
|
+
* Time complexity: O(n)
|
|
689
|
+
* Space complexity: O(n)
|
|
762
690
|
*/
|
|
763
691
|
|
|
764
692
|
/**
|
|
765
|
-
* Time
|
|
766
|
-
* Space
|
|
693
|
+
* Time complexity: O(n)
|
|
694
|
+
* Space complexity: O(n)
|
|
767
695
|
*
|
|
768
|
-
* The `perfectlyBalance` function
|
|
769
|
-
*
|
|
770
|
-
* @param iterationType - The `iterationType` parameter is an optional parameter that
|
|
771
|
-
* type of iteration to use when building a balanced binary search tree. It
|
|
772
|
-
*
|
|
696
|
+
* The `perfectlyBalance` function takes an optional `iterationType` parameter and returns `true` if
|
|
697
|
+
* the binary search tree is perfectly balanced, otherwise it returns `false`.
|
|
698
|
+
* @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that
|
|
699
|
+
* specifies the type of iteration to use when building a balanced binary search tree. It has a
|
|
700
|
+
* default value of `this.iterationType`, which means it will use the iteration type specified in the
|
|
701
|
+
* current instance of the class.
|
|
773
702
|
* @returns The function `perfectlyBalance` returns a boolean value.
|
|
774
703
|
*/
|
|
775
704
|
perfectlyBalance(iterationType: IterationType = this.iterationType): boolean {
|
|
@@ -810,27 +739,20 @@ export class BST<
|
|
|
810
739
|
}
|
|
811
740
|
|
|
812
741
|
/**
|
|
813
|
-
*
|
|
814
|
-
*
|
|
815
|
-
* AVL Tree: After insertion or deletion operations, an AVL tree performs rotation adjustments based on the balance factor of nodes to restore the tree's balance. These rotations can be left rotations, right rotations, left-right rotations, or right-left rotations, performed as needed.
|
|
816
|
-
*
|
|
817
|
-
* Use Cases and Efficiency:
|
|
818
|
-
* Perfectly Balanced Binary Tree: Perfectly balanced binary trees are typically used in specific scenarios such as complete binary heaps in heap sort or certain types of Huffman trees. However, they are not suitable for dynamic operations requiring frequent insertions and deletions, as these operations often necessitate full tree reconstruction.
|
|
819
|
-
* AVL Tree: AVL trees are well-suited for scenarios involving frequent searching, insertion, and deletion operations. Through rotation adjustments, AVL trees maintain their balance, ensuring average and worst-case time complexity of O(log n).
|
|
820
|
-
*/
|
|
821
|
-
|
|
822
|
-
/**
|
|
823
|
-
* Time Complexity: O(n)
|
|
824
|
-
* Space Complexity: O(log n)
|
|
742
|
+
* Time complexity: O(n)
|
|
743
|
+
* Space complexity: O(n)
|
|
825
744
|
*/
|
|
826
745
|
|
|
827
746
|
/**
|
|
828
747
|
* Time Complexity: O(n)
|
|
829
748
|
* Space Complexity: O(log n)
|
|
830
749
|
*
|
|
831
|
-
* The function checks if a binary tree is AVL balanced using either recursive or
|
|
832
|
-
*
|
|
833
|
-
*
|
|
750
|
+
* The function `isAVLBalanced` checks if a binary tree is AVL balanced using either a recursive or
|
|
751
|
+
* iterative approach.
|
|
752
|
+
* @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that
|
|
753
|
+
* specifies the type of iteration to use when checking if the AVL tree is balanced. It has a default
|
|
754
|
+
* value of `this.iterationType`, which means it will use the iteration type specified in the current
|
|
755
|
+
* instance of the AVL tree.
|
|
834
756
|
* @returns a boolean value.
|
|
835
757
|
*/
|
|
836
758
|
isAVLBalanced(iterationType: IterationType = this.iterationType): boolean {
|
|
@@ -878,61 +800,50 @@ export class BST<
|
|
|
878
800
|
}
|
|
879
801
|
|
|
880
802
|
/**
|
|
881
|
-
*
|
|
882
|
-
*
|
|
883
|
-
* can either be an object of type `NODE` or it can be `undefined`.
|
|
803
|
+
* Time complexity: O(n)
|
|
804
|
+
* Space complexity: O(n)
|
|
884
805
|
*/
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
806
|
+
|
|
807
|
+
protected _DEFAULT_COMPARATOR = (a: K, b: K): number => {
|
|
808
|
+
if (typeof a === 'object' && typeof b === 'object' && this.comparator === this._DEFAULT_COMPARATOR) {
|
|
809
|
+
throw TypeError(
|
|
810
|
+
'When comparing two object types, it is necessary to customize a [comparator] function of options parameter during the instantiation of the data structure.'
|
|
811
|
+
);
|
|
888
812
|
}
|
|
889
|
-
|
|
890
|
-
|
|
813
|
+
if (a > b) return 1;
|
|
814
|
+
if (a < b) return -1;
|
|
815
|
+
return 0;
|
|
816
|
+
};
|
|
891
817
|
|
|
892
818
|
/**
|
|
893
|
-
*
|
|
894
|
-
*
|
|
895
|
-
* @param {K} a - The parameter "a" is of type K.
|
|
896
|
-
* @param {K} b - The parameter "b" in the above code represents a K.
|
|
897
|
-
* @returns a value of type CP (ComparisonResult). The possible return values are 'GT' (greater
|
|
898
|
-
* than), 'LT' (less than), or 'EQ' (equal).
|
|
819
|
+
* Time complexity: O(n)
|
|
820
|
+
* Space complexity: O(n)
|
|
899
821
|
*/
|
|
900
|
-
protected _compare(a: K, b: K): CP {
|
|
901
|
-
const extractedA = this.extractor(a);
|
|
902
|
-
const extractedB = this.extractor(b);
|
|
903
|
-
const compared = this.variant === 'STANDARD' ? extractedA - extractedB : extractedB - extractedA;
|
|
904
822
|
|
|
905
|
-
|
|
906
|
-
if (compared < 0) return 'LT';
|
|
907
|
-
return 'EQ';
|
|
908
|
-
}
|
|
823
|
+
protected _comparator: Comparator<K> = this._DEFAULT_COMPARATOR;
|
|
909
824
|
|
|
910
825
|
/**
|
|
911
|
-
*
|
|
912
|
-
*
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
*
|
|
917
|
-
* @returns
|
|
826
|
+
* Time Complexity: O(n)
|
|
827
|
+
* Space Complexity: O(log n)
|
|
828
|
+
*/
|
|
829
|
+
|
|
830
|
+
/**
|
|
831
|
+
* The function returns the value of the _comparator property.
|
|
832
|
+
* @returns The `_comparator` property is being returned.
|
|
918
833
|
*/
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
const extractedB = this.extractor(b);
|
|
922
|
-
return this.variant === 'STANDARD' ? extractedA < extractedB : extractedA > extractedB;
|
|
834
|
+
get comparator() {
|
|
835
|
+
return this._comparator;
|
|
923
836
|
}
|
|
924
837
|
|
|
925
838
|
/**
|
|
926
|
-
* The function
|
|
927
|
-
*
|
|
928
|
-
* @param {
|
|
929
|
-
* @param {K} b - The parameter "b" is of type K, which means it can be any type. It is used as one
|
|
930
|
-
* of the arguments for the comparison in the function.
|
|
931
|
-
* @returns a boolean value.
|
|
839
|
+
* The function sets the root of a tree-like structure and updates the parent property of the new
|
|
840
|
+
* root.
|
|
841
|
+
* @param {NODE | undefined} v - v is a parameter of type NODE or undefined.
|
|
932
842
|
*/
|
|
933
|
-
protected
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
843
|
+
protected override _setRoot(v: NODE | undefined) {
|
|
844
|
+
if (v) {
|
|
845
|
+
v.parent = undefined;
|
|
846
|
+
}
|
|
847
|
+
this._root = v;
|
|
937
848
|
}
|
|
938
849
|
}
|