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