deque-typed 1.53.7 → 1.53.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/index.js +5 -0
- package/dist/data-structures/base/iterable-entry-base.js +4 -4
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +36 -17
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +65 -36
- package/dist/data-structures/binary-tree/avl-tree.d.ts +12 -8
- package/dist/data-structures/binary-tree/avl-tree.js +19 -6
- package/dist/data-structures/binary-tree/binary-tree.d.ts +53 -40
- package/dist/data-structures/binary-tree/binary-tree.js +76 -72
- package/dist/data-structures/binary-tree/bst.d.ts +87 -52
- package/dist/data-structures/binary-tree/bst.js +111 -63
- package/dist/data-structures/binary-tree/index.d.ts +1 -1
- package/dist/data-structures/binary-tree/index.js +1 -1
- package/dist/data-structures/binary-tree/{rb-tree.d.ts → red-black-tree.d.ts} +83 -10
- package/dist/data-structures/binary-tree/{rb-tree.js → red-black-tree.js} +91 -44
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +34 -18
- package/dist/data-structures/binary-tree/tree-multi-map.js +66 -40
- package/dist/data-structures/graph/abstract-graph.js +2 -2
- package/dist/data-structures/hash/hash-map.d.ts +31 -1
- package/dist/data-structures/hash/hash-map.js +35 -5
- package/dist/data-structures/heap/heap.d.ts +20 -3
- package/dist/data-structures/heap/heap.js +31 -11
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +46 -11
- package/dist/data-structures/linked-list/doubly-linked-list.js +68 -21
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +44 -11
- package/dist/data-structures/linked-list/singly-linked-list.js +70 -26
- package/dist/data-structures/queue/deque.d.ts +37 -8
- package/dist/data-structures/queue/deque.js +73 -29
- package/dist/data-structures/queue/queue.d.ts +41 -1
- package/dist/data-structures/queue/queue.js +51 -9
- package/dist/data-structures/stack/stack.d.ts +27 -10
- package/dist/data-structures/stack/stack.js +39 -20
- package/dist/data-structures/trie/trie.d.ts +8 -3
- package/dist/data-structures/trie/trie.js +8 -3
- package/dist/interfaces/binary-tree.d.ts +3 -4
- package/dist/types/data-structures/base/base.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +2 -3
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +2 -3
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +2 -3
- package/dist/types/data-structures/binary-tree/bst.d.ts +3 -4
- package/dist/types/data-structures/binary-tree/rb-tree.d.ts +4 -5
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +4 -5
- package/package.json +2 -2
- package/src/common/index.ts +7 -1
- package/src/data-structures/base/iterable-entry-base.ts +4 -4
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +82 -55
- package/src/data-structures/binary-tree/avl-tree.ts +32 -15
- package/src/data-structures/binary-tree/binary-tree.ts +89 -84
- package/src/data-structures/binary-tree/bst.ts +149 -97
- package/src/data-structures/binary-tree/index.ts +1 -1
- package/src/data-structures/binary-tree/{rb-tree.ts → red-black-tree.ts} +105 -55
- package/src/data-structures/binary-tree/tree-multi-map.ts +81 -51
- package/src/data-structures/graph/abstract-graph.ts +2 -2
- package/src/data-structures/hash/hash-map.ts +37 -7
- package/src/data-structures/heap/heap.ts +33 -10
- package/src/data-structures/linked-list/doubly-linked-list.ts +75 -21
- package/src/data-structures/linked-list/singly-linked-list.ts +77 -27
- package/src/data-structures/queue/deque.ts +72 -28
- package/src/data-structures/queue/queue.ts +50 -7
- package/src/data-structures/stack/stack.ts +39 -20
- package/src/data-structures/trie/trie.ts +8 -3
- package/src/interfaces/binary-tree.ts +3 -13
- package/src/types/data-structures/base/base.ts +1 -1
- package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +2 -4
- package/src/types/data-structures/binary-tree/avl-tree.ts +2 -4
- package/src/types/data-structures/binary-tree/binary-tree.ts +3 -3
- package/src/types/data-structures/binary-tree/bst.ts +3 -5
- package/src/types/data-structures/binary-tree/rb-tree.ts +4 -6
- package/src/types/data-structures/binary-tree/tree-multi-map.ts +4 -6
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
-
import
|
|
9
|
-
BSTNested,
|
|
8
|
+
import {
|
|
10
9
|
BSTNodeNested,
|
|
11
10
|
BSTNOptKeyOrNode,
|
|
12
11
|
BSTOptions,
|
|
@@ -15,6 +14,7 @@ import type {
|
|
|
15
14
|
Comparator,
|
|
16
15
|
CP,
|
|
17
16
|
DFSOrderPattern,
|
|
17
|
+
EntryCallback,
|
|
18
18
|
IterationType,
|
|
19
19
|
NodeCallback,
|
|
20
20
|
NodePredicate,
|
|
@@ -95,32 +95,48 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
|
|
|
95
95
|
* 6. Balance Variability: Can become unbalanced; special types maintain balance.
|
|
96
96
|
* 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.
|
|
97
97
|
* @example
|
|
98
|
-
* //
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
98
|
+
* // Merge 3 sorted datasets
|
|
99
|
+
* const dataset1 = new BST<number, string>([
|
|
100
|
+
* [1, 'A'],
|
|
101
|
+
* [7, 'G']
|
|
102
|
+
* ]);
|
|
103
|
+
* const dataset2 = [
|
|
104
|
+
* [2, 'B'],
|
|
105
|
+
* [6, 'F']
|
|
106
|
+
* ];
|
|
107
|
+
* const dataset3 = new BST<number, string>([
|
|
108
|
+
* [3, 'C'],
|
|
109
|
+
* [5, 'E'],
|
|
110
|
+
* [4, 'D']
|
|
111
|
+
* ]);
|
|
102
112
|
*
|
|
103
|
-
* //
|
|
104
|
-
* const
|
|
105
|
-
*
|
|
106
|
-
*
|
|
113
|
+
* // Merge datasets into a single BinarySearchTree
|
|
114
|
+
* const merged = new BST<number, string>(dataset1);
|
|
115
|
+
* merged.addMany(dataset2);
|
|
116
|
+
* merged.merge(dataset3);
|
|
107
117
|
*
|
|
108
|
-
* //
|
|
109
|
-
* console.log(
|
|
110
|
-
* console.log(findKthSmallest(3)); // 4
|
|
111
|
-
* console.log(findKthSmallest(7)); // 8
|
|
118
|
+
* // Verify merged dataset is in sorted order
|
|
119
|
+
* console.log([...merged.values()]); // ['A', 'B', 'C', 'D', 'E', 'F', 'G']
|
|
112
120
|
* @example
|
|
113
121
|
* // Find elements in a range
|
|
114
122
|
* const bst = new BST<number>([10, 5, 15, 3, 7, 12, 18]);
|
|
115
123
|
* console.log(bst.search(new Range(5, 10))); // [10, 5, 7]
|
|
116
|
-
* console.log(bst.
|
|
124
|
+
* console.log(bst.rangeSearch([4, 12], node => node.key.toString())); // ['10', '12', '5', '7']
|
|
117
125
|
* console.log(bst.search(new Range(4, 12, true, false))); // [10, 5, 7]
|
|
118
|
-
* console.log(bst.
|
|
126
|
+
* console.log(bst.rangeSearch([15, 20])); // [15, 18]
|
|
119
127
|
* console.log(bst.search(new Range(15, 20, false))); // [18]
|
|
120
128
|
* @example
|
|
121
129
|
* // Find lowest common ancestor
|
|
122
130
|
* const bst = new BST<number>([20, 10, 30, 5, 15, 25, 35, 3, 7, 12, 18]);
|
|
123
131
|
*
|
|
132
|
+
* // LCA helper function
|
|
133
|
+
* const findLCA = (num1: number, num2: number): number | undefined => {
|
|
134
|
+
* const path1 = bst.getPathToRoot(num1);
|
|
135
|
+
* const path2 = bst.getPathToRoot(num2);
|
|
136
|
+
* // Find the first common ancestor
|
|
137
|
+
* return findFirstCommon(path1, path2);
|
|
138
|
+
* };
|
|
139
|
+
*
|
|
124
140
|
* function findFirstCommon(arr1: number[], arr2: number[]): number | undefined {
|
|
125
141
|
* for (const num of arr1) {
|
|
126
142
|
* if (arr2.indexOf(num) !== -1) {
|
|
@@ -130,28 +146,14 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
|
|
|
130
146
|
* return undefined;
|
|
131
147
|
* }
|
|
132
148
|
*
|
|
133
|
-
* // LCA helper function
|
|
134
|
-
* const findLCA = (num1: number, num2: number): number | undefined => {
|
|
135
|
-
* const path1 = bst.getPathToRoot(num1);
|
|
136
|
-
* const path2 = bst.getPathToRoot(num2);
|
|
137
|
-
* // Find the first common ancestor
|
|
138
|
-
* return findFirstCommon(path1, path2);
|
|
139
|
-
* };
|
|
140
|
-
*
|
|
141
149
|
* // Assertions
|
|
142
150
|
* console.log(findLCA(3, 10)); // 7
|
|
143
151
|
* console.log(findLCA(5, 35)); // 15
|
|
144
152
|
* console.log(findLCA(20, 30)); // 25
|
|
145
153
|
*/
|
|
146
|
-
export class BST<
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
R = object,
|
|
150
|
-
NODE extends BSTNode<K, V, NODE> = BSTNode<K, V, BSTNodeNested<K, V>>,
|
|
151
|
-
TREE extends BST<K, V, R, NODE, TREE> = BST<K, V, R, NODE, BSTNested<K, V, R, NODE>>
|
|
152
|
-
>
|
|
153
|
-
extends BinaryTree<K, V, R, NODE, TREE>
|
|
154
|
-
implements IBinaryTree<K, V, R, NODE, TREE>
|
|
154
|
+
export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE> = BSTNode<K, V, BSTNodeNested<K, V>>>
|
|
155
|
+
extends BinaryTree<K, V, R, NODE>
|
|
156
|
+
implements IBinaryTree<K, V, R, NODE>
|
|
155
157
|
{
|
|
156
158
|
/**
|
|
157
159
|
* This is the constructor function for a Binary Search Tree class in TypeScript.
|
|
@@ -165,8 +167,8 @@ export class BST<
|
|
|
165
167
|
super([], options);
|
|
166
168
|
|
|
167
169
|
if (options) {
|
|
168
|
-
const {
|
|
169
|
-
if (typeof
|
|
170
|
+
const { specifyComparable, isReverse } = options;
|
|
171
|
+
if (typeof specifyComparable === 'function') this._specifyComparable = specifyComparable;
|
|
170
172
|
if (isReverse !== undefined) this._isReverse = isReverse;
|
|
171
173
|
}
|
|
172
174
|
|
|
@@ -194,6 +196,45 @@ export class BST<
|
|
|
194
196
|
return this._isReverse;
|
|
195
197
|
}
|
|
196
198
|
|
|
199
|
+
protected _comparator: Comparator<K> = (a: K, b: K): number => {
|
|
200
|
+
if (isComparable(a) && isComparable(b)) {
|
|
201
|
+
if (a > b) return 1;
|
|
202
|
+
if (a < b) return -1;
|
|
203
|
+
return 0;
|
|
204
|
+
}
|
|
205
|
+
if (this._specifyComparable) {
|
|
206
|
+
if (this._specifyComparable(a) > this._specifyComparable(b)) return 1;
|
|
207
|
+
if (this._specifyComparable(a) < this._specifyComparable(b)) return -1;
|
|
208
|
+
return 0;
|
|
209
|
+
}
|
|
210
|
+
if (typeof a === 'object' || typeof b === 'object') {
|
|
211
|
+
throw TypeError(
|
|
212
|
+
`When comparing object types, a custom specifyComparable must be defined in the constructor's options parameter.`
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return 0;
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* The function returns the value of the _comparator property.
|
|
221
|
+
* @returns The `_comparator` property is being returned.
|
|
222
|
+
*/
|
|
223
|
+
get comparator() {
|
|
224
|
+
return this._comparator;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
protected _specifyComparable?: (key: K) => Comparable;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* This function returns the value of the `_specifyComparable` property.
|
|
231
|
+
* @returns The method `specifyComparable()` is being returned, which is a getter method for the
|
|
232
|
+
* `_specifyComparable` property.
|
|
233
|
+
*/
|
|
234
|
+
get specifyComparable() {
|
|
235
|
+
return this._specifyComparable;
|
|
236
|
+
}
|
|
237
|
+
|
|
197
238
|
/**
|
|
198
239
|
* The function creates a new BSTNode with the given key and value and returns it.
|
|
199
240
|
* @param {K} key - The key parameter is of type K, which represents the type of the key for the node
|
|
@@ -207,39 +248,26 @@ export class BST<
|
|
|
207
248
|
}
|
|
208
249
|
|
|
209
250
|
/**
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
251
|
+
* Time Complexity: O(1)
|
|
252
|
+
* Space Complexity: O(1)
|
|
253
|
+
*
|
|
254
|
+
* The `createTree` function in TypeScript overrides the default options with the provided options to
|
|
255
|
+
* create a new Binary Search Tree.
|
|
256
|
+
* @param [options] - The `options` parameter in the `createTree` method is an optional object that
|
|
257
|
+
* can contain the following properties:
|
|
258
|
+
* @returns A new instance of a Binary Search Tree (BST) is being returned with the specified options
|
|
259
|
+
* and properties inherited from the current instance.
|
|
215
260
|
*/
|
|
216
|
-
|
|
217
|
-
|
|
261
|
+
// @ts-ignore
|
|
262
|
+
override createTree(options?: BSTOptions<K, V, R>) {
|
|
263
|
+
return new BST<K, V, R>([], {
|
|
218
264
|
iterationType: this.iterationType,
|
|
219
265
|
isMapMode: this._isMapMode,
|
|
220
|
-
|
|
266
|
+
specifyComparable: this._specifyComparable,
|
|
221
267
|
toEntryFn: this._toEntryFn,
|
|
222
268
|
isReverse: this._isReverse,
|
|
223
269
|
...options
|
|
224
|
-
})
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* The function overrides a method and converts a key, value pair or entry or raw element to a node.
|
|
229
|
-
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - A variable that can be of
|
|
230
|
-
* type R or BTNRep<K, V, NODE>. It represents either a key, a node, an entry, or a raw
|
|
231
|
-
* element.
|
|
232
|
-
* @param {V} [value] - The `value` parameter is an optional value of type `V`. It represents the
|
|
233
|
-
* value associated with a key in a key-value pair.
|
|
234
|
-
* @returns either a NODE object or undefined.
|
|
235
|
-
*/
|
|
236
|
-
override keyValueNodeEntryRawToNodeAndValue(
|
|
237
|
-
keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
|
|
238
|
-
value?: V
|
|
239
|
-
): [OptNode<NODE>, V | undefined] {
|
|
240
|
-
const [node, entryValue] = super.keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
|
|
241
|
-
if (node === null) return [undefined, undefined];
|
|
242
|
-
return [node, value ?? entryValue];
|
|
270
|
+
});
|
|
243
271
|
}
|
|
244
272
|
|
|
245
273
|
/**
|
|
@@ -284,7 +312,7 @@ export class BST<
|
|
|
284
312
|
* this._DEFAULT_COMPARATOR`.
|
|
285
313
|
*/
|
|
286
314
|
override isKey(key: any): key is K {
|
|
287
|
-
return isComparable(key, this.
|
|
315
|
+
return isComparable(key, this._specifyComparable !== undefined);
|
|
288
316
|
}
|
|
289
317
|
|
|
290
318
|
/**
|
|
@@ -299,7 +327,7 @@ export class BST<
|
|
|
299
327
|
* @returns a boolean value.
|
|
300
328
|
*/
|
|
301
329
|
override add(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R, value?: V): boolean {
|
|
302
|
-
const [newNode, newValue] = this.
|
|
330
|
+
const [newNode, newValue] = this._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
|
|
303
331
|
if (newNode === undefined) return false;
|
|
304
332
|
|
|
305
333
|
if (this._root === undefined) {
|
|
@@ -464,7 +492,7 @@ export class BST<
|
|
|
464
492
|
* @param anotherTree - `anotherTree` is an instance of a Binary Search Tree (BST) with key type `K`,
|
|
465
493
|
* value type `V`, return type `R`, node type `NODE`, and tree type `TREE`.
|
|
466
494
|
*/
|
|
467
|
-
override merge(anotherTree:
|
|
495
|
+
override merge(anotherTree: this) {
|
|
468
496
|
this.addMany(anotherTree, [], false);
|
|
469
497
|
}
|
|
470
498
|
|
|
@@ -609,6 +637,37 @@ export class BST<
|
|
|
609
637
|
return ans;
|
|
610
638
|
}
|
|
611
639
|
|
|
640
|
+
/**
|
|
641
|
+
* Time Complexity: O(log n)
|
|
642
|
+
* Space Complexity: O(n)
|
|
643
|
+
*
|
|
644
|
+
* The `rangeSearch` function searches for nodes within a specified range in a binary search tree.
|
|
645
|
+
* @param {Range<K> | [K, K]} range - The `range` parameter in the `rangeSearch` function can be
|
|
646
|
+
* either a `Range` object or an array of two elements representing the range boundaries.
|
|
647
|
+
* @param {C} callback - The `callback` parameter in the `rangeSearch` function is a callback
|
|
648
|
+
* function that is used to process each node that is found within the specified range during the
|
|
649
|
+
* search operation. It is of type `NodeCallback<NODE>`, where `NODE` is the type of nodes in the
|
|
650
|
+
* data structure.
|
|
651
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `rangeSearch`
|
|
652
|
+
* function represents the node from which the search for nodes within the specified range will
|
|
653
|
+
* begin. It is the starting point for the range search operation.
|
|
654
|
+
* @param {IterationType} iterationType - The `iterationType` parameter in the `rangeSearch` function
|
|
655
|
+
* is used to specify the type of iteration to be performed during the search operation. It has a
|
|
656
|
+
* default value of `this.iterationType`, which suggests that it is likely a property of the class or
|
|
657
|
+
* object that the `rangeSearch`
|
|
658
|
+
* @returns The `rangeSearch` function is returning the result of calling the `search` method with
|
|
659
|
+
* the specified parameters.
|
|
660
|
+
*/
|
|
661
|
+
rangeSearch<C extends NodeCallback<NODE>>(
|
|
662
|
+
range: Range<K> | [K, K],
|
|
663
|
+
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
664
|
+
startNode: BTNRep<K, V, NODE> | R = this._root,
|
|
665
|
+
iterationType: IterationType = this.iterationType
|
|
666
|
+
) {
|
|
667
|
+
const searchRange: Range<K> = range instanceof Range ? range : new Range(range[0], range[1]);
|
|
668
|
+
return this.search(searchRange, false, callback, startNode, iterationType);
|
|
669
|
+
}
|
|
670
|
+
|
|
612
671
|
/**
|
|
613
672
|
* Time Complexity: O(log n)
|
|
614
673
|
* Space Complexity: O(1)
|
|
@@ -885,43 +944,36 @@ export class BST<
|
|
|
885
944
|
return balanced;
|
|
886
945
|
}
|
|
887
946
|
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
947
|
+
// @ts-ignore
|
|
948
|
+
override map<MK, MV, MR>(
|
|
949
|
+
callback: EntryCallback<K, V | undefined, [MK, MV]>,
|
|
950
|
+
options?: BSTOptions<MK, MV, MR>,
|
|
951
|
+
thisArg?: any
|
|
952
|
+
) {
|
|
953
|
+
const newTree = new BST<MK, MV, MR>([], options);
|
|
954
|
+
let index = 0;
|
|
955
|
+
for (const [key, value] of this) {
|
|
956
|
+
newTree.add(callback.call(thisArg, key, value, index++, this));
|
|
898
957
|
}
|
|
899
|
-
|
|
900
|
-
throw TypeError(
|
|
901
|
-
`When comparing object types, a custom extractComparable must be defined in the constructor's options parameter.`
|
|
902
|
-
);
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
return 0;
|
|
906
|
-
};
|
|
907
|
-
|
|
908
|
-
/**
|
|
909
|
-
* The function returns the value of the _comparator property.
|
|
910
|
-
* @returns The `_comparator` property is being returned.
|
|
911
|
-
*/
|
|
912
|
-
get comparator() {
|
|
913
|
-
return this._comparator;
|
|
958
|
+
return newTree;
|
|
914
959
|
}
|
|
915
960
|
|
|
916
|
-
protected _extractComparable?: (key: K) => Comparable;
|
|
917
|
-
|
|
918
961
|
/**
|
|
919
|
-
*
|
|
920
|
-
* @
|
|
921
|
-
*
|
|
962
|
+
* The function overrides a method and converts a key, value pair or entry or raw element to a node.
|
|
963
|
+
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - A variable that can be of
|
|
964
|
+
* type R or BTNRep<K, V, NODE>. It represents either a key, a node, an entry, or a raw
|
|
965
|
+
* element.
|
|
966
|
+
* @param {V} [value] - The `value` parameter is an optional value of type `V`. It represents the
|
|
967
|
+
* value associated with a key in a key-value pair.
|
|
968
|
+
* @returns either a NODE object or undefined.
|
|
922
969
|
*/
|
|
923
|
-
|
|
924
|
-
|
|
970
|
+
protected override _keyValueNodeEntryRawToNodeAndValue(
|
|
971
|
+
keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
|
|
972
|
+
value?: V
|
|
973
|
+
): [OptNode<NODE>, V | undefined] {
|
|
974
|
+
const [node, entryValue] = super._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
|
|
975
|
+
if (node === null) return [undefined, undefined];
|
|
976
|
+
return [node, value ?? entryValue];
|
|
925
977
|
}
|
|
926
978
|
|
|
927
979
|
/**
|
|
@@ -2,10 +2,10 @@ import type {
|
|
|
2
2
|
BinaryTreeDeleteResult,
|
|
3
3
|
BTNRep,
|
|
4
4
|
CRUD,
|
|
5
|
+
EntryCallback,
|
|
5
6
|
OptNode,
|
|
6
7
|
RBTNColor,
|
|
7
|
-
|
|
8
|
-
RedBlackTreeNested,
|
|
8
|
+
RedBlackTreeOptions,
|
|
9
9
|
RedBlackTreeNodeNested
|
|
10
10
|
} from '../../types';
|
|
11
11
|
import { BST, BSTNode } from './bst';
|
|
@@ -54,28 +54,76 @@ export class RedBlackTreeNode<
|
|
|
54
54
|
/**
|
|
55
55
|
* 1. Efficient self-balancing, but not completely balanced. Compared with AVLTree, the addition and deletion efficiency is high but the query efficiency is slightly lower.
|
|
56
56
|
* 2. It is BST itself. Compared with Heap which is not completely ordered, RedBlackTree is completely ordered.
|
|
57
|
+
* @example
|
|
58
|
+
* // Find elements in a range
|
|
59
|
+
* const bst = new RedBlackTree<number>([10, 5, 15, 3, 7, 12, 18]);
|
|
60
|
+
* console.log(bst.search(new Range(5, 10))); // [5, 10, 7]
|
|
61
|
+
* console.log(bst.search(new Range(4, 12))); // [5, 10, 12, 7]
|
|
62
|
+
* console.log(bst.search(new Range(15, 20))); // [15, 18]
|
|
63
|
+
* @example
|
|
64
|
+
* // using Red-Black Tree as a price-based index for stock data
|
|
65
|
+
* // Define the structure of individual stock records
|
|
66
|
+
* interface StockRecord {
|
|
67
|
+
* price: number; // Stock price (key for indexing)
|
|
68
|
+
* symbol: string; // Stock ticker symbol
|
|
69
|
+
* volume: number; // Trade volume
|
|
70
|
+
* }
|
|
71
|
+
*
|
|
72
|
+
* // Simulate stock market data as it might come from an external feed
|
|
73
|
+
* const marketStockData: StockRecord[] = [
|
|
74
|
+
* { price: 142.5, symbol: 'AAPL', volume: 1000000 },
|
|
75
|
+
* { price: 335.2, symbol: 'MSFT', volume: 800000 },
|
|
76
|
+
* { price: 3285.04, symbol: 'AMZN', volume: 500000 },
|
|
77
|
+
* { price: 267.98, symbol: 'META', volume: 750000 },
|
|
78
|
+
* { price: 234.57, symbol: 'GOOGL', volume: 900000 }
|
|
79
|
+
* ];
|
|
80
|
+
*
|
|
81
|
+
* // Extend the stock record type to include metadata for database usage
|
|
82
|
+
* type StockTableRecord = StockRecord & { lastUpdated: Date };
|
|
83
|
+
*
|
|
84
|
+
* // Create a Red-Black Tree to index stock records by price
|
|
85
|
+
* // Simulates a database index with stock price as the key for quick lookups
|
|
86
|
+
* const priceIndex = new RedBlackTree<number, StockTableRecord, StockRecord>(marketStockData, {
|
|
87
|
+
* toEntryFn: stockRecord => [
|
|
88
|
+
* stockRecord.price, // Use stock price as the key
|
|
89
|
+
* {
|
|
90
|
+
* ...stockRecord,
|
|
91
|
+
* lastUpdated: new Date() // Add a timestamp for when the record was indexed
|
|
92
|
+
* }
|
|
93
|
+
* ]
|
|
94
|
+
* });
|
|
95
|
+
*
|
|
96
|
+
* // Query the stock with the highest price
|
|
97
|
+
* const highestPricedStock = priceIndex.getRightMost();
|
|
98
|
+
* console.log(priceIndex.get(highestPricedStock)?.symbol); // 'AMZN' // Amazon has the highest price
|
|
99
|
+
*
|
|
100
|
+
* // Query stocks within a specific price range (200 to 400)
|
|
101
|
+
* const stocksInRange = priceIndex.rangeSearch(
|
|
102
|
+
* [200, 400], // Price range
|
|
103
|
+
* node => priceIndex.get(node)?.symbol // Extract stock symbols for the result
|
|
104
|
+
* );
|
|
105
|
+
* console.log(stocksInRange); // ['GOOGL', 'MSFT', 'META']
|
|
57
106
|
*/
|
|
58
107
|
export class RedBlackTree<
|
|
59
108
|
K = any,
|
|
60
109
|
V = any,
|
|
61
110
|
R = object,
|
|
62
|
-
NODE extends RedBlackTreeNode<K, V, NODE> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V
|
|
63
|
-
TREE extends RedBlackTree<K, V, R, NODE, TREE> = RedBlackTree<K, V, R, NODE, RedBlackTreeNested<K, V, R, NODE>>
|
|
111
|
+
NODE extends RedBlackTreeNode<K, V, NODE> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>
|
|
64
112
|
>
|
|
65
|
-
extends BST<K, V, R, NODE
|
|
66
|
-
implements IBinaryTree<K, V, R, NODE
|
|
113
|
+
extends BST<K, V, R, NODE>
|
|
114
|
+
implements IBinaryTree<K, V, R, NODE>
|
|
67
115
|
{
|
|
68
116
|
/**
|
|
69
117
|
* This is the constructor function for a Red-Black Tree data structure in TypeScript.
|
|
70
118
|
* @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter is an
|
|
71
119
|
* iterable object that can contain either keys, nodes, entries, or raw elements. It is used to
|
|
72
|
-
* initialize the
|
|
120
|
+
* initialize the RedBlackTree with the provided elements.
|
|
73
121
|
* @param [options] - The `options` parameter is an optional object that can be passed to the
|
|
74
|
-
* constructor. It is of type `
|
|
122
|
+
* constructor. It is of type `RedBlackTreeOptions<K, V, R>`. This object can contain various options for
|
|
75
123
|
* configuring the behavior of the Red-Black Tree. The specific properties and their meanings would
|
|
76
124
|
* depend on the implementation
|
|
77
125
|
*/
|
|
78
|
-
constructor(keysNodesEntriesOrRaws: Iterable<R | BTNRep<K, V, NODE>> = [], options?:
|
|
126
|
+
constructor(keysNodesEntriesOrRaws: Iterable<R | BTNRep<K, V, NODE>> = [], options?: RedBlackTreeOptions<K, V, R>) {
|
|
79
127
|
super([], options);
|
|
80
128
|
|
|
81
129
|
this._root = this.NIL;
|
|
@@ -114,19 +162,23 @@ export class RedBlackTree<
|
|
|
114
162
|
}
|
|
115
163
|
|
|
116
164
|
/**
|
|
117
|
-
* The function
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
165
|
+
* The function `createTree` overrides the default implementation to create a Red-Black Tree with
|
|
166
|
+
* specified options in TypeScript.
|
|
167
|
+
* @param [options] - The `options` parameter in the `createTree` method is of type `RedBlackTreeOptions<K,
|
|
168
|
+
* V, R>`, which is a generic type with three type parameters `K`, `V`, and `R`. This parameter
|
|
169
|
+
* allows you to pass additional configuration options when creating a new Red-
|
|
170
|
+
* @returns A new instance of a RedBlackTree with the specified options and properties from the
|
|
171
|
+
* current object is being returned.
|
|
121
172
|
*/
|
|
122
|
-
|
|
123
|
-
|
|
173
|
+
// @ts-ignore
|
|
174
|
+
override createTree(options?: RedBlackTreeOptions<K, V, R>) {
|
|
175
|
+
return new RedBlackTree<K, V, R>([], {
|
|
124
176
|
iterationType: this.iterationType,
|
|
125
177
|
isMapMode: this._isMapMode,
|
|
126
|
-
|
|
178
|
+
specifyComparable: this._specifyComparable,
|
|
127
179
|
toEntryFn: this._toEntryFn,
|
|
128
180
|
...options
|
|
129
|
-
})
|
|
181
|
+
});
|
|
130
182
|
}
|
|
131
183
|
|
|
132
184
|
/**
|
|
@@ -143,42 +195,6 @@ export class RedBlackTree<
|
|
|
143
195
|
return keyNodeEntryOrRaw instanceof RedBlackTreeNode;
|
|
144
196
|
}
|
|
145
197
|
|
|
146
|
-
// /**
|
|
147
|
-
// * Time Complexity: O(1)
|
|
148
|
-
// * Space Complexity: O(1)
|
|
149
|
-
// */
|
|
150
|
-
//
|
|
151
|
-
// /**
|
|
152
|
-
// * Time Complexity: O(1)
|
|
153
|
-
// * Space Complexity: O(1)
|
|
154
|
-
// *
|
|
155
|
-
// * The function `keyValueNodeEntryRawToNodeAndValue` takes a key, value, or entry and returns a node if it is
|
|
156
|
-
// * valid, otherwise it returns undefined.
|
|
157
|
-
// * @param {BTNRep<K, V, NODE>} keyNodeEntryOrRaw - The key, value, or entry to convert.
|
|
158
|
-
// * @param {V} [value] - The value associated with the key (if `keyNodeEntryOrRaw` is a key).
|
|
159
|
-
// * @returns {NODE | undefined} - The corresponding Red-Black Tree node, or `undefined` if conversion fails.
|
|
160
|
-
// */
|
|
161
|
-
// override keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R, value?: V): NODE | undefined {
|
|
162
|
-
//
|
|
163
|
-
// if (keyNodeEntryOrRaw === null || keyNodeEntryOrRaw === undefined) return;
|
|
164
|
-
// if (this.isNode(keyNodeEntryOrRaw)) return keyNodeEntryOrRaw;
|
|
165
|
-
//
|
|
166
|
-
// if (this._toEntryFn) {
|
|
167
|
-
// const [key, entryValue] = this._toEntryFn(keyNodeEntryOrRaw as R);
|
|
168
|
-
// if (this.isKey(key)) return this.createNode(key, value ?? entryValue, 'RED');
|
|
169
|
-
// }
|
|
170
|
-
//
|
|
171
|
-
// if (this.isEntry(keyNodeEntryOrRaw)) {
|
|
172
|
-
// const [key, value] = keyNodeEntryOrRaw;
|
|
173
|
-
// if (key === undefined || key === null) return;
|
|
174
|
-
// else return this.createNode(key, value, 'RED');
|
|
175
|
-
// }
|
|
176
|
-
//
|
|
177
|
-
// if (this.isKey(keyNodeEntryOrRaw)) return this.createNode(keyNodeEntryOrRaw, value, 'RED');
|
|
178
|
-
//
|
|
179
|
-
// return ;
|
|
180
|
-
// }
|
|
181
|
-
|
|
182
198
|
/**
|
|
183
199
|
* Time Complexity: O(1)
|
|
184
200
|
* Space Complexity: O(1)
|
|
@@ -207,7 +223,7 @@ export class RedBlackTree<
|
|
|
207
223
|
* returns true. If the node cannot be added or updated, the method returns false.
|
|
208
224
|
*/
|
|
209
225
|
override add(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R, value?: V): boolean {
|
|
210
|
-
const [newNode, newValue] = this.
|
|
226
|
+
const [newNode, newValue] = this._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
|
|
211
227
|
if (!this.isRealNode(newNode)) return false;
|
|
212
228
|
|
|
213
229
|
const insertStatus = this._insert(newNode);
|
|
@@ -304,6 +320,40 @@ export class RedBlackTree<
|
|
|
304
320
|
return results;
|
|
305
321
|
}
|
|
306
322
|
|
|
323
|
+
/**
|
|
324
|
+
* Time Complexity: O(n)
|
|
325
|
+
* Space Complexity: O(n)
|
|
326
|
+
*
|
|
327
|
+
* The `map` function in TypeScript overrides the default behavior to create a new Red-Black Tree by
|
|
328
|
+
* applying a callback to each entry in the original tree.
|
|
329
|
+
* @param callback - A function that will be called for each entry in the tree, with parameters
|
|
330
|
+
* representing the key, value, index, and the tree itself. It should return an entry for the new
|
|
331
|
+
* tree.
|
|
332
|
+
* @param [options] - The `options` parameter in the `map` method is of type `RedBlackTreeOptions<MK, MV,
|
|
333
|
+
* MR>`. This parameter allows you to specify additional options or configurations for the Red-Black
|
|
334
|
+
* Tree that will be created during the mapping process. These options could include things like
|
|
335
|
+
* custom comparators
|
|
336
|
+
* @param {any} [thisArg] - The `thisArg` parameter in the `override map` function is used to specify
|
|
337
|
+
* the value of `this` when executing the `callback` function. It allows you to set the context
|
|
338
|
+
* (value of `this`) for the callback function. This can be useful when you want to access properties
|
|
339
|
+
* or
|
|
340
|
+
* @returns A new Red-Black Tree is being returned, where each entry has been transformed using the
|
|
341
|
+
* provided callback function.
|
|
342
|
+
*/
|
|
343
|
+
// @ts-ignore
|
|
344
|
+
override map<MK, MV, MR>(
|
|
345
|
+
callback: EntryCallback<K, V | undefined, [MK, MV]>,
|
|
346
|
+
options?: RedBlackTreeOptions<MK, MV, MR>,
|
|
347
|
+
thisArg?: any
|
|
348
|
+
) {
|
|
349
|
+
const newTree = new RedBlackTree<MK, MV, MR>([], options);
|
|
350
|
+
let index = 0;
|
|
351
|
+
for (const [key, value] of this) {
|
|
352
|
+
newTree.add(callback.call(thisArg, key, value, index++, this));
|
|
353
|
+
}
|
|
354
|
+
return newTree;
|
|
355
|
+
}
|
|
356
|
+
|
|
307
357
|
/**
|
|
308
358
|
* Time Complexity: O(1)
|
|
309
359
|
* Space Complexity: O(1)
|
|
@@ -370,7 +420,7 @@ export class RedBlackTree<
|
|
|
370
420
|
|
|
371
421
|
if (!parent) {
|
|
372
422
|
this._setRoot(node);
|
|
373
|
-
} else if (node.key
|
|
423
|
+
} else if (this._compare(node.key, parent.key) < 0) {
|
|
374
424
|
parent.left = node;
|
|
375
425
|
} else {
|
|
376
426
|
parent.right = node;
|