directed-graph-typed 1.48.0 → 1.49.0
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/base/index.d.ts +1 -0
- package/dist/data-structures/base/index.js +17 -0
- package/dist/data-structures/base/iterable-base.d.ts +232 -0
- package/dist/data-structures/base/iterable-base.js +312 -0
- package/dist/data-structures/binary-tree/avl-tree.d.ts +28 -19
- package/dist/data-structures/binary-tree/avl-tree.js +22 -11
- package/dist/data-structures/binary-tree/binary-tree.d.ts +158 -152
- package/dist/data-structures/binary-tree/binary-tree.js +241 -215
- package/dist/data-structures/binary-tree/bst.d.ts +64 -48
- package/dist/data-structures/binary-tree/bst.js +94 -65
- package/dist/data-structures/binary-tree/rb-tree.d.ts +39 -39
- package/dist/data-structures/binary-tree/rb-tree.js +42 -49
- package/dist/data-structures/binary-tree/tree-multimap.d.ts +60 -34
- package/dist/data-structures/binary-tree/tree-multimap.js +59 -27
- package/dist/data-structures/graph/abstract-graph.d.ts +92 -53
- package/dist/data-structures/graph/abstract-graph.js +130 -103
- package/dist/data-structures/graph/directed-graph.d.ts +70 -52
- package/dist/data-structures/graph/directed-graph.js +111 -65
- package/dist/data-structures/graph/map-graph.d.ts +5 -5
- package/dist/data-structures/graph/map-graph.js +8 -8
- package/dist/data-structures/graph/undirected-graph.d.ts +51 -32
- package/dist/data-structures/graph/undirected-graph.js +117 -54
- package/dist/data-structures/hash/hash-map.d.ts +160 -44
- package/dist/data-structures/hash/hash-map.js +314 -82
- package/dist/data-structures/heap/heap.d.ts +50 -7
- package/dist/data-structures/heap/heap.js +60 -30
- package/dist/data-structures/index.d.ts +1 -0
- package/dist/data-structures/index.js +1 -0
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +42 -55
- package/dist/data-structures/linked-list/doubly-linked-list.js +50 -77
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +36 -55
- package/dist/data-structures/linked-list/singly-linked-list.js +44 -77
- package/dist/data-structures/queue/deque.d.ts +35 -167
- package/dist/data-structures/queue/deque.js +43 -249
- package/dist/data-structures/queue/queue.d.ts +49 -48
- package/dist/data-structures/queue/queue.js +69 -82
- package/dist/data-structures/stack/stack.d.ts +43 -10
- package/dist/data-structures/stack/stack.js +50 -31
- package/dist/data-structures/trie/trie.d.ts +41 -6
- package/dist/data-structures/trie/trie.js +53 -32
- package/dist/interfaces/binary-tree.d.ts +6 -6
- package/dist/types/common.d.ts +11 -8
- package/dist/types/common.js +6 -1
- package/dist/types/data-structures/base/base.d.ts +5 -0
- package/dist/types/data-structures/base/base.js +2 -0
- package/dist/types/data-structures/base/index.d.ts +1 -0
- package/dist/types/data-structures/base/index.js +17 -0
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +3 -3
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +4 -4
- package/dist/types/data-structures/binary-tree/bst.d.ts +6 -6
- package/dist/types/data-structures/binary-tree/rb-tree.d.ts +3 -3
- package/dist/types/data-structures/binary-tree/tree-multimap.d.ts +3 -3
- package/dist/types/data-structures/hash/hash-map.d.ts +4 -0
- package/dist/types/data-structures/index.d.ts +1 -0
- package/dist/types/data-structures/index.js +1 -0
- package/package.json +2 -2
- package/src/data-structures/base/index.ts +1 -0
- package/src/data-structures/base/iterable-base.ts +329 -0
- package/src/data-structures/binary-tree/avl-tree.ts +37 -25
- package/src/data-structures/binary-tree/binary-tree.ts +336 -296
- package/src/data-structures/binary-tree/bst.ts +135 -89
- package/src/data-structures/binary-tree/rb-tree.ts +60 -69
- package/src/data-structures/binary-tree/tree-multimap.ts +86 -49
- package/src/data-structures/graph/abstract-graph.ts +136 -104
- package/src/data-structures/graph/directed-graph.ts +114 -65
- package/src/data-structures/graph/map-graph.ts +8 -8
- package/src/data-structures/graph/undirected-graph.ts +124 -56
- package/src/data-structures/hash/hash-map.ts +335 -84
- package/src/data-structures/heap/heap.ts +63 -36
- package/src/data-structures/index.ts +1 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +54 -83
- package/src/data-structures/linked-list/singly-linked-list.ts +49 -84
- package/src/data-structures/queue/deque.ts +43 -275
- package/src/data-structures/queue/queue.ts +71 -86
- package/src/data-structures/stack/stack.ts +53 -34
- package/src/data-structures/trie/trie.ts +58 -35
- package/src/interfaces/binary-tree.ts +5 -6
- package/src/types/common.ts +11 -8
- package/src/types/data-structures/base/base.ts +6 -0
- package/src/types/data-structures/base/index.ts +1 -0
- package/src/types/data-structures/binary-tree/avl-tree.ts +3 -3
- package/src/types/data-structures/binary-tree/binary-tree.ts +6 -5
- package/src/types/data-structures/binary-tree/bst.ts +6 -6
- package/src/types/data-structures/binary-tree/rb-tree.ts +3 -3
- package/src/types/data-structures/binary-tree/tree-multimap.ts +3 -3
- package/src/types/data-structures/hash/hash-map.ts +2 -0
- package/src/types/data-structures/heap/heap.ts +1 -1
- package/src/types/data-structures/index.ts +1 -0
- package/src/types/data-structures/priority-queue/priority-queue.ts +1 -1
|
@@ -11,20 +11,18 @@ import type {
|
|
|
11
11
|
BSTNodeNested,
|
|
12
12
|
BSTOptions,
|
|
13
13
|
BTNCallback,
|
|
14
|
-
BTNKey,
|
|
15
14
|
BTNodeExemplar,
|
|
16
|
-
BTNodePureExemplar
|
|
17
|
-
Comparator
|
|
15
|
+
BTNodePureExemplar
|
|
18
16
|
} from '../../types';
|
|
19
|
-
import { CP, IterationType } from '../../types';
|
|
17
|
+
import { BSTVariant, BTNodeKeyOrNode, CP, IterationType } from '../../types';
|
|
20
18
|
import { BinaryTree, BinaryTreeNode } from './binary-tree';
|
|
21
19
|
import { IBinaryTree } from '../../interfaces';
|
|
22
20
|
import { Queue } from '../queue';
|
|
23
21
|
|
|
24
|
-
export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extends BinaryTreeNode<V, N> {
|
|
22
|
+
export class BSTNode<K = any, V = any, N extends BSTNode<K, V, N> = BSTNodeNested<K, V>> extends BinaryTreeNode<K, V, N> {
|
|
25
23
|
override parent?: N;
|
|
26
24
|
|
|
27
|
-
constructor(key:
|
|
25
|
+
constructor(key: K, value?: V) {
|
|
28
26
|
super(key, value);
|
|
29
27
|
this.parent = undefined;
|
|
30
28
|
this._left = undefined;
|
|
@@ -81,9 +79,9 @@ export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extend
|
|
|
81
79
|
* 6. Balance Variability: Can become unbalanced; special types maintain balance.
|
|
82
80
|
* 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.
|
|
83
81
|
*/
|
|
84
|
-
export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>, TREE extends BST<V, N, TREE> = BST<V, N, BSTNested<V, N>>>
|
|
85
|
-
extends BinaryTree<V, N, TREE>
|
|
86
|
-
implements IBinaryTree<V, N, TREE> {
|
|
82
|
+
export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BSTNodeNested<K, V>>, TREE extends BST<K, V, N, TREE> = BST<K, V, N, BSTNested<K, V, N>>>
|
|
83
|
+
extends BinaryTree<K, V, N, TREE>
|
|
84
|
+
implements IBinaryTree<K, V, N, TREE> {
|
|
87
85
|
|
|
88
86
|
|
|
89
87
|
/**
|
|
@@ -94,13 +92,13 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
94
92
|
* @param [options] - The `options` parameter is an optional object that can contain additional
|
|
95
93
|
* configuration options for the binary search tree. It can have the following properties:
|
|
96
94
|
*/
|
|
97
|
-
constructor(elements?: Iterable<BTNodeExemplar<V, N>>, options?: Partial<BSTOptions
|
|
95
|
+
constructor(elements?: Iterable<BTNodeExemplar<K, V, N>>, options?: Partial<BSTOptions<K>>) {
|
|
98
96
|
super([], options);
|
|
99
97
|
|
|
100
98
|
if (options) {
|
|
101
|
-
const {
|
|
102
|
-
if (
|
|
103
|
-
this.
|
|
99
|
+
const { variant } = options;
|
|
100
|
+
if (variant) {
|
|
101
|
+
this._variant = variant;
|
|
104
102
|
}
|
|
105
103
|
}
|
|
106
104
|
|
|
@@ -115,18 +113,22 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
115
113
|
return this._root;
|
|
116
114
|
}
|
|
117
115
|
|
|
118
|
-
|
|
116
|
+
protected _variant = BSTVariant.MIN
|
|
117
|
+
|
|
118
|
+
get variant() {
|
|
119
|
+
return this._variant;
|
|
120
|
+
}
|
|
119
121
|
|
|
120
122
|
/**
|
|
121
123
|
* The function creates a new binary search tree node with the given key and value.
|
|
122
|
-
* @param {
|
|
124
|
+
* @param {K} key - The key parameter is the key value that will be associated with
|
|
123
125
|
* the new node. It is used to determine the position of the node in the binary search tree.
|
|
124
126
|
* @param [value] - The parameter `value` is an optional value that can be assigned to the node. It
|
|
125
127
|
* represents the value associated with the node in a binary search tree.
|
|
126
128
|
* @returns a new instance of the BSTNode class with the specified key and value.
|
|
127
129
|
*/
|
|
128
|
-
override createNode(key:
|
|
129
|
-
return new BSTNode<V, N>(key, value) as N;
|
|
130
|
+
override createNode(key: K, value?: V): N {
|
|
131
|
+
return new BSTNode<K, V, N>(key, value) as N;
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
/**
|
|
@@ -136,29 +138,32 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
136
138
|
* that defines various options for creating a binary search tree.
|
|
137
139
|
* @returns a new instance of the BST class with the specified options.
|
|
138
140
|
*/
|
|
139
|
-
override createTree(options?: Partial<BSTOptions
|
|
140
|
-
return new BST<V, N, TREE>([], {
|
|
141
|
+
override createTree(options?: Partial<BSTOptions<K>>): TREE {
|
|
142
|
+
return new BST<K, V, N, TREE>([], {
|
|
141
143
|
iterationType: this.iterationType,
|
|
142
|
-
|
|
144
|
+
variant: this.variant, ...options
|
|
143
145
|
}) as TREE;
|
|
144
146
|
}
|
|
145
147
|
|
|
146
148
|
/**
|
|
147
149
|
* The function checks if an exemplar is an instance of BSTNode.
|
|
148
|
-
* @param exemplar - The `exemplar` parameter is a variable of type `BTNodeExemplar<V, N>`.
|
|
150
|
+
* @param exemplar - The `exemplar` parameter is a variable of type `BTNodeExemplar<K, V, N>`.
|
|
149
151
|
* @returns a boolean value indicating whether the exemplar is an instance of the BSTNode class.
|
|
150
152
|
*/
|
|
151
|
-
override isNode(exemplar: BTNodeExemplar<V, N>): exemplar is N {
|
|
153
|
+
override isNode(exemplar: BTNodeExemplar<K, V, N>): exemplar is N {
|
|
152
154
|
return exemplar instanceof BSTNode;
|
|
153
155
|
}
|
|
154
156
|
|
|
157
|
+
|
|
155
158
|
/**
|
|
156
|
-
* The function `exemplarToNode` takes an exemplar and returns a
|
|
157
|
-
*
|
|
158
|
-
* @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<V, N
|
|
159
|
-
* @
|
|
159
|
+
* The function `exemplarToNode` takes an exemplar and returns a node if the exemplar is valid,
|
|
160
|
+
* otherwise it returns undefined.
|
|
161
|
+
* @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<K, V, N>`, where:
|
|
162
|
+
* @param {V} [value] - The `value` parameter is an optional value that can be passed to the
|
|
163
|
+
* `exemplarToNode` function. It represents the value associated with the exemplar node.
|
|
164
|
+
* @returns a node of type N or undefined.
|
|
160
165
|
*/
|
|
161
|
-
override exemplarToNode(exemplar: BTNodeExemplar<V, N
|
|
166
|
+
override exemplarToNode(exemplar: BTNodeExemplar<K, V, N>, value?: V): N | undefined {
|
|
162
167
|
let node: N | undefined;
|
|
163
168
|
if (exemplar === null || exemplar === undefined) {
|
|
164
169
|
return;
|
|
@@ -171,8 +176,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
171
176
|
} else {
|
|
172
177
|
node = this.createNode(key, value);
|
|
173
178
|
}
|
|
174
|
-
} else if (this.
|
|
175
|
-
node = this.createNode(exemplar);
|
|
179
|
+
} else if (this.isNotNodeInstance(exemplar)) {
|
|
180
|
+
node = this.createNode(exemplar, value);
|
|
176
181
|
} else {
|
|
177
182
|
return;
|
|
178
183
|
}
|
|
@@ -188,14 +193,16 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
188
193
|
* Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n).
|
|
189
194
|
* Space Complexity: O(1) - Constant space is used.
|
|
190
195
|
*
|
|
191
|
-
* The `add` function adds a new node to a binary
|
|
192
|
-
*
|
|
193
|
-
* @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can
|
|
194
|
-
* @
|
|
195
|
-
*
|
|
196
|
+
* The `add` function adds a new node to a binary tree, updating the value if the key already exists
|
|
197
|
+
* or inserting a new node if the key is unique.
|
|
198
|
+
* @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can accept three types of values:
|
|
199
|
+
* @param {V} [value] - The `value` parameter represents the value associated with the key that is
|
|
200
|
+
* being added to the binary tree.
|
|
201
|
+
* @returns The method `add` returns either the newly added node (`newNode`) or `undefined` if the
|
|
202
|
+
* node was not added.
|
|
196
203
|
*/
|
|
197
|
-
override add(keyOrNodeOrEntry: BTNodeExemplar<V, N
|
|
198
|
-
const newNode = this.exemplarToNode(keyOrNodeOrEntry);
|
|
204
|
+
override add(keyOrNodeOrEntry: BTNodeExemplar<K, V, N>, value?: V): N | undefined {
|
|
205
|
+
const newNode = this.exemplarToNode(keyOrNodeOrEntry, value);
|
|
199
206
|
if (newNode === undefined) return;
|
|
200
207
|
|
|
201
208
|
if (this.root === undefined) {
|
|
@@ -249,34 +256,48 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
249
256
|
* Time Complexity: O(k log n) - Adding each element individually in a balanced tree.
|
|
250
257
|
* Space Complexity: O(k) - Additional space is required for the sorted array.
|
|
251
258
|
*
|
|
252
|
-
* The `addMany` function in TypeScript adds multiple nodes to a binary tree,
|
|
253
|
-
*
|
|
254
|
-
* @param keysOrNodesOrEntries - An iterable containing keys, nodes, or entries to be added to
|
|
255
|
-
* binary tree.
|
|
256
|
-
* @param [
|
|
257
|
-
*
|
|
259
|
+
* The `addMany` function in TypeScript adds multiple keys or nodes to a binary tree, optionally
|
|
260
|
+
* balancing the tree after each addition.
|
|
261
|
+
* @param keysOrNodesOrEntries - An iterable containing the keys, nodes, or entries to be added to
|
|
262
|
+
* the binary tree.
|
|
263
|
+
* @param [values] - An optional iterable of values to be associated with the keys or nodes being
|
|
264
|
+
* added. If provided, the values will be assigned to the corresponding keys or nodes in the same
|
|
265
|
+
* order. If not provided, undefined will be assigned as the value for each key or node.
|
|
266
|
+
* @param [isBalanceAdd=true] - A boolean flag indicating whether the add operation should be
|
|
267
|
+
* balanced or not. If set to true, the add operation will be balanced using a binary search tree
|
|
268
|
+
* algorithm. If set to false, the add operation will not be balanced and the elements will be added
|
|
269
|
+
* in the order they appear in the input.
|
|
258
270
|
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
259
|
-
* type of iteration to use when adding multiple keys or nodes
|
|
260
|
-
*
|
|
261
|
-
*
|
|
262
|
-
* @returns The `addMany` function returns an array of `N` or `undefined` values.
|
|
271
|
+
* type of iteration to use when adding multiple keys or nodes. It has a default value of
|
|
272
|
+
* `this.iterationType`, which suggests that it is a property of the current object.
|
|
273
|
+
* @returns The function `addMany` returns an array of nodes (`N`) or `undefined` values.
|
|
263
274
|
*/
|
|
264
275
|
override addMany(
|
|
265
|
-
keysOrNodesOrEntries: Iterable<BTNodeExemplar<V, N>>,
|
|
276
|
+
keysOrNodesOrEntries: Iterable<BTNodeExemplar<K, V, N>>,
|
|
277
|
+
values?: Iterable<V | undefined>,
|
|
266
278
|
isBalanceAdd = true,
|
|
267
279
|
iterationType = this.iterationType
|
|
268
280
|
): (N | undefined)[] {
|
|
269
|
-
const inserted: (N | undefined)[] = []
|
|
281
|
+
const inserted: (N | undefined)[] = [];
|
|
282
|
+
|
|
283
|
+
let valuesIterator: Iterator<V | undefined> | undefined;
|
|
284
|
+
|
|
285
|
+
if (values) {
|
|
286
|
+
valuesIterator = values[Symbol.iterator]();
|
|
287
|
+
}
|
|
288
|
+
|
|
270
289
|
if (!isBalanceAdd) {
|
|
271
290
|
for (const kve of keysOrNodesOrEntries) {
|
|
272
|
-
const
|
|
291
|
+
const value = valuesIterator?.next().value;
|
|
292
|
+
const nn = this.add(kve, value);
|
|
273
293
|
inserted.push(nn);
|
|
274
294
|
}
|
|
275
295
|
return inserted;
|
|
276
296
|
}
|
|
277
|
-
const realBTNExemplars: BTNodePureExemplar<V, N>[] = [];
|
|
278
297
|
|
|
279
|
-
const
|
|
298
|
+
const realBTNExemplars: BTNodePureExemplar<K, V, N>[] = [];
|
|
299
|
+
|
|
300
|
+
const isRealBTNExemplar = (kve: BTNodeExemplar<K, V, N>): kve is BTNodePureExemplar<K, V, N> => {
|
|
280
301
|
if (kve === undefined || kve === null) return false;
|
|
281
302
|
return !(this.isEntry(kve) && (kve[0] === undefined || kve[0] === null));
|
|
282
303
|
}
|
|
@@ -285,24 +306,22 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
285
306
|
isRealBTNExemplar(kve) && realBTNExemplars.push(kve);
|
|
286
307
|
}
|
|
287
308
|
|
|
288
|
-
|
|
289
|
-
let sorted: BTNodePureExemplar<V, N>[] = [];
|
|
309
|
+
let sorted: BTNodePureExemplar<K, V, N>[] = [];
|
|
290
310
|
|
|
291
311
|
sorted = realBTNExemplars.sort((a, b) => {
|
|
292
312
|
let aR: number, bR: number;
|
|
293
|
-
if (this.isEntry(a)) aR = a[0]
|
|
294
|
-
else if (this.isRealNode(a)) aR = a.key
|
|
295
|
-
else aR = a;
|
|
313
|
+
if (this.isEntry(a)) aR = this.extractor(a[0]);
|
|
314
|
+
else if (this.isRealNode(a)) aR = this.extractor(a.key);
|
|
315
|
+
else aR = this.extractor(a);
|
|
296
316
|
|
|
297
|
-
if (this.isEntry(b)) bR = b[0]
|
|
298
|
-
else if (this.isRealNode(b)) bR = b.key
|
|
299
|
-
else bR = b;
|
|
317
|
+
if (this.isEntry(b)) bR = this.extractor(b[0]);
|
|
318
|
+
else if (this.isRealNode(b)) bR = this.extractor(b.key);
|
|
319
|
+
else bR = this.extractor(b);
|
|
300
320
|
|
|
301
321
|
return aR - bR;
|
|
302
|
-
})
|
|
303
|
-
|
|
322
|
+
});
|
|
304
323
|
|
|
305
|
-
const _dfs = (arr: BTNodePureExemplar<V, N>[]) => {
|
|
324
|
+
const _dfs = (arr: BTNodePureExemplar<K, V, N>[]) => {
|
|
306
325
|
if (arr.length === 0) return;
|
|
307
326
|
|
|
308
327
|
const mid = Math.floor((arr.length - 1) / 2);
|
|
@@ -311,6 +330,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
311
330
|
_dfs(arr.slice(0, mid));
|
|
312
331
|
_dfs(arr.slice(mid + 1));
|
|
313
332
|
};
|
|
333
|
+
|
|
314
334
|
const _iterate = () => {
|
|
315
335
|
const n = sorted.length;
|
|
316
336
|
const stack: [[number, number]] = [[0, n - 1]];
|
|
@@ -328,6 +348,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
328
348
|
}
|
|
329
349
|
}
|
|
330
350
|
};
|
|
351
|
+
|
|
331
352
|
if (iterationType === IterationType.RECURSIVE) {
|
|
332
353
|
_dfs(sorted);
|
|
333
354
|
} else {
|
|
@@ -337,6 +358,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
337
358
|
return inserted;
|
|
338
359
|
}
|
|
339
360
|
|
|
361
|
+
|
|
340
362
|
/**
|
|
341
363
|
* Time Complexity: O(n log n) - Adding each element individually in a balanced tree.
|
|
342
364
|
* Space Complexity: O(n) - Additional space is required for the sorted array.
|
|
@@ -348,8 +370,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
348
370
|
*
|
|
349
371
|
* The `lastKey` function returns the key of the rightmost node in a binary tree, or the key of the
|
|
350
372
|
* leftmost node if the comparison result is greater than.
|
|
351
|
-
* @param {
|
|
352
|
-
* type `
|
|
373
|
+
* @param {K | N | undefined} beginRoot - The `beginRoot` parameter is optional and can be of
|
|
374
|
+
* type `K`, `N`, or `undefined`. It represents the starting point for finding the last key in
|
|
353
375
|
* the binary tree. If not provided, it defaults to the root of the binary tree (`this.root`).
|
|
354
376
|
* @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
|
|
355
377
|
* be performed. It can have one of the following values:
|
|
@@ -357,12 +379,25 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
357
379
|
* the key of the leftmost node if the comparison result is greater than, and the key of the
|
|
358
380
|
* rightmost node otherwise. If no node is found, it returns 0.
|
|
359
381
|
*/
|
|
360
|
-
lastKey(beginRoot: BSTNodeKeyOrNode<N> = this.root
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
382
|
+
lastKey(beginRoot: BSTNodeKeyOrNode<K, N> = this.root): K | undefined {
|
|
383
|
+
let current = this.ensureNode(beginRoot);
|
|
384
|
+
if (!current) return undefined;
|
|
385
|
+
|
|
386
|
+
if (this._variant === BSTVariant.MIN) {
|
|
387
|
+
// For BSTVariant.MIN, find the rightmost node
|
|
388
|
+
while (current.right !== undefined) {
|
|
389
|
+
current = current.right;
|
|
390
|
+
}
|
|
391
|
+
} else {
|
|
392
|
+
// For BSTVariant.MAX, find the leftmost node
|
|
393
|
+
while (current.left !== undefined) {
|
|
394
|
+
current = current.left;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return current.key;
|
|
364
398
|
}
|
|
365
399
|
|
|
400
|
+
|
|
366
401
|
/**
|
|
367
402
|
* Time Complexity: O(log n) - Average case for a balanced tree.
|
|
368
403
|
* Space Complexity: O(1) - Constant space is used.
|
|
@@ -374,7 +409,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
374
409
|
*
|
|
375
410
|
* The function `getNodeByKey` searches for a node in a binary tree based on a given key, using
|
|
376
411
|
* either recursive or iterative methods.
|
|
377
|
-
* @param {
|
|
412
|
+
* @param {K} key - The `key` parameter is the key value that we are searching for in the tree.
|
|
378
413
|
* It is used to identify the node that we want to retrieve.
|
|
379
414
|
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
380
415
|
* type of iteration to use when searching for a node in the binary tree. It can have two possible
|
|
@@ -382,7 +417,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
382
417
|
* @returns The function `getNodeByKey` returns a node (`N`) if a node with the specified key is
|
|
383
418
|
* found in the binary tree. If no node is found, it returns `undefined`.
|
|
384
419
|
*/
|
|
385
|
-
override getNodeByKey(key:
|
|
420
|
+
override getNodeByKey(key: K, iterationType = IterationType.ITERATIVE): N | undefined {
|
|
386
421
|
if (!this.root) return undefined;
|
|
387
422
|
if (iterationType === IterationType.RECURSIVE) {
|
|
388
423
|
const _dfs = (cur: N): N | undefined => {
|
|
@@ -407,6 +442,16 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
407
442
|
}
|
|
408
443
|
}
|
|
409
444
|
|
|
445
|
+
/**
|
|
446
|
+
* The function "isNotNodeInstance" checks if a potential key is a K.
|
|
447
|
+
* @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any
|
|
448
|
+
* data type.
|
|
449
|
+
* @returns a boolean value indicating whether the potentialKey is of type number or not.
|
|
450
|
+
*/
|
|
451
|
+
override isNotNodeInstance(potentialKey: BTNodeKeyOrNode<K, N>): potentialKey is K {
|
|
452
|
+
return !(potentialKey instanceof BSTNode)
|
|
453
|
+
}
|
|
454
|
+
|
|
410
455
|
/**
|
|
411
456
|
* Time Complexity: O(log n) - Average case for a balanced tree.
|
|
412
457
|
* Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
|
|
@@ -415,14 +460,14 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
415
460
|
/**
|
|
416
461
|
* The function `ensureNode` returns the node corresponding to the given key if it is a node key,
|
|
417
462
|
* otherwise it returns the key itself.
|
|
418
|
-
* @param {
|
|
463
|
+
* @param {K | N | undefined} key - The `key` parameter can be of type `K`, `N`, or
|
|
419
464
|
* `undefined`.
|
|
420
465
|
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
421
466
|
* type of iteration to be performed. It has a default value of `IterationType.ITERATIVE`.
|
|
422
467
|
* @returns either a node object (N) or undefined.
|
|
423
468
|
*/
|
|
424
|
-
override ensureNode(key: BSTNodeKeyOrNode<N>, iterationType = IterationType.ITERATIVE): N | undefined {
|
|
425
|
-
return this.
|
|
469
|
+
override ensureNode(key: BSTNodeKeyOrNode<K, N>, iterationType = IterationType.ITERATIVE): N | undefined {
|
|
470
|
+
return this.isNotNodeInstance(key) ? this.getNodeByKey(key, iterationType) : key;
|
|
426
471
|
}
|
|
427
472
|
|
|
428
473
|
/**
|
|
@@ -441,7 +486,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
441
486
|
* first node that matches the identifier. If set to true, the function will return an array
|
|
442
487
|
* containing only the first matching node. If set to false (default), the function will continue
|
|
443
488
|
* searching for all nodes that match the identifier and return an array containing
|
|
444
|
-
* @param {
|
|
489
|
+
* @param {K | N | undefined} beginRoot - The `beginRoot` parameter represents the starting node
|
|
445
490
|
* for the traversal. It can be either a key value or a node object. If it is undefined, the
|
|
446
491
|
* traversal will start from the root of the tree.
|
|
447
492
|
* @param iterationType - The `iterationType` parameter determines the type of iteration to be
|
|
@@ -452,7 +497,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
452
497
|
identifier: ReturnType<C> | undefined,
|
|
453
498
|
callback: C = this._defaultOneParamCallback as C,
|
|
454
499
|
onlyOne = false,
|
|
455
|
-
beginRoot: BSTNodeKeyOrNode<N> = this.root,
|
|
500
|
+
beginRoot: BSTNodeKeyOrNode<K, N> = this.root,
|
|
456
501
|
iterationType = this.iterationType
|
|
457
502
|
): N[] {
|
|
458
503
|
beginRoot = this.ensureNode(beginRoot);
|
|
@@ -470,8 +515,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
470
515
|
if (!cur.left && !cur.right) return;
|
|
471
516
|
// TODO potential bug
|
|
472
517
|
if (callback === this._defaultOneParamCallback) {
|
|
473
|
-
if (this._compare(cur.key, identifier as
|
|
474
|
-
if (this._compare(cur.key, identifier as
|
|
518
|
+
if (this._compare(cur.key, identifier as K) === CP.gt) cur.left && _traverse(cur.left);
|
|
519
|
+
if (this._compare(cur.key, identifier as K) === CP.lt) cur.right && _traverse(cur.right);
|
|
475
520
|
} else {
|
|
476
521
|
cur.left && _traverse(cur.left);
|
|
477
522
|
cur.right && _traverse(cur.right);
|
|
@@ -491,8 +536,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
491
536
|
}
|
|
492
537
|
// TODO potential bug
|
|
493
538
|
if (callback === this._defaultOneParamCallback) {
|
|
494
|
-
if (this._compare(cur.key, identifier as
|
|
495
|
-
if (this._compare(cur.key, identifier as
|
|
539
|
+
if (this._compare(cur.key, identifier as K) === CP.gt) cur.left && queue.push(cur.left);
|
|
540
|
+
if (this._compare(cur.key, identifier as K) === CP.lt) cur.right && queue.push(cur.right);
|
|
496
541
|
} else {
|
|
497
542
|
cur.left && queue.push(cur.left);
|
|
498
543
|
cur.right && queue.push(cur.right);
|
|
@@ -522,7 +567,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
522
567
|
* traverse nodes that are lesser than, greater than, or equal to the `targetNode`. It is of type
|
|
523
568
|
* `CP`, which is a custom type representing the comparison operator. The possible values for
|
|
524
569
|
* `lesserOrGreater` are
|
|
525
|
-
* @param {
|
|
570
|
+
* @param {K | N | undefined} targetNode - The `targetNode` parameter represents the node in the
|
|
526
571
|
* binary tree that you want to traverse from. It can be specified either by its key, by the node
|
|
527
572
|
* object itself, or it can be left undefined to start the traversal from the root of the tree.
|
|
528
573
|
* @param iterationType - The `iterationType` parameter determines the type of traversal to be
|
|
@@ -533,7 +578,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
533
578
|
lesserOrGreaterTraverse<C extends BTNCallback<N>>(
|
|
534
579
|
callback: C = this._defaultOneParamCallback as C,
|
|
535
580
|
lesserOrGreater: CP = CP.lt,
|
|
536
|
-
targetNode: BSTNodeKeyOrNode<N> = this.root,
|
|
581
|
+
targetNode: BSTNodeKeyOrNode<K, N> = this.root,
|
|
537
582
|
iterationType = this.iterationType
|
|
538
583
|
): ReturnType<C>[] {
|
|
539
584
|
targetNode = this.ensureNode(targetNode);
|
|
@@ -614,7 +659,6 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
614
659
|
if (l <= r) {
|
|
615
660
|
const m = l + Math.floor((r - l) / 2);
|
|
616
661
|
const midNode = sorted[m];
|
|
617
|
-
debugger;
|
|
618
662
|
this.add([midNode.key, midNode.value]);
|
|
619
663
|
stack.push([m + 1, r]);
|
|
620
664
|
stack.push([l, m - 1]);
|
|
@@ -704,15 +748,17 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
704
748
|
/**
|
|
705
749
|
* The function compares two values using a comparator function and returns whether the first value
|
|
706
750
|
* is greater than, less than, or equal to the second value.
|
|
707
|
-
* @param {
|
|
708
|
-
* @param {
|
|
751
|
+
* @param {K} a - The parameter "a" is of type K.
|
|
752
|
+
* @param {K} b - The parameter "b" in the above code represents a K.
|
|
709
753
|
* @returns a value of type CP (ComparisonResult). The possible return values are CP.gt (greater
|
|
710
754
|
* than), CP.lt (less than), or CP.eq (equal).
|
|
711
755
|
*/
|
|
712
|
-
protected _compare(a:
|
|
713
|
-
const
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
756
|
+
protected _compare(a: K, b: K): CP {
|
|
757
|
+
const extractedA = this.extractor(a);
|
|
758
|
+
const extractedB = this.extractor(b);
|
|
759
|
+
const compared = this.variant === BSTVariant.MIN ? extractedA - extractedB : extractedB - extractedA;
|
|
760
|
+
|
|
761
|
+
return compared > 0 ? CP.gt : compared < 0 ? CP.lt : CP.eq;
|
|
717
762
|
}
|
|
763
|
+
|
|
718
764
|
}
|