data-structure-typed 1.42.6 → 1.42.8
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/CHANGELOG.md +1 -1
- package/README.md +123 -123
- package/benchmark/report.html +12 -12
- package/benchmark/report.json +101 -101
- package/dist/cjs/src/data-structures/binary-tree/avl-tree.d.ts +5 -5
- package/dist/cjs/src/data-structures/binary-tree/avl-tree.js +19 -14
- package/dist/cjs/src/data-structures/binary-tree/avl-tree.js.map +1 -1
- package/dist/cjs/src/data-structures/binary-tree/binary-tree.d.ts +108 -60
- package/dist/cjs/src/data-structures/binary-tree/binary-tree.js +189 -89
- package/dist/cjs/src/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/src/data-structures/binary-tree/bst.d.ts +30 -8
- package/dist/cjs/src/data-structures/binary-tree/bst.js +77 -28
- package/dist/cjs/src/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/cjs/src/data-structures/binary-tree/rb-tree.d.ts +35 -28
- package/dist/cjs/src/data-structures/binary-tree/rb-tree.js +44 -45
- package/dist/cjs/src/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/cjs/src/data-structures/binary-tree/tree-multimap.d.ts +7 -12
- package/dist/cjs/src/data-structures/binary-tree/tree-multimap.js +38 -37
- package/dist/cjs/src/data-structures/binary-tree/tree-multimap.js.map +1 -1
- package/dist/cjs/src/interfaces/binary-tree.d.ts +2 -2
- package/dist/cjs/src/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/cjs/src/types/data-structures/binary-tree/binary-tree.js +6 -0
- package/dist/cjs/src/types/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/src/types/data-structures/binary-tree/rb-tree.d.ts +2 -2
- package/dist/mjs/src/data-structures/binary-tree/avl-tree.d.ts +5 -5
- package/dist/mjs/src/data-structures/binary-tree/avl-tree.js +19 -14
- package/dist/mjs/src/data-structures/binary-tree/binary-tree.d.ts +108 -60
- package/dist/mjs/src/data-structures/binary-tree/binary-tree.js +191 -89
- package/dist/mjs/src/data-structures/binary-tree/bst.d.ts +30 -8
- package/dist/mjs/src/data-structures/binary-tree/bst.js +78 -27
- package/dist/mjs/src/data-structures/binary-tree/rb-tree.d.ts +35 -28
- package/dist/mjs/src/data-structures/binary-tree/rb-tree.js +43 -45
- package/dist/mjs/src/data-structures/binary-tree/tree-multimap.d.ts +7 -12
- package/dist/mjs/src/data-structures/binary-tree/tree-multimap.js +38 -37
- package/dist/mjs/src/interfaces/binary-tree.d.ts +2 -2
- package/dist/mjs/src/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/mjs/src/types/data-structures/binary-tree/binary-tree.js +6 -0
- package/dist/mjs/src/types/data-structures/binary-tree/rb-tree.d.ts +2 -2
- package/dist/umd/data-structure-typed.min.js +1 -1
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +1 -1
- package/src/data-structures/binary-tree/avl-tree.ts +24 -18
- package/src/data-structures/binary-tree/binary-tree.ts +248 -142
- package/src/data-structures/binary-tree/bst.ts +88 -38
- package/src/data-structures/binary-tree/rb-tree.ts +52 -58
- package/src/data-structures/binary-tree/tree-multimap.ts +50 -54
- package/src/interfaces/binary-tree.ts +2 -2
- package/src/types/data-structures/binary-tree/binary-tree.ts +7 -1
- package/src/types/data-structures/binary-tree/rb-tree.ts +2 -2
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +9 -9
|
@@ -10,9 +10,9 @@ import { CP, IterationType } from '../../types';
|
|
|
10
10
|
import { BinaryTree, BinaryTreeNode } from './binary-tree';
|
|
11
11
|
import { IBinaryTree } from '../../interfaces';
|
|
12
12
|
export declare class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extends BinaryTreeNode<V, N> {
|
|
13
|
-
parent
|
|
13
|
+
parent?: N;
|
|
14
14
|
constructor(key: BTNKey, value?: V);
|
|
15
|
-
protected _left
|
|
15
|
+
protected _left?: N;
|
|
16
16
|
/**
|
|
17
17
|
* Get the left child node.
|
|
18
18
|
*/
|
|
@@ -22,7 +22,7 @@ export declare class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>
|
|
|
22
22
|
* @param {N | undefined} v - The left child node.
|
|
23
23
|
*/
|
|
24
24
|
set left(v: N | undefined);
|
|
25
|
-
protected _right
|
|
25
|
+
protected _right?: N;
|
|
26
26
|
/**
|
|
27
27
|
* Get the right child node.
|
|
28
28
|
*/
|
|
@@ -41,7 +41,7 @@ export declare class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNe
|
|
|
41
41
|
* binary search tree.
|
|
42
42
|
*/
|
|
43
43
|
constructor(options?: BSTOptions);
|
|
44
|
-
protected _root
|
|
44
|
+
protected _root?: N;
|
|
45
45
|
/**
|
|
46
46
|
* Get the root node of the binary tree.
|
|
47
47
|
*/
|
|
@@ -79,7 +79,7 @@ export declare class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNe
|
|
|
79
79
|
* It can have two possible values:
|
|
80
80
|
* @returns The `addMany` function returns an array of `N`, `undefined`, or `undefined` values.
|
|
81
81
|
*/
|
|
82
|
-
addMany(keysOrNodes: (BTNKey |
|
|
82
|
+
addMany(keysOrNodes: (BTNKey | N | undefined)[], data?: (V | undefined)[], isBalanceAdd?: boolean, iterationType?: IterationType): (N | undefined)[];
|
|
83
83
|
/**
|
|
84
84
|
* The function `lastKey` returns the key of the rightmost node if the comparison result is less
|
|
85
85
|
* than, the key of the leftmost node if the comparison result is greater than, and the key of the
|
|
@@ -95,7 +95,29 @@ export declare class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNe
|
|
|
95
95
|
* the key of the leftmost node if the comparison result is greater than, and the key of the
|
|
96
96
|
* rightmost node otherwise. If no node is found, it returns 0.
|
|
97
97
|
*/
|
|
98
|
-
lastKey(beginRoot?: N | undefined, iterationType?: IterationType): BTNKey;
|
|
98
|
+
lastKey(beginRoot?: BTNKey | N | undefined, iterationType?: IterationType): BTNKey;
|
|
99
|
+
/**
|
|
100
|
+
* The function `getNodeByKey` searches for a node in a binary tree based on a given key, using
|
|
101
|
+
* either recursive or iterative methods.
|
|
102
|
+
* @param {BTNKey} key - The `key` parameter is the key value that we are searching for in the tree.
|
|
103
|
+
* It is used to find the node with the matching key value.
|
|
104
|
+
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
105
|
+
* type of iteration to use when searching for a node in the binary tree. It can have two possible
|
|
106
|
+
* values:
|
|
107
|
+
* @returns The function `getNodeByKey` returns a node (`N`) if a node with the specified key is
|
|
108
|
+
* found in the binary tree. If no node is found, it returns `undefined`.
|
|
109
|
+
*/
|
|
110
|
+
getNodeByKey(key: BTNKey, iterationType?: IterationType): N | undefined;
|
|
111
|
+
/**
|
|
112
|
+
* The function `ensureNotKey` returns the node corresponding to the given key if it is a node key,
|
|
113
|
+
* otherwise it returns the key itself.
|
|
114
|
+
* @param {BTNKey | N | undefined} key - The `key` parameter can be of type `BTNKey`, `N`, or
|
|
115
|
+
* `undefined`.
|
|
116
|
+
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
117
|
+
* type of iteration to be performed. It has a default value of `IterationType.ITERATIVE`.
|
|
118
|
+
* @returns either a node object (N) or undefined.
|
|
119
|
+
*/
|
|
120
|
+
ensureNotKey(key: BTNKey | N | undefined, iterationType?: IterationType): N | undefined;
|
|
99
121
|
/**
|
|
100
122
|
* The function `getNodes` retrieves nodes from a binary tree based on a given node property or key,
|
|
101
123
|
* using either recursive or iterative traversal.
|
|
@@ -104,7 +126,7 @@ export declare class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNe
|
|
|
104
126
|
* generic type `N`.
|
|
105
127
|
* @param callback - The `callback` parameter is a function that takes a node as input and returns a
|
|
106
128
|
* value. This value is compared with the `nodeProperty` parameter to determine if the node should be
|
|
107
|
-
* included in the result. The default value for `callback` is `this.
|
|
129
|
+
* included in the result. The default value for `callback` is `this._defaultOneParamCallback`, which is
|
|
108
130
|
* a
|
|
109
131
|
* @param [onlyOne=false] - A boolean value indicating whether to stop the traversal after finding
|
|
110
132
|
* the first node that matches the nodeProperty. If set to true, the function will return an array
|
|
@@ -117,7 +139,7 @@ export declare class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNe
|
|
|
117
139
|
* traverse the binary tree. It can have one of the following values:
|
|
118
140
|
* @returns an array of nodes (N[]).
|
|
119
141
|
*/
|
|
120
|
-
getNodes<C extends BTNCallback<N>>(identifier: ReturnType<C> | undefined, callback?: C, onlyOne?: boolean, beginRoot?: N | undefined, iterationType?: IterationType): N[];
|
|
142
|
+
getNodes<C extends BTNCallback<N>>(identifier: ReturnType<C> | undefined, callback?: C, onlyOne?: boolean, beginRoot?: BTNKey | N | undefined, iterationType?: IterationType): N[];
|
|
121
143
|
/**
|
|
122
144
|
* The `lesserOrGreaterTraverse` function traverses a binary tree and applies a callback function to
|
|
123
145
|
* nodes that have a key value lesser or greater than a target key value.
|
|
@@ -65,7 +65,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
-
_root
|
|
68
|
+
_root;
|
|
69
69
|
/**
|
|
70
70
|
* Get the root node of the binary tree.
|
|
71
71
|
*/
|
|
@@ -94,9 +94,6 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
94
94
|
* was not added or if the parameters were invalid, it returns undefined or undefined.
|
|
95
95
|
*/
|
|
96
96
|
add(keyOrNode, value) {
|
|
97
|
-
if (keyOrNode === 8) {
|
|
98
|
-
debugger;
|
|
99
|
-
}
|
|
100
97
|
if (keyOrNode === null)
|
|
101
98
|
return undefined;
|
|
102
99
|
// TODO support node as a parameter
|
|
@@ -105,7 +102,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
105
102
|
if (keyOrNode instanceof BSTNode) {
|
|
106
103
|
newNode = keyOrNode;
|
|
107
104
|
}
|
|
108
|
-
else if (
|
|
105
|
+
else if (this.isNodeKey(keyOrNode)) {
|
|
109
106
|
newNode = this.createNode(keyOrNode, value);
|
|
110
107
|
}
|
|
111
108
|
else {
|
|
@@ -188,32 +185,32 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
188
185
|
*/
|
|
189
186
|
addMany(keysOrNodes, data, isBalanceAdd = true, iterationType = this.iterationType) {
|
|
190
187
|
// TODO this addMany function is inefficient, it should be optimized
|
|
191
|
-
function
|
|
188
|
+
function hasNoUndefined(arr) {
|
|
192
189
|
return arr.indexOf(undefined) === -1;
|
|
193
190
|
}
|
|
194
|
-
if (!isBalanceAdd || !
|
|
191
|
+
if (!isBalanceAdd || !hasNoUndefined(keysOrNodes)) {
|
|
195
192
|
return super.addMany(keysOrNodes, data).map(n => n ?? undefined);
|
|
196
193
|
}
|
|
197
194
|
const inserted = [];
|
|
198
195
|
const combinedArr = keysOrNodes.map((value, index) => [value, data?.[index]]);
|
|
199
196
|
let sorted = [];
|
|
200
|
-
function
|
|
197
|
+
function _isNodeOrUndefinedTuple(arr) {
|
|
201
198
|
for (const [keyOrNode] of arr)
|
|
202
199
|
if (keyOrNode instanceof BSTNode)
|
|
203
200
|
return true;
|
|
204
201
|
return false;
|
|
205
202
|
}
|
|
206
|
-
|
|
203
|
+
const _isBinaryTreeKeyOrNullTuple = (arr) => {
|
|
207
204
|
for (const [keyOrNode] of arr)
|
|
208
|
-
if (
|
|
205
|
+
if (this.isNodeKey(keyOrNode))
|
|
209
206
|
return true;
|
|
210
207
|
return false;
|
|
211
|
-
}
|
|
208
|
+
};
|
|
212
209
|
let sortedKeysOrNodes = [], sortedData = [];
|
|
213
|
-
if (
|
|
210
|
+
if (_isNodeOrUndefinedTuple(combinedArr)) {
|
|
214
211
|
sorted = combinedArr.sort((a, b) => a[0].key - b[0].key);
|
|
215
212
|
}
|
|
216
|
-
else if (
|
|
213
|
+
else if (_isBinaryTreeKeyOrNullTuple(combinedArr)) {
|
|
217
214
|
sorted = combinedArr.sort((a, b) => a[0] - b[0]);
|
|
218
215
|
}
|
|
219
216
|
else {
|
|
@@ -221,16 +218,16 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
221
218
|
}
|
|
222
219
|
sortedKeysOrNodes = sorted.map(([keyOrNode]) => keyOrNode);
|
|
223
220
|
sortedData = sorted.map(([, value]) => value);
|
|
224
|
-
const
|
|
221
|
+
const _dfs = (arr, data) => {
|
|
225
222
|
if (arr.length === 0)
|
|
226
223
|
return;
|
|
227
224
|
const mid = Math.floor((arr.length - 1) / 2);
|
|
228
225
|
const newNode = this.add(arr[mid], data?.[mid]);
|
|
229
226
|
inserted.push(newNode);
|
|
230
|
-
|
|
231
|
-
|
|
227
|
+
_dfs(arr.slice(0, mid), data?.slice(0, mid));
|
|
228
|
+
_dfs(arr.slice(mid + 1), data?.slice(mid + 1));
|
|
232
229
|
};
|
|
233
|
-
const
|
|
230
|
+
const _iterate = () => {
|
|
234
231
|
const n = sorted.length;
|
|
235
232
|
const stack = [[0, n - 1]];
|
|
236
233
|
while (stack.length > 0) {
|
|
@@ -248,10 +245,10 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
248
245
|
}
|
|
249
246
|
};
|
|
250
247
|
if (iterationType === types_1.IterationType.RECURSIVE) {
|
|
251
|
-
|
|
248
|
+
_dfs(sortedKeysOrNodes, sortedData);
|
|
252
249
|
}
|
|
253
250
|
else {
|
|
254
|
-
|
|
251
|
+
_iterate();
|
|
255
252
|
}
|
|
256
253
|
return inserted;
|
|
257
254
|
}
|
|
@@ -278,6 +275,60 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
278
275
|
else
|
|
279
276
|
return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
|
|
280
277
|
}
|
|
278
|
+
/**
|
|
279
|
+
* The function `getNodeByKey` searches for a node in a binary tree based on a given key, using
|
|
280
|
+
* either recursive or iterative methods.
|
|
281
|
+
* @param {BTNKey} key - The `key` parameter is the key value that we are searching for in the tree.
|
|
282
|
+
* It is used to find the node with the matching key value.
|
|
283
|
+
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
284
|
+
* type of iteration to use when searching for a node in the binary tree. It can have two possible
|
|
285
|
+
* values:
|
|
286
|
+
* @returns The function `getNodeByKey` returns a node (`N`) if a node with the specified key is
|
|
287
|
+
* found in the binary tree. If no node is found, it returns `undefined`.
|
|
288
|
+
*/
|
|
289
|
+
getNodeByKey(key, iterationType = types_1.IterationType.ITERATIVE) {
|
|
290
|
+
if (!this.root)
|
|
291
|
+
return undefined;
|
|
292
|
+
if (iterationType === types_1.IterationType.RECURSIVE) {
|
|
293
|
+
const _dfs = (cur) => {
|
|
294
|
+
if (cur.key === key)
|
|
295
|
+
return cur;
|
|
296
|
+
if (!cur.left && !cur.right)
|
|
297
|
+
return;
|
|
298
|
+
if (this._compare(cur.key, key) === types_1.CP.gt && cur.left)
|
|
299
|
+
return _dfs(cur.left);
|
|
300
|
+
if (this._compare(cur.key, key) === types_1.CP.lt && cur.right)
|
|
301
|
+
return _dfs(cur.right);
|
|
302
|
+
};
|
|
303
|
+
return _dfs(this.root);
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
const queue = new queue_1.Queue([this.root]);
|
|
307
|
+
while (queue.size > 0) {
|
|
308
|
+
const cur = queue.shift();
|
|
309
|
+
if (cur) {
|
|
310
|
+
if (this._compare(cur.key, key) === types_1.CP.eq)
|
|
311
|
+
return cur;
|
|
312
|
+
if (this._compare(cur.key, key) === types_1.CP.gt)
|
|
313
|
+
cur.left && queue.push(cur.left);
|
|
314
|
+
if (this._compare(cur.key, key) === types_1.CP.lt)
|
|
315
|
+
cur.right && queue.push(cur.right);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* The function `ensureNotKey` returns the node corresponding to the given key if it is a node key,
|
|
322
|
+
* otherwise it returns the key itself.
|
|
323
|
+
* @param {BTNKey | N | undefined} key - The `key` parameter can be of type `BTNKey`, `N`, or
|
|
324
|
+
* `undefined`.
|
|
325
|
+
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
326
|
+
* type of iteration to be performed. It has a default value of `IterationType.ITERATIVE`.
|
|
327
|
+
* @returns either a node object (N) or undefined.
|
|
328
|
+
*/
|
|
329
|
+
ensureNotKey(key, iterationType = types_1.IterationType.ITERATIVE) {
|
|
330
|
+
return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key;
|
|
331
|
+
}
|
|
281
332
|
/**
|
|
282
333
|
* The function `getNodes` retrieves nodes from a binary tree based on a given node property or key,
|
|
283
334
|
* using either recursive or iterative traversal.
|
|
@@ -286,7 +337,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
286
337
|
* generic type `N`.
|
|
287
338
|
* @param callback - The `callback` parameter is a function that takes a node as input and returns a
|
|
288
339
|
* value. This value is compared with the `nodeProperty` parameter to determine if the node should be
|
|
289
|
-
* included in the result. The default value for `callback` is `this.
|
|
340
|
+
* included in the result. The default value for `callback` is `this._defaultOneParamCallback`, which is
|
|
290
341
|
* a
|
|
291
342
|
* @param [onlyOne=false] - A boolean value indicating whether to stop the traversal after finding
|
|
292
343
|
* the first node that matches the nodeProperty. If set to true, the function will return an array
|
|
@@ -299,7 +350,8 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
299
350
|
* traverse the binary tree. It can have one of the following values:
|
|
300
351
|
* @returns an array of nodes (N[]).
|
|
301
352
|
*/
|
|
302
|
-
getNodes(identifier, callback = this.
|
|
353
|
+
getNodes(identifier, callback = this._defaultOneParamCallback, onlyOne = false, beginRoot = this.root, iterationType = this.iterationType) {
|
|
354
|
+
beginRoot = this.ensureNotKey(beginRoot);
|
|
303
355
|
if (!beginRoot)
|
|
304
356
|
return [];
|
|
305
357
|
const ans = [];
|
|
@@ -314,7 +366,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
314
366
|
if (!cur.left && !cur.right)
|
|
315
367
|
return;
|
|
316
368
|
// TODO potential bug
|
|
317
|
-
if (callback === this.
|
|
369
|
+
if (callback === this._defaultOneParamCallback) {
|
|
318
370
|
if (this._compare(cur.key, identifier) === types_1.CP.gt)
|
|
319
371
|
cur.left && _traverse(cur.left);
|
|
320
372
|
if (this._compare(cur.key, identifier) === types_1.CP.lt)
|
|
@@ -339,7 +391,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
339
391
|
return ans;
|
|
340
392
|
}
|
|
341
393
|
// TODO potential bug
|
|
342
|
-
if (callback === this.
|
|
394
|
+
if (callback === this._defaultOneParamCallback) {
|
|
343
395
|
if (this._compare(cur.key, identifier) === types_1.CP.gt)
|
|
344
396
|
cur.left && queue.push(cur.left);
|
|
345
397
|
if (this._compare(cur.key, identifier) === types_1.CP.lt)
|
|
@@ -372,15 +424,14 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
372
424
|
* done recursively or iteratively. It can have two possible values:
|
|
373
425
|
* @returns The function `lesserOrGreaterTraverse` returns an array of `ReturnType<BTNCallback<N>>`.
|
|
374
426
|
*/
|
|
375
|
-
lesserOrGreaterTraverse(callback = this.
|
|
376
|
-
|
|
377
|
-
targetNode = this.getNode(targetNode) ?? undefined;
|
|
427
|
+
lesserOrGreaterTraverse(callback = this._defaultOneParamCallback, lesserOrGreater = types_1.CP.lt, targetNode = this.root, iterationType = this.iterationType) {
|
|
428
|
+
targetNode = this.ensureNotKey(targetNode);
|
|
378
429
|
const ans = [];
|
|
379
430
|
if (!targetNode)
|
|
380
431
|
return ans;
|
|
381
|
-
const targetKey = targetNode.key;
|
|
382
432
|
if (!this.root)
|
|
383
433
|
return ans;
|
|
434
|
+
const targetKey = targetNode.key;
|
|
384
435
|
if (iterationType === types_1.IterationType.RECURSIVE) {
|
|
385
436
|
const _traverse = (cur) => {
|
|
386
437
|
const compared = this._compare(cur.key, targetKey);
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
8
|
+
import { BiTreeDeleteResult, BTNCallback, BTNKey, IterationType, RBTNColor, RedBlackTreeNodeNested, RBTreeOptions } from '../../types';
|
|
9
9
|
import { BST, BSTNode } from "./bst";
|
|
10
10
|
import { IBinaryTree } from "../../interfaces";
|
|
11
|
-
export declare class
|
|
11
|
+
export declare class RedBlackTreeNode<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTreeNodeNested<V>> extends BSTNode<V, N> {
|
|
12
12
|
color: RBTNColor;
|
|
13
13
|
constructor(key: BTNKey, value?: V, color?: RBTNColor);
|
|
14
14
|
}
|
|
@@ -19,74 +19,81 @@ export declare class RBTreeNode<V = any, N extends RBTreeNode<V, N> = RBTreeNode
|
|
|
19
19
|
* 4. Red nodes must have black children.
|
|
20
20
|
* 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.
|
|
21
21
|
*/
|
|
22
|
-
export declare class RedBlackTree<V = any, N extends
|
|
22
|
+
export declare class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTreeNode<V, RedBlackTreeNodeNested<V>>> extends BST<V, N> implements IBinaryTree<V, N> {
|
|
23
23
|
constructor(options?: RBTreeOptions);
|
|
24
24
|
protected _root: N;
|
|
25
25
|
get root(): N;
|
|
26
26
|
protected _size: number;
|
|
27
27
|
get size(): number;
|
|
28
28
|
NIL: N;
|
|
29
|
+
/**
|
|
30
|
+
* The `add` function adds a new node to a Red-Black Tree data structure.
|
|
31
|
+
* @param {BTNKey | N | null | undefined} keyOrNode - The `keyOrNode` parameter can be one of the
|
|
32
|
+
* following types:
|
|
33
|
+
* @param {V} [value] - The `value` parameter is an optional value that can be associated with the
|
|
34
|
+
* key in the node being added to the Red-Black Tree.
|
|
35
|
+
* @returns The method returns either a node (`N`) or `undefined`.
|
|
36
|
+
*/
|
|
29
37
|
add(keyOrNode: BTNKey | N | null | undefined, value?: V): N | undefined;
|
|
30
38
|
createNode(key: BTNKey, value?: V, color?: RBTNColor): N;
|
|
31
|
-
|
|
32
|
-
|
|
39
|
+
/**
|
|
40
|
+
* The `delete` function removes a node from a binary tree based on a given identifier and updates
|
|
41
|
+
* the tree accordingly.
|
|
42
|
+
* @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
|
|
43
|
+
* that you want to use to identify the node that you want to delete from the binary tree. It can be
|
|
44
|
+
* of any type that is returned by the callback function `C`. It can also be `null` or `undefined` if
|
|
45
|
+
* you don't want to
|
|
46
|
+
* @param {C} callback - The `callback` parameter is a function that takes a node of type `N` and
|
|
47
|
+
* returns a value of type `ReturnType<C>`. It is used to determine if a node should be deleted based
|
|
48
|
+
* on its identifier. The `callback` function is optional and defaults to `this._defaultOneParam
|
|
49
|
+
* @returns an array of `BiTreeDeleteResult<N>`.
|
|
50
|
+
*/
|
|
51
|
+
delete<C extends BTNCallback<N>>(identifier: ReturnType<C> | null | undefined, callback?: C): BiTreeDeleteResult<N>[];
|
|
52
|
+
isRealNode(node: N | undefined): node is N;
|
|
33
53
|
getNode<C extends BTNCallback<N, BTNKey>>(identifier: BTNKey, callback?: C, beginRoot?: N | undefined, iterationType?: IterationType): N | undefined;
|
|
34
54
|
getNode<C extends BTNCallback<N, N>>(identifier: N | undefined, callback?: C, beginRoot?: N | undefined, iterationType?: IterationType): N | undefined;
|
|
35
55
|
getNode<C extends BTNCallback<N>>(identifier: ReturnType<C>, callback: C, beginRoot?: N | undefined, iterationType?: IterationType): N | undefined;
|
|
36
|
-
/**
|
|
37
|
-
* The function returns the leftmost node in a red-black tree.
|
|
38
|
-
* @param {RBTreeNode} node - The parameter "node" is of type RBTreeNode, which represents a node in
|
|
39
|
-
* a Red-Black Tree.
|
|
40
|
-
* @returns The leftmost node in the given RBTreeNode.
|
|
41
|
-
*/
|
|
42
|
-
getLeftMost(node?: N): N;
|
|
43
|
-
/**
|
|
44
|
-
* The function returns the rightmost node in a red-black tree.
|
|
45
|
-
* @param {RBTreeNode} node - The parameter "node" is of type RBTreeNode.
|
|
46
|
-
* @returns the rightmost node in a red-black tree.
|
|
47
|
-
*/
|
|
48
|
-
getRightMost(node: N): N;
|
|
49
56
|
/**
|
|
50
57
|
* The function returns the successor of a given node in a red-black tree.
|
|
51
|
-
* @param {
|
|
52
|
-
* @returns the successor of the given
|
|
58
|
+
* @param {RedBlackTreeNode} x - RedBlackTreeNode - The node for which we want to find the successor.
|
|
59
|
+
* @returns the successor of the given RedBlackTreeNode.
|
|
53
60
|
*/
|
|
54
61
|
getSuccessor(x: N): N | undefined;
|
|
55
62
|
/**
|
|
56
63
|
* The function returns the predecessor of a given node in a red-black tree.
|
|
57
|
-
* @param {
|
|
64
|
+
* @param {RedBlackTreeNode} x - The parameter `x` is of type `RedBlackTreeNode`, which represents a node in a
|
|
58
65
|
* Red-Black Tree.
|
|
59
|
-
* @returns the predecessor of the given
|
|
66
|
+
* @returns the predecessor of the given RedBlackTreeNode 'x'.
|
|
60
67
|
*/
|
|
61
68
|
getPredecessor(x: N): N;
|
|
62
69
|
clear(): void;
|
|
63
70
|
protected _setRoot(v: N): void;
|
|
64
71
|
/**
|
|
65
72
|
* The function performs a left rotation on a red-black tree node.
|
|
66
|
-
* @param {
|
|
73
|
+
* @param {RedBlackTreeNode} x - The parameter `x` is a RedBlackTreeNode object.
|
|
67
74
|
*/
|
|
68
75
|
protected _leftRotate(x: N): void;
|
|
69
76
|
/**
|
|
70
77
|
* The function performs a right rotation on a red-black tree node.
|
|
71
|
-
* @param {
|
|
78
|
+
* @param {RedBlackTreeNode} x - x is a RedBlackTreeNode, which represents the node that needs to be right
|
|
72
79
|
* rotated.
|
|
73
80
|
*/
|
|
74
81
|
protected _rightRotate(x: N): void;
|
|
75
82
|
/**
|
|
76
83
|
* The _fixDelete function is used to rebalance the Red-Black Tree after a node deletion.
|
|
77
|
-
* @param {
|
|
84
|
+
* @param {RedBlackTreeNode} x - The parameter `x` is of type `RedBlackTreeNode`, which represents a node in a
|
|
78
85
|
* red-black tree.
|
|
79
86
|
*/
|
|
80
87
|
protected _fixDelete(x: N): void;
|
|
81
88
|
/**
|
|
82
89
|
* The function `_rbTransplant` replaces one node in a red-black tree with another node.
|
|
83
|
-
* @param {
|
|
84
|
-
* @param {
|
|
90
|
+
* @param {RedBlackTreeNode} u - The parameter "u" represents a RedBlackTreeNode object.
|
|
91
|
+
* @param {RedBlackTreeNode} v - The parameter "v" is a RedBlackTreeNode object.
|
|
85
92
|
*/
|
|
86
93
|
protected _rbTransplant(u: N, v: N): void;
|
|
87
94
|
/**
|
|
88
95
|
* The `_fixInsert` function is used to fix the red-black tree after an insertion operation.
|
|
89
|
-
* @param {
|
|
96
|
+
* @param {RedBlackTreeNode} k - The parameter `k` is a RedBlackTreeNode object, which represents a node in a
|
|
90
97
|
* red-black tree.
|
|
91
98
|
*/
|
|
92
99
|
protected _fixInsert(k: N): void;
|
|
@@ -7,18 +7,18 @@
|
|
|
7
7
|
* @license MIT License
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.RedBlackTree = exports.
|
|
10
|
+
exports.RedBlackTree = exports.RedBlackTreeNode = void 0;
|
|
11
11
|
const types_1 = require("../../types");
|
|
12
12
|
const bst_1 = require("./bst");
|
|
13
13
|
const binary_tree_1 = require("./binary-tree");
|
|
14
|
-
class
|
|
14
|
+
class RedBlackTreeNode extends bst_1.BSTNode {
|
|
15
15
|
color;
|
|
16
16
|
constructor(key, value, color = types_1.RBTNColor.BLACK) {
|
|
17
17
|
super(key, value);
|
|
18
18
|
this.color = color;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
exports.
|
|
21
|
+
exports.RedBlackTreeNode = RedBlackTreeNode;
|
|
22
22
|
/**
|
|
23
23
|
* 1. Each node is either red or black.
|
|
24
24
|
* 2. The root node is always black.
|
|
@@ -39,13 +39,21 @@ class RedBlackTree extends bst_1.BST {
|
|
|
39
39
|
get size() {
|
|
40
40
|
return this._size;
|
|
41
41
|
}
|
|
42
|
-
NIL = new
|
|
42
|
+
NIL = new RedBlackTreeNode(NaN);
|
|
43
|
+
/**
|
|
44
|
+
* The `add` function adds a new node to a Red-Black Tree data structure.
|
|
45
|
+
* @param {BTNKey | N | null | undefined} keyOrNode - The `keyOrNode` parameter can be one of the
|
|
46
|
+
* following types:
|
|
47
|
+
* @param {V} [value] - The `value` parameter is an optional value that can be associated with the
|
|
48
|
+
* key in the node being added to the Red-Black Tree.
|
|
49
|
+
* @returns The method returns either a node (`N`) or `undefined`.
|
|
50
|
+
*/
|
|
43
51
|
add(keyOrNode, value) {
|
|
44
52
|
let node;
|
|
45
|
-
if (
|
|
53
|
+
if (this.isNodeKey(keyOrNode)) {
|
|
46
54
|
node = this.createNode(keyOrNode, value, types_1.RBTNColor.RED);
|
|
47
55
|
}
|
|
48
|
-
else if (keyOrNode instanceof
|
|
56
|
+
else if (keyOrNode instanceof RedBlackTreeNode) {
|
|
49
57
|
node = keyOrNode;
|
|
50
58
|
}
|
|
51
59
|
else if (keyOrNode === null) {
|
|
@@ -93,9 +101,21 @@ class RedBlackTree extends bst_1.BST {
|
|
|
93
101
|
this._size++;
|
|
94
102
|
}
|
|
95
103
|
createNode(key, value, color = types_1.RBTNColor.BLACK) {
|
|
96
|
-
return new
|
|
104
|
+
return new RedBlackTreeNode(key, value, color);
|
|
97
105
|
}
|
|
98
|
-
|
|
106
|
+
/**
|
|
107
|
+
* The `delete` function removes a node from a binary tree based on a given identifier and updates
|
|
108
|
+
* the tree accordingly.
|
|
109
|
+
* @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
|
|
110
|
+
* that you want to use to identify the node that you want to delete from the binary tree. It can be
|
|
111
|
+
* of any type that is returned by the callback function `C`. It can also be `null` or `undefined` if
|
|
112
|
+
* you don't want to
|
|
113
|
+
* @param {C} callback - The `callback` parameter is a function that takes a node of type `N` and
|
|
114
|
+
* returns a value of type `ReturnType<C>`. It is used to determine if a node should be deleted based
|
|
115
|
+
* on its identifier. The `callback` function is optional and defaults to `this._defaultOneParam
|
|
116
|
+
* @returns an array of `BiTreeDeleteResult<N>`.
|
|
117
|
+
*/
|
|
118
|
+
delete(identifier, callback = this._defaultOneParamCallback) {
|
|
99
119
|
const ans = [];
|
|
100
120
|
if (identifier === null)
|
|
101
121
|
return ans;
|
|
@@ -153,7 +173,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
153
173
|
// TODO
|
|
154
174
|
return ans;
|
|
155
175
|
}
|
|
156
|
-
|
|
176
|
+
isRealNode(node) {
|
|
157
177
|
return node !== this.NIL && node !== undefined;
|
|
158
178
|
}
|
|
159
179
|
/**
|
|
@@ -164,49 +184,27 @@ class RedBlackTree extends bst_1.BST {
|
|
|
164
184
|
* @param callback - The `callback` parameter is a function that is used to determine whether a node
|
|
165
185
|
* matches the desired criteria. It takes a node as input and returns a boolean value indicating
|
|
166
186
|
* whether the node matches the criteria or not. The default callback function
|
|
167
|
-
* (`this.
|
|
187
|
+
* (`this._defaultOneParamCallback`) is used if no callback function is
|
|
168
188
|
* @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
|
|
169
189
|
* the root node from which the search should begin.
|
|
170
190
|
* @param iterationType - The `iterationType` parameter specifies the type of iteration to be
|
|
171
191
|
* performed when searching for a node in the binary tree. It can have one of the following values:
|
|
172
192
|
* @returns either the found node (of type N) or null if no node is found.
|
|
173
193
|
*/
|
|
174
|
-
getNode(identifier, callback = this.
|
|
194
|
+
getNode(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
|
|
175
195
|
if (identifier instanceof binary_tree_1.BinaryTreeNode)
|
|
176
196
|
callback = (node => node);
|
|
197
|
+
beginRoot = this.ensureNotKey(beginRoot);
|
|
177
198
|
return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined;
|
|
178
199
|
}
|
|
179
|
-
/**
|
|
180
|
-
* The function returns the leftmost node in a red-black tree.
|
|
181
|
-
* @param {RBTreeNode} node - The parameter "node" is of type RBTreeNode, which represents a node in
|
|
182
|
-
* a Red-Black Tree.
|
|
183
|
-
* @returns The leftmost node in the given RBTreeNode.
|
|
184
|
-
*/
|
|
185
|
-
getLeftMost(node = this.root) {
|
|
186
|
-
while (node.left !== undefined && node.left !== this.NIL) {
|
|
187
|
-
node = node.left;
|
|
188
|
-
}
|
|
189
|
-
return node;
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* The function returns the rightmost node in a red-black tree.
|
|
193
|
-
* @param {RBTreeNode} node - The parameter "node" is of type RBTreeNode.
|
|
194
|
-
* @returns the rightmost node in a red-black tree.
|
|
195
|
-
*/
|
|
196
|
-
getRightMost(node) {
|
|
197
|
-
while (node.right !== undefined && node.right !== this.NIL) {
|
|
198
|
-
node = node.right;
|
|
199
|
-
}
|
|
200
|
-
return node;
|
|
201
|
-
}
|
|
202
200
|
/**
|
|
203
201
|
* The function returns the successor of a given node in a red-black tree.
|
|
204
|
-
* @param {
|
|
205
|
-
* @returns the successor of the given
|
|
202
|
+
* @param {RedBlackTreeNode} x - RedBlackTreeNode - The node for which we want to find the successor.
|
|
203
|
+
* @returns the successor of the given RedBlackTreeNode.
|
|
206
204
|
*/
|
|
207
205
|
getSuccessor(x) {
|
|
208
206
|
if (x.right !== this.NIL) {
|
|
209
|
-
return this.getLeftMost(x.right);
|
|
207
|
+
return this.getLeftMost(x.right) ?? undefined;
|
|
210
208
|
}
|
|
211
209
|
let y = x.parent;
|
|
212
210
|
while (y !== this.NIL && y !== undefined && x === y.right) {
|
|
@@ -217,9 +215,9 @@ class RedBlackTree extends bst_1.BST {
|
|
|
217
215
|
}
|
|
218
216
|
/**
|
|
219
217
|
* The function returns the predecessor of a given node in a red-black tree.
|
|
220
|
-
* @param {
|
|
218
|
+
* @param {RedBlackTreeNode} x - The parameter `x` is of type `RedBlackTreeNode`, which represents a node in a
|
|
221
219
|
* Red-Black Tree.
|
|
222
|
-
* @returns the predecessor of the given
|
|
220
|
+
* @returns the predecessor of the given RedBlackTreeNode 'x'.
|
|
223
221
|
*/
|
|
224
222
|
getPredecessor(x) {
|
|
225
223
|
if (x.left !== this.NIL) {
|
|
@@ -244,7 +242,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
244
242
|
}
|
|
245
243
|
/**
|
|
246
244
|
* The function performs a left rotation on a red-black tree node.
|
|
247
|
-
* @param {
|
|
245
|
+
* @param {RedBlackTreeNode} x - The parameter `x` is a RedBlackTreeNode object.
|
|
248
246
|
*/
|
|
249
247
|
_leftRotate(x) {
|
|
250
248
|
if (x.right) {
|
|
@@ -270,7 +268,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
270
268
|
}
|
|
271
269
|
/**
|
|
272
270
|
* The function performs a right rotation on a red-black tree node.
|
|
273
|
-
* @param {
|
|
271
|
+
* @param {RedBlackTreeNode} x - x is a RedBlackTreeNode, which represents the node that needs to be right
|
|
274
272
|
* rotated.
|
|
275
273
|
*/
|
|
276
274
|
_rightRotate(x) {
|
|
@@ -297,7 +295,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
297
295
|
}
|
|
298
296
|
/**
|
|
299
297
|
* The _fixDelete function is used to rebalance the Red-Black Tree after a node deletion.
|
|
300
|
-
* @param {
|
|
298
|
+
* @param {RedBlackTreeNode} x - The parameter `x` is of type `RedBlackTreeNode`, which represents a node in a
|
|
301
299
|
* red-black tree.
|
|
302
300
|
*/
|
|
303
301
|
_fixDelete(x) {
|
|
@@ -366,8 +364,8 @@ class RedBlackTree extends bst_1.BST {
|
|
|
366
364
|
}
|
|
367
365
|
/**
|
|
368
366
|
* The function `_rbTransplant` replaces one node in a red-black tree with another node.
|
|
369
|
-
* @param {
|
|
370
|
-
* @param {
|
|
367
|
+
* @param {RedBlackTreeNode} u - The parameter "u" represents a RedBlackTreeNode object.
|
|
368
|
+
* @param {RedBlackTreeNode} v - The parameter "v" is a RedBlackTreeNode object.
|
|
371
369
|
*/
|
|
372
370
|
_rbTransplant(u, v) {
|
|
373
371
|
if (u.parent === undefined) {
|
|
@@ -383,7 +381,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
383
381
|
}
|
|
384
382
|
/**
|
|
385
383
|
* The `_fixInsert` function is used to fix the red-black tree after an insertion operation.
|
|
386
|
-
* @param {
|
|
384
|
+
* @param {RedBlackTreeNode} k - The parameter `k` is a RedBlackTreeNode object, which represents a node in a
|
|
387
385
|
* red-black tree.
|
|
388
386
|
*/
|
|
389
387
|
_fixInsert(k) {
|