queue-typed 2.0.4 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/data-structures/base/iterable-element-base.d.ts +186 -83
- package/dist/data-structures/base/iterable-element-base.js +149 -107
- package/dist/data-structures/base/iterable-entry-base.d.ts +95 -119
- package/dist/data-structures/base/iterable-entry-base.js +59 -116
- package/dist/data-structures/base/linear-base.d.ts +250 -192
- package/dist/data-structures/base/linear-base.js +137 -274
- package/dist/data-structures/binary-tree/avl-tree-counter.d.ts +126 -158
- package/dist/data-structures/binary-tree/avl-tree-counter.js +171 -205
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +100 -69
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +135 -87
- package/dist/data-structures/binary-tree/avl-tree.d.ts +138 -149
- package/dist/data-structures/binary-tree/avl-tree.js +208 -195
- package/dist/data-structures/binary-tree/binary-tree.d.ts +476 -632
- package/dist/data-structures/binary-tree/binary-tree.js +612 -879
- package/dist/data-structures/binary-tree/bst.d.ts +258 -306
- package/dist/data-structures/binary-tree/bst.js +505 -481
- package/dist/data-structures/binary-tree/red-black-tree.d.ts +107 -179
- package/dist/data-structures/binary-tree/red-black-tree.js +114 -209
- package/dist/data-structures/binary-tree/tree-counter.d.ts +132 -154
- package/dist/data-structures/binary-tree/tree-counter.js +172 -203
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +72 -69
- package/dist/data-structures/binary-tree/tree-multi-map.js +105 -85
- package/dist/data-structures/graph/abstract-graph.d.ts +238 -233
- package/dist/data-structures/graph/abstract-graph.js +267 -237
- package/dist/data-structures/graph/directed-graph.d.ts +108 -224
- package/dist/data-structures/graph/directed-graph.js +146 -233
- package/dist/data-structures/graph/map-graph.d.ts +49 -55
- package/dist/data-structures/graph/map-graph.js +56 -59
- package/dist/data-structures/graph/undirected-graph.d.ts +103 -146
- package/dist/data-structures/graph/undirected-graph.js +129 -149
- package/dist/data-structures/hash/hash-map.d.ts +164 -338
- package/dist/data-structures/hash/hash-map.js +270 -457
- package/dist/data-structures/heap/heap.d.ts +214 -289
- package/dist/data-structures/heap/heap.js +340 -349
- package/dist/data-structures/heap/max-heap.d.ts +11 -47
- package/dist/data-structures/heap/max-heap.js +11 -66
- package/dist/data-structures/heap/min-heap.d.ts +12 -47
- package/dist/data-structures/heap/min-heap.js +11 -66
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +231 -347
- package/dist/data-structures/linked-list/doubly-linked-list.js +368 -494
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +261 -310
- package/dist/data-structures/linked-list/singly-linked-list.js +447 -466
- package/dist/data-structures/linked-list/skip-linked-list.d.ts +0 -107
- package/dist/data-structures/linked-list/skip-linked-list.js +0 -100
- package/dist/data-structures/priority-queue/max-priority-queue.d.ts +12 -56
- package/dist/data-structures/priority-queue/max-priority-queue.js +11 -78
- package/dist/data-structures/priority-queue/min-priority-queue.d.ts +11 -57
- package/dist/data-structures/priority-queue/min-priority-queue.js +10 -79
- package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -61
- package/dist/data-structures/priority-queue/priority-queue.js +8 -83
- package/dist/data-structures/queue/deque.d.ts +227 -254
- package/dist/data-structures/queue/deque.js +309 -348
- package/dist/data-structures/queue/queue.d.ts +180 -201
- package/dist/data-structures/queue/queue.js +265 -248
- package/dist/data-structures/stack/stack.d.ts +124 -102
- package/dist/data-structures/stack/stack.js +181 -125
- package/dist/data-structures/trie/trie.d.ts +164 -165
- package/dist/data-structures/trie/trie.js +189 -172
- package/dist/interfaces/binary-tree.d.ts +56 -6
- package/dist/interfaces/graph.d.ts +16 -0
- package/dist/types/data-structures/base/base.d.ts +1 -1
- package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -0
- package/dist/types/utils/utils.d.ts +6 -6
- package/dist/utils/utils.d.ts +110 -49
- package/dist/utils/utils.js +148 -73
- package/package.json +2 -2
- package/src/data-structures/base/iterable-element-base.ts +238 -115
- package/src/data-structures/base/iterable-entry-base.ts +96 -120
- package/src/data-structures/base/linear-base.ts +271 -277
- package/src/data-structures/binary-tree/avl-tree-counter.ts +198 -216
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +192 -101
- package/src/data-structures/binary-tree/avl-tree.ts +239 -206
- package/src/data-structures/binary-tree/binary-tree.ts +681 -905
- package/src/data-structures/binary-tree/bst.ts +568 -570
- package/src/data-structures/binary-tree/red-black-tree.ts +161 -222
- package/src/data-structures/binary-tree/tree-counter.ts +199 -218
- package/src/data-structures/binary-tree/tree-multi-map.ts +131 -97
- package/src/data-structures/graph/abstract-graph.ts +339 -264
- package/src/data-structures/graph/directed-graph.ts +146 -236
- package/src/data-structures/graph/map-graph.ts +63 -60
- package/src/data-structures/graph/undirected-graph.ts +129 -152
- package/src/data-structures/hash/hash-map.ts +274 -496
- package/src/data-structures/heap/heap.ts +389 -402
- package/src/data-structures/heap/max-heap.ts +12 -76
- package/src/data-structures/heap/min-heap.ts +13 -76
- package/src/data-structures/linked-list/doubly-linked-list.ts +426 -530
- package/src/data-structures/linked-list/singly-linked-list.ts +495 -517
- package/src/data-structures/linked-list/skip-linked-list.ts +1 -108
- package/src/data-structures/priority-queue/max-priority-queue.ts +12 -87
- package/src/data-structures/priority-queue/min-priority-queue.ts +11 -88
- package/src/data-structures/priority-queue/priority-queue.ts +3 -92
- package/src/data-structures/queue/deque.ts +381 -357
- package/src/data-structures/queue/queue.ts +310 -264
- package/src/data-structures/stack/stack.ts +217 -131
- package/src/data-structures/trie/trie.ts +240 -175
- package/src/interfaces/binary-tree.ts +240 -6
- package/src/interfaces/graph.ts +37 -0
- package/src/types/data-structures/base/base.ts +5 -5
- package/src/types/data-structures/graph/abstract-graph.ts +5 -0
- package/src/types/utils/utils.ts +9 -5
- package/src/utils/utils.ts +152 -86
|
@@ -1,4 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* data-structure-typed
|
|
3
|
+
*
|
|
4
|
+
* @author Pablo Zeng
|
|
5
|
+
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
|
6
|
+
* @license MIT License
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type {
|
|
10
|
+
BinaryTreeDeleteResult,
|
|
11
|
+
BinaryTreeOptions,
|
|
12
|
+
CRUD,
|
|
13
|
+
EntryCallback,
|
|
14
|
+
OptNode,
|
|
15
|
+
RBTNColor,
|
|
16
|
+
RedBlackTreeOptions
|
|
17
|
+
} from '../../types';
|
|
2
18
|
import { BST, BSTNode } from './bst';
|
|
3
19
|
import { IBinaryTree } from '../../interfaces';
|
|
4
20
|
|
|
@@ -6,15 +22,14 @@ export class RedBlackTreeNode<K = any, V = any> extends BSTNode<K, V> {
|
|
|
6
22
|
override parent?: RedBlackTreeNode<K, V> = undefined;
|
|
7
23
|
|
|
8
24
|
/**
|
|
9
|
-
*
|
|
10
|
-
* @
|
|
11
|
-
*
|
|
12
|
-
* @param
|
|
13
|
-
*
|
|
14
|
-
* @
|
|
15
|
-
* color of the node in a Red-Black Tree. It has a default value of 'BLACK' if not provided
|
|
16
|
-
* explicitly.
|
|
25
|
+
* Create a Red-Black Tree and optionally bulk-insert items.
|
|
26
|
+
* @remarks Time O(n log n), Space O(n)
|
|
27
|
+
* @param key - See parameter type for details.
|
|
28
|
+
* @param [value]- See parameter type for details.
|
|
29
|
+
* @param color - See parameter type for details.
|
|
30
|
+
* @returns New RedBlackTree instance.
|
|
17
31
|
*/
|
|
32
|
+
|
|
18
33
|
constructor(key: K, value?: V, color: RBTNColor = 'BLACK') {
|
|
19
34
|
super(key, value);
|
|
20
35
|
this._color = color;
|
|
@@ -22,10 +37,23 @@ export class RedBlackTreeNode<K = any, V = any> extends BSTNode<K, V> {
|
|
|
22
37
|
|
|
23
38
|
override _left?: RedBlackTreeNode<K, V> | null | undefined = undefined;
|
|
24
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Get the left child pointer.
|
|
42
|
+
* @remarks Time O(1), Space O(1)
|
|
43
|
+
* @returns Left child node, or null/undefined.
|
|
44
|
+
*/
|
|
45
|
+
|
|
25
46
|
override get left(): RedBlackTreeNode<K, V> | null | undefined {
|
|
26
47
|
return this._left;
|
|
27
48
|
}
|
|
28
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Set the left child and update its parent pointer.
|
|
52
|
+
* @remarks Time O(1), Space O(1)
|
|
53
|
+
* @param v - New left node, or null/undefined.
|
|
54
|
+
* @returns void
|
|
55
|
+
*/
|
|
56
|
+
|
|
29
57
|
override set left(v: RedBlackTreeNode<K, V> | null | undefined) {
|
|
30
58
|
if (v) {
|
|
31
59
|
v.parent = this;
|
|
@@ -35,10 +63,23 @@ export class RedBlackTreeNode<K = any, V = any> extends BSTNode<K, V> {
|
|
|
35
63
|
|
|
36
64
|
override _right?: RedBlackTreeNode<K, V> | null | undefined = undefined;
|
|
37
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Get the right child pointer.
|
|
68
|
+
* @remarks Time O(1), Space O(1)
|
|
69
|
+
* @returns Right child node, or null/undefined.
|
|
70
|
+
*/
|
|
71
|
+
|
|
38
72
|
override get right(): RedBlackTreeNode<K, V> | null | undefined {
|
|
39
73
|
return this._right;
|
|
40
74
|
}
|
|
41
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Set the right child and update its parent pointer.
|
|
78
|
+
* @remarks Time O(1), Space O(1)
|
|
79
|
+
* @param v - New right node, or null/undefined.
|
|
80
|
+
* @returns void
|
|
81
|
+
*/
|
|
82
|
+
|
|
42
83
|
override set right(v: RedBlackTreeNode<K, V> | null | undefined) {
|
|
43
84
|
if (v) {
|
|
44
85
|
v.parent = this;
|
|
@@ -48,6 +89,11 @@ export class RedBlackTreeNode<K = any, V = any> extends BSTNode<K, V> {
|
|
|
48
89
|
}
|
|
49
90
|
|
|
50
91
|
/**
|
|
92
|
+
* RRRRed-Black Tree (self-balancing BST) supporting map-like mode and stable O(log n) updates.
|
|
93
|
+
* @remarks Time O(1), Space O(1)
|
|
94
|
+
* @template K
|
|
95
|
+
* @template V
|
|
96
|
+
* @template R
|
|
51
97
|
* 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.
|
|
52
98
|
* 2. It is BST itself. Compared with Heap which is not completely ordered, RedBlackTree is completely ordered.
|
|
53
99
|
* @example
|
|
@@ -94,21 +140,11 @@ export class RedBlackTreeNode<K = any, V = any> extends BSTNode<K, V> {
|
|
|
94
140
|
* );
|
|
95
141
|
* console.log(stocksInRange); // ['GOOGL', 'META', 'MSFT']
|
|
96
142
|
*/
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
143
|
+
|
|
144
|
+
export class RedBlackTree<K = any, V = any, R extends object = object>
|
|
145
|
+
extends BST<K, V, R>
|
|
146
|
+
implements IBinaryTree<K, V, R>
|
|
100
147
|
{
|
|
101
|
-
/**
|
|
102
|
-
* This TypeScript constructor initializes a Red-Black Tree with optional keys, nodes, entries, or
|
|
103
|
-
* raw data.
|
|
104
|
-
* @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the constructor is an
|
|
105
|
-
* iterable that can contain either `K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined` objects or `R` objects. It
|
|
106
|
-
* is used to initialize the Red-Black Tree with keys, nodes, entries, or
|
|
107
|
-
* @param [options] - The `options` parameter in the constructor is of type `RedBlackTreeOptions<K,
|
|
108
|
-
* V, R>`. It is an optional parameter that allows you to specify additional options for the
|
|
109
|
-
* RedBlackTree class. These options could include configuration settings, behavior customization, or
|
|
110
|
-
* any other parameters that are specific to
|
|
111
|
-
*/
|
|
112
148
|
constructor(
|
|
113
149
|
keysNodesEntriesOrRaws: Iterable<
|
|
114
150
|
K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | R
|
|
@@ -126,60 +162,34 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
126
162
|
|
|
127
163
|
protected override _root: RedBlackTreeNode<K, V> | undefined;
|
|
128
164
|
|
|
165
|
+
/**
|
|
166
|
+
* Get the current root node.
|
|
167
|
+
* @remarks Time O(1), Space O(1)
|
|
168
|
+
* @returns Root node, or undefined.
|
|
169
|
+
*/
|
|
129
170
|
override get root(): RedBlackTreeNode<K, V> | undefined {
|
|
130
171
|
return this._root;
|
|
131
172
|
}
|
|
132
173
|
|
|
133
174
|
/**
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
* @param
|
|
139
|
-
*
|
|
140
|
-
* function.
|
|
141
|
-
* @param {V} [value] - The `value` parameter is an optional parameter that represents the value
|
|
142
|
-
* associated with the key in the node. It is not required and can be omitted if you only need to
|
|
143
|
-
* create a node with a key.
|
|
144
|
-
* @param {RBTNColor} [color=BLACK] - The "color" parameter is used to specify the color of the node
|
|
145
|
-
* in a Red-Black Tree. It can have two possible values: "RED" or "BLACK". By default, the color is
|
|
146
|
-
* set to "BLACK" if not specified.
|
|
147
|
-
* @returns A new instance of a RedBlackTreeNode with the specified key, value, and color is being
|
|
148
|
-
* returned.
|
|
175
|
+
* Create a red-black node for the given key/value (value ignored in map mode).
|
|
176
|
+
* @remarks Time O(1), Space O(1)
|
|
177
|
+
* @param key - See parameter type for details.
|
|
178
|
+
* @param [value] - See parameter type for details.
|
|
179
|
+
* @param color - See parameter type for details.
|
|
180
|
+
* @returns A new RedBlackTreeNode instance.
|
|
149
181
|
*/
|
|
150
|
-
override
|
|
182
|
+
override _createNode(key: K, value?: V, color: RBTNColor = 'BLACK'): RedBlackTreeNode<K, V> {
|
|
151
183
|
return new RedBlackTreeNode<K, V>(key, this._isMapMode ? undefined : value, color);
|
|
152
184
|
}
|
|
153
185
|
|
|
154
186
|
/**
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
* @param [options] - The `options` parameter is an optional object that contains additional
|
|
160
|
-
* configuration options for creating the Red-Black Tree. It has the following properties:
|
|
161
|
-
* @returns a new instance of a RedBlackTree object.
|
|
187
|
+
* Type guard: check whether the input is a RedBlackTreeNode.
|
|
188
|
+
* @remarks Time O(1), Space O(1)
|
|
189
|
+
* @param keyNodeOrEntry - See parameter type for details.
|
|
190
|
+
* @returns True if the value is a RedBlackTreeNode.
|
|
162
191
|
*/
|
|
163
|
-
override createTree(options?: RedBlackTreeOptions<K, V, R>) {
|
|
164
|
-
return new RedBlackTree<K, V, R, MK, MV, MR>([], {
|
|
165
|
-
iterationType: this.iterationType,
|
|
166
|
-
isMapMode: this._isMapMode,
|
|
167
|
-
specifyComparable: this._specifyComparable,
|
|
168
|
-
toEntryFn: this._toEntryFn,
|
|
169
|
-
...options
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
192
|
|
|
173
|
-
/**
|
|
174
|
-
* Time Complexity: O(1)
|
|
175
|
-
* Space Complexity: O(1)
|
|
176
|
-
*
|
|
177
|
-
* The function checks if the input is an instance of the RedBlackTreeNode class.
|
|
178
|
-
* @param {K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined} keyNodeOrEntry - The parameter
|
|
179
|
-
* `keyNodeOrEntry` can be of type `R` or `K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined`.
|
|
180
|
-
* @returns a boolean value indicating whether the input parameter `keyNodeOrEntry` is
|
|
181
|
-
* an instance of the `RedBlackTreeNode` class.
|
|
182
|
-
*/
|
|
183
193
|
override isNode(
|
|
184
194
|
keyNodeOrEntry: K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined
|
|
185
195
|
): keyNodeOrEntry is RedBlackTreeNode<K, V> {
|
|
@@ -187,31 +197,22 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
187
197
|
}
|
|
188
198
|
|
|
189
199
|
/**
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
* The "clear" function sets the root node of a data structure to a sentinel value and resets the
|
|
194
|
-
* size counter to zero.
|
|
200
|
+
* Remove all nodes and clear the key→value store (if in map mode).
|
|
201
|
+
* @remarks Time O(n), Space O(1)
|
|
202
|
+
* @returns void
|
|
195
203
|
*/
|
|
204
|
+
|
|
196
205
|
override clear() {
|
|
197
206
|
super.clear();
|
|
198
207
|
this._root = this.NIL;
|
|
199
208
|
}
|
|
200
209
|
|
|
201
210
|
/**
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
* @param {K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined} keyNodeOrEntry - The parameter
|
|
208
|
-
* `keyNodeOrEntry` can accept a value of type `R` or `K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined`.
|
|
209
|
-
* @param {V} [value] - The `value` parameter is an optional value that you want to associate with
|
|
210
|
-
* the key in the data structure. It represents the value that you want to add or update in the data
|
|
211
|
-
* structure.
|
|
212
|
-
* @returns The method is returning a boolean value. If a new node is successfully added to the tree,
|
|
213
|
-
* the method returns true. If the node already exists and its value is updated, the method also
|
|
214
|
-
* returns true. If the node cannot be added or updated, the method returns false.
|
|
211
|
+
* Insert or replace an entry using BST order and red-black fix-up.
|
|
212
|
+
* @remarks Time O(log n), Space O(1)
|
|
213
|
+
* @param keyNodeOrEntry - Key, node, or [key, value] entry to insert.
|
|
214
|
+
* @param [value]- See parameter type for details.
|
|
215
|
+
* @returns True if inserted or updated; false if ignored.
|
|
215
216
|
*/
|
|
216
217
|
override add(
|
|
217
218
|
keyNodeOrEntry: K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
|
|
@@ -223,7 +224,6 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
223
224
|
const insertStatus = this._insert(newNode);
|
|
224
225
|
|
|
225
226
|
if (insertStatus === 'CREATED') {
|
|
226
|
-
// Ensure the root is black
|
|
227
227
|
if (this.isRealNode(this._root)) {
|
|
228
228
|
this._root.color = 'BLACK';
|
|
229
229
|
} else {
|
|
@@ -241,19 +241,12 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
/**
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
* a given predicate and maintain the binary search tree properties.
|
|
249
|
-
* @param {K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined} keyNodeOrEntry - The `keyNodeOrEntry`
|
|
250
|
-
* parameter in the `override delete` method is used to specify the condition or key based on which a
|
|
251
|
-
* node should be deleted from the binary tree. It can be a key, a node, an entry, or a predicate
|
|
252
|
-
* function that determines which node(s) should be deleted.
|
|
253
|
-
* @returns The `override delete` method is returning an array of `BinaryTreeDeleteResult<RedBlackTreeNode<K, V>>`
|
|
254
|
-
* objects. Each object in the array contains information about the deleted node and whether
|
|
255
|
-
* balancing is needed.
|
|
244
|
+
* Delete a node by key/node/entry and rebalance as needed.
|
|
245
|
+
* @remarks Time O(log n), Space O(1)
|
|
246
|
+
* @param keyNodeOrEntry - Key, node, or [key, value] entry identifying the node to delete.
|
|
247
|
+
* @returns Array with deletion metadata (removed node, rebalancing hint if any).
|
|
256
248
|
*/
|
|
249
|
+
|
|
257
250
|
override delete(
|
|
258
251
|
keyNodeOrEntry: K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined
|
|
259
252
|
): BinaryTreeDeleteResult<RedBlackTreeNode<K, V>>[] {
|
|
@@ -310,7 +303,6 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
310
303
|
if (this._isMapMode) this._store.delete(nodeToDelete.key);
|
|
311
304
|
this._size--;
|
|
312
305
|
|
|
313
|
-
// If the original color was black, fix the tree
|
|
314
306
|
if (originalColor === 'BLACK') {
|
|
315
307
|
this._deleteFixup(replacementNode);
|
|
316
308
|
}
|
|
@@ -321,60 +313,54 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
321
313
|
}
|
|
322
314
|
|
|
323
315
|
/**
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
* @param callback -
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
* @
|
|
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.
|
|
316
|
+
* Transform entries into a like-kind red-black tree with possibly different key/value types.
|
|
317
|
+
* @remarks Time O(n), Space O(n)
|
|
318
|
+
* @template MK
|
|
319
|
+
* @template MV
|
|
320
|
+
* @template MR
|
|
321
|
+
* @param callback - Mapping function from (key, value, index, tree) to a new [key, value].
|
|
322
|
+
* @param [options] - See parameter type for details.
|
|
323
|
+
* @param [thisArg] - See parameter type for details.
|
|
324
|
+
* @returns A new RedBlackTree with mapped entries.
|
|
342
325
|
*/
|
|
343
|
-
|
|
326
|
+
|
|
327
|
+
override map<MK = K, MV = V, MR extends object = object>(
|
|
344
328
|
callback: EntryCallback<K, V | undefined, [MK, MV]>,
|
|
345
|
-
options?:
|
|
346
|
-
thisArg?:
|
|
329
|
+
options?: Partial<BinaryTreeOptions<MK, MV, MR>>,
|
|
330
|
+
thisArg?: unknown
|
|
347
331
|
): RedBlackTree<MK, MV, MR> {
|
|
348
|
-
const
|
|
332
|
+
const out = this._createLike<MK, MV, MR>([], options);
|
|
333
|
+
|
|
349
334
|
let index = 0;
|
|
350
335
|
for (const [key, value] of this) {
|
|
351
|
-
|
|
336
|
+
out.add(callback.call(thisArg, key, value, index++, this));
|
|
352
337
|
}
|
|
353
|
-
return
|
|
338
|
+
return out;
|
|
354
339
|
}
|
|
355
340
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
341
|
+
protected override _createInstance<TK = K, TV = V, TR extends object = R>(
|
|
342
|
+
options?: Partial<RedBlackTreeOptions<TK, TV, TR>>
|
|
343
|
+
): this {
|
|
344
|
+
const Ctor = this.constructor as unknown as new (
|
|
345
|
+
iter?: Iterable<TK | RedBlackTreeNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR>,
|
|
346
|
+
opts?: RedBlackTreeOptions<TK, TV, TR>
|
|
347
|
+
) => RedBlackTree<TK, TV, TR>;
|
|
348
|
+
return new Ctor([], { ...this._snapshotOptions<TK, TV, TR>(), ...(options ?? {}) }) as unknown as this;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
protected override _createLike<TK = K, TV = V, TR extends object = R>(
|
|
352
|
+
iter: Iterable<
|
|
353
|
+
TK | RedBlackTreeNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR
|
|
354
|
+
> = [],
|
|
355
|
+
options?: Partial<RedBlackTreeOptions<TK, TV, TR>>
|
|
356
|
+
): RedBlackTree<TK, TV, TR> {
|
|
357
|
+
const Ctor = this.constructor as unknown as new (
|
|
358
|
+
iter?: Iterable<TK | RedBlackTreeNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR>,
|
|
359
|
+
opts?: RedBlackTreeOptions<TK, TV, TR>
|
|
360
|
+
) => RedBlackTree<TK, TV, TR>;
|
|
361
|
+
return new Ctor(iter, { ...this._snapshotOptions<TK, TV, TR>(), ...(options ?? {}) });
|
|
368
362
|
}
|
|
369
363
|
|
|
370
|
-
/**
|
|
371
|
-
* Time Complexity: O(1)
|
|
372
|
-
* Space Complexity: O(1)
|
|
373
|
-
*
|
|
374
|
-
* The function sets the root of a tree-like structure and updates the parent property of the new
|
|
375
|
-
* root.
|
|
376
|
-
* @param {RedBlackTreeNode<K, V> | undefined} v - v is a parameter of type RedBlackTreeNode<K, V> or undefined.
|
|
377
|
-
*/
|
|
378
364
|
protected override _setRoot(v: RedBlackTreeNode<K, V> | undefined) {
|
|
379
365
|
if (v) {
|
|
380
366
|
v.parent = undefined;
|
|
@@ -382,18 +368,6 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
382
368
|
this._root = v;
|
|
383
369
|
}
|
|
384
370
|
|
|
385
|
-
/**
|
|
386
|
-
* Time Complexity: O(1)
|
|
387
|
-
* Space Complexity: O(1)
|
|
388
|
-
*
|
|
389
|
-
* The function replaces an old node with a new node while preserving the color of the old node.
|
|
390
|
-
* @param {RedBlackTreeNode<K, V>} oldNode - The `oldNode` parameter represents the node that needs to be replaced in
|
|
391
|
-
* the data structure.
|
|
392
|
-
* @param {RedBlackTreeNode<K, V>} newNode - The `newNode` parameter is of type `RedBlackTreeNode<K, V>`, which represents a node in a
|
|
393
|
-
* data structure.
|
|
394
|
-
* @returns The method is returning the result of calling the `_replaceNode` method from the
|
|
395
|
-
* superclass, with the `oldNode` and `newNode` parameters.
|
|
396
|
-
*/
|
|
397
371
|
protected override _replaceNode(
|
|
398
372
|
oldNode: RedBlackTreeNode<K, V>,
|
|
399
373
|
newNode: RedBlackTreeNode<K, V>
|
|
@@ -404,17 +378,12 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
404
378
|
}
|
|
405
379
|
|
|
406
380
|
/**
|
|
407
|
-
*
|
|
408
|
-
*
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
* maintain the red-black tree properties.
|
|
412
|
-
* @param {RedBlackTreeNode<K, V>} node - The `node` parameter represents the node that needs to be inserted into the
|
|
413
|
-
* binary search tree.
|
|
414
|
-
* @returns a string value indicating the result of the insertion operation. It can return either
|
|
415
|
-
* 'UPDATED' if the node with the same key already exists and was updated, or 'CREATED' if a new node
|
|
416
|
-
* was created and inserted into the tree.
|
|
381
|
+
* (Protected) Standard BST insert followed by red-black fix-up.
|
|
382
|
+
* @remarks Time O(log n), Space O(1)
|
|
383
|
+
* @param node - Node to insert.
|
|
384
|
+
* @returns Status string: 'CREATED' or 'UPDATED'.
|
|
417
385
|
*/
|
|
386
|
+
|
|
418
387
|
protected _insert(node: RedBlackTreeNode<K, V>): CRUD {
|
|
419
388
|
let current = this.root;
|
|
420
389
|
let parent: RedBlackTreeNode<K, V> | undefined = undefined;
|
|
@@ -451,14 +420,13 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
451
420
|
}
|
|
452
421
|
|
|
453
422
|
/**
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
* @
|
|
459
|
-
* @param {RedBlackTreeNode<K, V> | undefined} v - The parameter `v` is of type `RedBlackTreeNode<K, V> | undefined`, which means it can
|
|
460
|
-
* either be a `RedBlackTreeNode<K, V>` object or `undefined`.
|
|
423
|
+
* (Protected) Transplant a subtree in place of another during deletion.
|
|
424
|
+
* @remarks Time O(1), Space O(1)
|
|
425
|
+
* @param u - Node to replace.
|
|
426
|
+
* @param v - Replacement subtree root (may be undefined).
|
|
427
|
+
* @returns void
|
|
461
428
|
*/
|
|
429
|
+
|
|
462
430
|
protected _transplant(u: RedBlackTreeNode<K, V>, v: RedBlackTreeNode<K, V> | undefined): void {
|
|
463
431
|
if (!u.parent) {
|
|
464
432
|
this._setRoot(v);
|
|
@@ -474,37 +442,28 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
474
442
|
}
|
|
475
443
|
|
|
476
444
|
/**
|
|
477
|
-
*
|
|
478
|
-
*
|
|
479
|
-
*
|
|
480
|
-
*
|
|
481
|
-
* @param {RedBlackTreeNode<K, V> | undefined} z - The parameter `z` represents a node in the Red-Black Tree data
|
|
482
|
-
* structure. It can either be a valid node or `undefined`.
|
|
445
|
+
* (Protected) Restore red-black properties after insertion (recolor/rotate).
|
|
446
|
+
* @remarks Time O(log n), Space O(1)
|
|
447
|
+
* @param z - Recently inserted node.
|
|
448
|
+
* @returns void
|
|
483
449
|
*/
|
|
450
|
+
|
|
484
451
|
protected _insertFixup(z: RedBlackTreeNode<K, V> | undefined): void {
|
|
485
|
-
// Continue fixing the tree as long as the parent of z is red
|
|
486
452
|
while (z?.parent?.color === 'RED') {
|
|
487
|
-
// Check if the parent of z is the left child of its parent
|
|
488
453
|
if (z.parent === z.parent.parent?.left) {
|
|
489
|
-
// Case 1: The uncle (y) of z is red
|
|
490
454
|
const y = z.parent.parent.right;
|
|
491
455
|
if (y?.color === 'RED') {
|
|
492
|
-
// Set colors to restore properties of Red-Black Tree
|
|
493
456
|
z.parent.color = 'BLACK';
|
|
494
457
|
y.color = 'BLACK';
|
|
495
458
|
z.parent.parent.color = 'RED';
|
|
496
|
-
|
|
459
|
+
|
|
497
460
|
z = z.parent.parent;
|
|
498
461
|
} else {
|
|
499
|
-
// Case 2: The uncle (y) of z is black, and z is a right child
|
|
500
462
|
if (z === z.parent.right) {
|
|
501
|
-
// Perform a left rotation to transform the case into Case 3
|
|
502
463
|
z = z.parent;
|
|
503
464
|
this._leftRotate(z);
|
|
504
465
|
}
|
|
505
466
|
|
|
506
|
-
// Case 3: The uncle (y) of z is black, and z is a left child
|
|
507
|
-
// Adjust colors and perform a right rotation
|
|
508
467
|
if (z && this.isRealNode(z.parent) && this.isRealNode(z.parent.parent)) {
|
|
509
468
|
z.parent.color = 'BLACK';
|
|
510
469
|
z.parent.parent.color = 'RED';
|
|
@@ -512,8 +471,6 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
512
471
|
}
|
|
513
472
|
}
|
|
514
473
|
} else {
|
|
515
|
-
// Symmetric case for the right child (left and right exchanged)
|
|
516
|
-
// Follow the same logic as above with left and right exchanged
|
|
517
474
|
const y: RedBlackTreeNode<K, V> | undefined = z?.parent?.parent?.left ?? undefined;
|
|
518
475
|
if (y?.color === 'RED') {
|
|
519
476
|
z.parent.color = 'BLACK';
|
|
@@ -535,26 +492,20 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
535
492
|
}
|
|
536
493
|
}
|
|
537
494
|
|
|
538
|
-
// Ensure that the root is black after fixing
|
|
539
495
|
if (this.isRealNode(this._root)) this._root.color = 'BLACK';
|
|
540
496
|
}
|
|
541
497
|
|
|
542
498
|
/**
|
|
543
|
-
*
|
|
544
|
-
*
|
|
545
|
-
*
|
|
546
|
-
*
|
|
547
|
-
* the colors and performing rotations.
|
|
548
|
-
* @param {RedBlackTreeNode<K, V> | undefined} node - The `node` parameter represents a node in a binary tree. It can
|
|
549
|
-
* be either a valid node object or `undefined`.
|
|
550
|
-
* @returns The function does not return any value. It has a return type of `void`, which means it
|
|
551
|
-
* does not return anything.
|
|
499
|
+
* (Protected) Restore red-black properties after deletion (recolor/rotate).
|
|
500
|
+
* @remarks Time O(log n), Space O(1)
|
|
501
|
+
* @param node - Child that replaced the deleted node (may be undefined).
|
|
502
|
+
* @returns void
|
|
552
503
|
*/
|
|
504
|
+
|
|
553
505
|
protected _deleteFixup(node: RedBlackTreeNode<K, V> | undefined): void {
|
|
554
|
-
// Early exit condition
|
|
555
506
|
if (!node || node === this.root || node.color === 'BLACK') {
|
|
556
507
|
if (node) {
|
|
557
|
-
node.color = 'BLACK';
|
|
508
|
+
node.color = 'BLACK';
|
|
558
509
|
}
|
|
559
510
|
return;
|
|
560
511
|
}
|
|
@@ -563,13 +514,12 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
563
514
|
const parent: RedBlackTreeNode<K, V> | undefined = node.parent;
|
|
564
515
|
|
|
565
516
|
if (!parent) {
|
|
566
|
-
break;
|
|
517
|
+
break;
|
|
567
518
|
}
|
|
568
519
|
|
|
569
520
|
if (node === parent.left) {
|
|
570
521
|
let sibling = parent.right;
|
|
571
522
|
|
|
572
|
-
// Cases 1 and 2: Sibling is red or both children of sibling are black
|
|
573
523
|
if (sibling?.color === 'RED') {
|
|
574
524
|
sibling.color = 'BLACK';
|
|
575
525
|
parent.color = 'RED';
|
|
@@ -577,12 +527,10 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
577
527
|
sibling = parent.right;
|
|
578
528
|
}
|
|
579
529
|
|
|
580
|
-
// Case 3: Sibling's left child is black
|
|
581
530
|
if ((sibling?.left?.color ?? 'BLACK') === 'BLACK') {
|
|
582
531
|
if (sibling) sibling.color = 'RED';
|
|
583
532
|
node = parent;
|
|
584
533
|
} else {
|
|
585
|
-
// Case 4: Adjust colors and perform a right rotation
|
|
586
534
|
if (sibling?.left) sibling.left.color = 'BLACK';
|
|
587
535
|
if (sibling) sibling.color = parent.color;
|
|
588
536
|
parent.color = 'BLACK';
|
|
@@ -590,10 +538,8 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
590
538
|
node = this.root;
|
|
591
539
|
}
|
|
592
540
|
} else {
|
|
593
|
-
// Symmetric case for the right child (left and right exchanged)
|
|
594
541
|
let sibling = parent.left;
|
|
595
542
|
|
|
596
|
-
// Cases 1 and 2: Sibling is red or both children of sibling are black
|
|
597
543
|
if (sibling?.color === 'RED') {
|
|
598
544
|
sibling.color = 'BLACK';
|
|
599
545
|
if (parent) parent.color = 'RED';
|
|
@@ -601,12 +547,10 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
601
547
|
if (parent) sibling = parent.left;
|
|
602
548
|
}
|
|
603
549
|
|
|
604
|
-
// Case 3: Sibling's left child is black
|
|
605
550
|
if ((sibling?.right?.color ?? 'BLACK') === 'BLACK') {
|
|
606
551
|
if (sibling) sibling.color = 'RED';
|
|
607
552
|
node = parent;
|
|
608
553
|
} else {
|
|
609
|
-
// Case 4: Adjust colors and perform a left rotation
|
|
610
554
|
if (sibling?.right) sibling.right.color = 'BLACK';
|
|
611
555
|
if (sibling) sibling.color = parent.color;
|
|
612
556
|
if (parent) parent.color = 'BLACK';
|
|
@@ -616,21 +560,18 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
616
560
|
}
|
|
617
561
|
}
|
|
618
562
|
|
|
619
|
-
// Ensure that the final node (possibly the root) is black
|
|
620
563
|
if (node) {
|
|
621
564
|
node.color = 'BLACK';
|
|
622
565
|
}
|
|
623
566
|
}
|
|
624
567
|
|
|
625
568
|
/**
|
|
626
|
-
*
|
|
627
|
-
*
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
* @param {RedBlackTreeNode<K, V> | undefined} x - The parameter `x` is of type `RedBlackTreeNode<K, V> | undefined`. It represents a
|
|
631
|
-
* node in a binary tree or `undefined` if there is no node.
|
|
632
|
-
* @returns void, which means it does not return any value.
|
|
569
|
+
* (Protected) Perform a left rotation around x.
|
|
570
|
+
* @remarks Time O(1), Space O(1)
|
|
571
|
+
* @param x - Pivot node to rotate around.
|
|
572
|
+
* @returns void
|
|
633
573
|
*/
|
|
574
|
+
|
|
634
575
|
protected _leftRotate(x: RedBlackTreeNode<K, V> | undefined): void {
|
|
635
576
|
if (!x || !x.right) {
|
|
636
577
|
return;
|
|
@@ -658,14 +599,12 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
658
599
|
}
|
|
659
600
|
|
|
660
601
|
/**
|
|
661
|
-
*
|
|
662
|
-
*
|
|
663
|
-
*
|
|
664
|
-
*
|
|
665
|
-
* @param {RedBlackTreeNode<K, V> | undefined} y - The parameter `y` is of type `RedBlackTreeNode<K, V> | undefined`. It represents a
|
|
666
|
-
* node in a binary tree or `undefined` if there is no node.
|
|
667
|
-
* @returns void, which means it does not return any value.
|
|
602
|
+
* (Protected) Perform a right rotation around y.
|
|
603
|
+
* @remarks Time O(1), Space O(1)
|
|
604
|
+
* @param y - Pivot node to rotate around.
|
|
605
|
+
* @returns void
|
|
668
606
|
*/
|
|
607
|
+
|
|
669
608
|
protected _rightRotate(y: RedBlackTreeNode<K, V> | undefined): void {
|
|
670
609
|
if (!y || !y.left) {
|
|
671
610
|
return;
|