min-heap-typed 2.0.5 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data-structures/base/iterable-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 +602 -873
- 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 +1 -0
- package/dist/utils/utils.d.ts +1 -1
- package/dist/utils/utils.js +2 -1
- 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 +196 -217
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +188 -102
- package/src/data-structures/binary-tree/avl-tree.ts +237 -206
- package/src/data-structures/binary-tree/binary-tree.ts +665 -896
- package/src/data-structures/binary-tree/bst.ts +565 -572
- package/src/data-structures/binary-tree/red-black-tree.ts +157 -223
- package/src/data-structures/binary-tree/tree-counter.ts +195 -219
- package/src/data-structures/binary-tree/tree-multi-map.ts +127 -98
- 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 +2 -0
- package/src/utils/utils.ts +9 -14
|
@@ -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
|
+
* RRRRRRRRRRRRRRRRRRRed-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,8 @@ 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
|
-
implements IBinaryTree<K, V, R, MK, MV, MR>
|
|
100
|
-
{
|
|
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
|
-
*/
|
|
143
|
+
|
|
144
|
+
export class RedBlackTree<K = any, V = any, R = any> extends BST<K, V, R> implements IBinaryTree<K, V, R> {
|
|
112
145
|
constructor(
|
|
113
146
|
keysNodesEntriesOrRaws: Iterable<
|
|
114
147
|
K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | R
|
|
@@ -126,60 +159,34 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
126
159
|
|
|
127
160
|
protected override _root: RedBlackTreeNode<K, V> | undefined;
|
|
128
161
|
|
|
162
|
+
/**
|
|
163
|
+
* Get the current root node.
|
|
164
|
+
* @remarks Time O(1), Space O(1)
|
|
165
|
+
* @returns Root node, or undefined.
|
|
166
|
+
*/
|
|
129
167
|
override get root(): RedBlackTreeNode<K, V> | undefined {
|
|
130
168
|
return this._root;
|
|
131
169
|
}
|
|
132
170
|
|
|
133
171
|
/**
|
|
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.
|
|
172
|
+
* Create a red-black node for the given key/value (value ignored in map mode).
|
|
173
|
+
* @remarks Time O(1), Space O(1)
|
|
174
|
+
* @param key - See parameter type for details.
|
|
175
|
+
* @param [value] - See parameter type for details.
|
|
176
|
+
* @param color - See parameter type for details.
|
|
177
|
+
* @returns A new RedBlackTreeNode instance.
|
|
149
178
|
*/
|
|
150
|
-
override
|
|
179
|
+
override _createNode(key: K, value?: V, color: RBTNColor = 'BLACK'): RedBlackTreeNode<K, V> {
|
|
151
180
|
return new RedBlackTreeNode<K, V>(key, this._isMapMode ? undefined : value, color);
|
|
152
181
|
}
|
|
153
182
|
|
|
154
183
|
/**
|
|
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.
|
|
184
|
+
* Type guard: check whether the input is a RedBlackTreeNode.
|
|
185
|
+
* @remarks Time O(1), Space O(1)
|
|
186
|
+
* @param keyNodeOrEntry - See parameter type for details.
|
|
187
|
+
* @returns True if the value is a RedBlackTreeNode.
|
|
162
188
|
*/
|
|
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
189
|
|
|
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
190
|
override isNode(
|
|
184
191
|
keyNodeOrEntry: K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined
|
|
185
192
|
): keyNodeOrEntry is RedBlackTreeNode<K, V> {
|
|
@@ -187,31 +194,22 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
187
194
|
}
|
|
188
195
|
|
|
189
196
|
/**
|
|
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.
|
|
197
|
+
* Remove all nodes and clear the key→value store (if in map mode).
|
|
198
|
+
* @remarks Time O(n), Space O(1)
|
|
199
|
+
* @returns void
|
|
195
200
|
*/
|
|
201
|
+
|
|
196
202
|
override clear() {
|
|
197
203
|
super.clear();
|
|
198
204
|
this._root = this.NIL;
|
|
199
205
|
}
|
|
200
206
|
|
|
201
207
|
/**
|
|
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.
|
|
208
|
+
* Insert or replace an entry using BST order and red-black fix-up.
|
|
209
|
+
* @remarks Time O(log n), Space O(1)
|
|
210
|
+
* @param keyNodeOrEntry - Key, node, or [key, value] entry to insert.
|
|
211
|
+
* @param [value]- See parameter type for details.
|
|
212
|
+
* @returns True if inserted or updated; false if ignored.
|
|
215
213
|
*/
|
|
216
214
|
override add(
|
|
217
215
|
keyNodeOrEntry: K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
|
|
@@ -223,7 +221,6 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
223
221
|
const insertStatus = this._insert(newNode);
|
|
224
222
|
|
|
225
223
|
if (insertStatus === 'CREATED') {
|
|
226
|
-
// Ensure the root is black
|
|
227
224
|
if (this.isRealNode(this._root)) {
|
|
228
225
|
this._root.color = 'BLACK';
|
|
229
226
|
} else {
|
|
@@ -241,19 +238,12 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
241
238
|
}
|
|
242
239
|
|
|
243
240
|
/**
|
|
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.
|
|
241
|
+
* Delete a node by key/node/entry and rebalance as needed.
|
|
242
|
+
* @remarks Time O(log n), Space O(1)
|
|
243
|
+
* @param keyNodeOrEntry - Key, node, or [key, value] entry identifying the node to delete.
|
|
244
|
+
* @returns Array with deletion metadata (removed node, rebalancing hint if any).
|
|
256
245
|
*/
|
|
246
|
+
|
|
257
247
|
override delete(
|
|
258
248
|
keyNodeOrEntry: K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined
|
|
259
249
|
): BinaryTreeDeleteResult<RedBlackTreeNode<K, V>>[] {
|
|
@@ -310,7 +300,6 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
310
300
|
if (this._isMapMode) this._store.delete(nodeToDelete.key);
|
|
311
301
|
this._size--;
|
|
312
302
|
|
|
313
|
-
// If the original color was black, fix the tree
|
|
314
303
|
if (originalColor === 'BLACK') {
|
|
315
304
|
this._deleteFixup(replacementNode);
|
|
316
305
|
}
|
|
@@ -321,60 +310,52 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
321
310
|
}
|
|
322
311
|
|
|
323
312
|
/**
|
|
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.
|
|
313
|
+
* Transform entries into a like-kind red-black tree with possibly different key/value types.
|
|
314
|
+
* @remarks Time O(n), Space O(n)
|
|
315
|
+
* @template MK
|
|
316
|
+
* @template MV
|
|
317
|
+
* @template MR
|
|
318
|
+
* @param callback - Mapping function from (key, value, index, tree) to a new [key, value].
|
|
319
|
+
* @param [options] - See parameter type for details.
|
|
320
|
+
* @param [thisArg] - See parameter type for details.
|
|
321
|
+
* @returns A new RedBlackTree with mapped entries.
|
|
342
322
|
*/
|
|
343
|
-
|
|
323
|
+
|
|
324
|
+
override map<MK = K, MV = V, MR = any>(
|
|
344
325
|
callback: EntryCallback<K, V | undefined, [MK, MV]>,
|
|
345
|
-
options?:
|
|
346
|
-
thisArg?:
|
|
326
|
+
options?: Partial<BinaryTreeOptions<MK, MV, MR>>,
|
|
327
|
+
thisArg?: unknown
|
|
347
328
|
): RedBlackTree<MK, MV, MR> {
|
|
348
|
-
const
|
|
329
|
+
const out = this._createLike<MK, MV, MR>([], options);
|
|
330
|
+
|
|
349
331
|
let index = 0;
|
|
350
332
|
for (const [key, value] of this) {
|
|
351
|
-
|
|
333
|
+
out.add(callback.call(thisArg, key, value, index++, this));
|
|
352
334
|
}
|
|
353
|
-
return
|
|
335
|
+
return out;
|
|
354
336
|
}
|
|
355
337
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
override
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
338
|
+
protected override _createInstance<TK = K, TV = V, TR = R>(options?: Partial<RedBlackTreeOptions<TK, TV, TR>>): this {
|
|
339
|
+
const Ctor = this.constructor as unknown as new (
|
|
340
|
+
iter?: Iterable<TK | RedBlackTreeNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR>,
|
|
341
|
+
opts?: RedBlackTreeOptions<TK, TV, TR>
|
|
342
|
+
) => RedBlackTree<TK, TV, TR>;
|
|
343
|
+
return new Ctor([], { ...this._snapshotOptions<TK, TV, TR>(), ...(options ?? {}) }) as unknown as this;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
protected override _createLike<TK = K, TV = V, TR = R>(
|
|
347
|
+
iter: Iterable<
|
|
348
|
+
TK | RedBlackTreeNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR
|
|
349
|
+
> = [],
|
|
350
|
+
options?: Partial<RedBlackTreeOptions<TK, TV, TR>>
|
|
351
|
+
): RedBlackTree<TK, TV, TR> {
|
|
352
|
+
const Ctor = this.constructor as unknown as new (
|
|
353
|
+
iter?: Iterable<TK | RedBlackTreeNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR>,
|
|
354
|
+
opts?: RedBlackTreeOptions<TK, TV, TR>
|
|
355
|
+
) => RedBlackTree<TK, TV, TR>;
|
|
356
|
+
return new Ctor(iter, { ...this._snapshotOptions<TK, TV, TR>(), ...(options ?? {}) });
|
|
368
357
|
}
|
|
369
358
|
|
|
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
359
|
protected override _setRoot(v: RedBlackTreeNode<K, V> | undefined) {
|
|
379
360
|
if (v) {
|
|
380
361
|
v.parent = undefined;
|
|
@@ -382,18 +363,6 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
382
363
|
this._root = v;
|
|
383
364
|
}
|
|
384
365
|
|
|
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
366
|
protected override _replaceNode(
|
|
398
367
|
oldNode: RedBlackTreeNode<K, V>,
|
|
399
368
|
newNode: RedBlackTreeNode<K, V>
|
|
@@ -404,17 +373,12 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
404
373
|
}
|
|
405
374
|
|
|
406
375
|
/**
|
|
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.
|
|
376
|
+
* (Protected) Standard BST insert followed by red-black fix-up.
|
|
377
|
+
* @remarks Time O(log n), Space O(1)
|
|
378
|
+
* @param node - Node to insert.
|
|
379
|
+
* @returns Status string: 'CREATED' or 'UPDATED'.
|
|
417
380
|
*/
|
|
381
|
+
|
|
418
382
|
protected _insert(node: RedBlackTreeNode<K, V>): CRUD {
|
|
419
383
|
let current = this.root;
|
|
420
384
|
let parent: RedBlackTreeNode<K, V> | undefined = undefined;
|
|
@@ -451,14 +415,13 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
451
415
|
}
|
|
452
416
|
|
|
453
417
|
/**
|
|
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`.
|
|
418
|
+
* (Protected) Transplant a subtree in place of another during deletion.
|
|
419
|
+
* @remarks Time O(1), Space O(1)
|
|
420
|
+
* @param u - Node to replace.
|
|
421
|
+
* @param v - Replacement subtree root (may be undefined).
|
|
422
|
+
* @returns void
|
|
461
423
|
*/
|
|
424
|
+
|
|
462
425
|
protected _transplant(u: RedBlackTreeNode<K, V>, v: RedBlackTreeNode<K, V> | undefined): void {
|
|
463
426
|
if (!u.parent) {
|
|
464
427
|
this._setRoot(v);
|
|
@@ -474,37 +437,28 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
474
437
|
}
|
|
475
438
|
|
|
476
439
|
/**
|
|
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`.
|
|
440
|
+
* (Protected) Restore red-black properties after insertion (recolor/rotate).
|
|
441
|
+
* @remarks Time O(log n), Space O(1)
|
|
442
|
+
* @param z - Recently inserted node.
|
|
443
|
+
* @returns void
|
|
483
444
|
*/
|
|
445
|
+
|
|
484
446
|
protected _insertFixup(z: RedBlackTreeNode<K, V> | undefined): void {
|
|
485
|
-
// Continue fixing the tree as long as the parent of z is red
|
|
486
447
|
while (z?.parent?.color === 'RED') {
|
|
487
|
-
// Check if the parent of z is the left child of its parent
|
|
488
448
|
if (z.parent === z.parent.parent?.left) {
|
|
489
|
-
// Case 1: The uncle (y) of z is red
|
|
490
449
|
const y = z.parent.parent.right;
|
|
491
450
|
if (y?.color === 'RED') {
|
|
492
|
-
// Set colors to restore properties of Red-Black Tree
|
|
493
451
|
z.parent.color = 'BLACK';
|
|
494
452
|
y.color = 'BLACK';
|
|
495
453
|
z.parent.parent.color = 'RED';
|
|
496
|
-
|
|
454
|
+
|
|
497
455
|
z = z.parent.parent;
|
|
498
456
|
} else {
|
|
499
|
-
// Case 2: The uncle (y) of z is black, and z is a right child
|
|
500
457
|
if (z === z.parent.right) {
|
|
501
|
-
// Perform a left rotation to transform the case into Case 3
|
|
502
458
|
z = z.parent;
|
|
503
459
|
this._leftRotate(z);
|
|
504
460
|
}
|
|
505
461
|
|
|
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
462
|
if (z && this.isRealNode(z.parent) && this.isRealNode(z.parent.parent)) {
|
|
509
463
|
z.parent.color = 'BLACK';
|
|
510
464
|
z.parent.parent.color = 'RED';
|
|
@@ -512,8 +466,6 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
512
466
|
}
|
|
513
467
|
}
|
|
514
468
|
} 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
469
|
const y: RedBlackTreeNode<K, V> | undefined = z?.parent?.parent?.left ?? undefined;
|
|
518
470
|
if (y?.color === 'RED') {
|
|
519
471
|
z.parent.color = 'BLACK';
|
|
@@ -535,26 +487,20 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
535
487
|
}
|
|
536
488
|
}
|
|
537
489
|
|
|
538
|
-
// Ensure that the root is black after fixing
|
|
539
490
|
if (this.isRealNode(this._root)) this._root.color = 'BLACK';
|
|
540
491
|
}
|
|
541
492
|
|
|
542
493
|
/**
|
|
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.
|
|
494
|
+
* (Protected) Restore red-black properties after deletion (recolor/rotate).
|
|
495
|
+
* @remarks Time O(log n), Space O(1)
|
|
496
|
+
* @param node - Child that replaced the deleted node (may be undefined).
|
|
497
|
+
* @returns void
|
|
552
498
|
*/
|
|
499
|
+
|
|
553
500
|
protected _deleteFixup(node: RedBlackTreeNode<K, V> | undefined): void {
|
|
554
|
-
// Early exit condition
|
|
555
501
|
if (!node || node === this.root || node.color === 'BLACK') {
|
|
556
502
|
if (node) {
|
|
557
|
-
node.color = 'BLACK';
|
|
503
|
+
node.color = 'BLACK';
|
|
558
504
|
}
|
|
559
505
|
return;
|
|
560
506
|
}
|
|
@@ -563,13 +509,12 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
563
509
|
const parent: RedBlackTreeNode<K, V> | undefined = node.parent;
|
|
564
510
|
|
|
565
511
|
if (!parent) {
|
|
566
|
-
break;
|
|
512
|
+
break;
|
|
567
513
|
}
|
|
568
514
|
|
|
569
515
|
if (node === parent.left) {
|
|
570
516
|
let sibling = parent.right;
|
|
571
517
|
|
|
572
|
-
// Cases 1 and 2: Sibling is red or both children of sibling are black
|
|
573
518
|
if (sibling?.color === 'RED') {
|
|
574
519
|
sibling.color = 'BLACK';
|
|
575
520
|
parent.color = 'RED';
|
|
@@ -577,12 +522,10 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
577
522
|
sibling = parent.right;
|
|
578
523
|
}
|
|
579
524
|
|
|
580
|
-
// Case 3: Sibling's left child is black
|
|
581
525
|
if ((sibling?.left?.color ?? 'BLACK') === 'BLACK') {
|
|
582
526
|
if (sibling) sibling.color = 'RED';
|
|
583
527
|
node = parent;
|
|
584
528
|
} else {
|
|
585
|
-
// Case 4: Adjust colors and perform a right rotation
|
|
586
529
|
if (sibling?.left) sibling.left.color = 'BLACK';
|
|
587
530
|
if (sibling) sibling.color = parent.color;
|
|
588
531
|
parent.color = 'BLACK';
|
|
@@ -590,10 +533,8 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
590
533
|
node = this.root;
|
|
591
534
|
}
|
|
592
535
|
} else {
|
|
593
|
-
// Symmetric case for the right child (left and right exchanged)
|
|
594
536
|
let sibling = parent.left;
|
|
595
537
|
|
|
596
|
-
// Cases 1 and 2: Sibling is red or both children of sibling are black
|
|
597
538
|
if (sibling?.color === 'RED') {
|
|
598
539
|
sibling.color = 'BLACK';
|
|
599
540
|
if (parent) parent.color = 'RED';
|
|
@@ -601,12 +542,10 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
601
542
|
if (parent) sibling = parent.left;
|
|
602
543
|
}
|
|
603
544
|
|
|
604
|
-
// Case 3: Sibling's left child is black
|
|
605
545
|
if ((sibling?.right?.color ?? 'BLACK') === 'BLACK') {
|
|
606
546
|
if (sibling) sibling.color = 'RED';
|
|
607
547
|
node = parent;
|
|
608
548
|
} else {
|
|
609
|
-
// Case 4: Adjust colors and perform a left rotation
|
|
610
549
|
if (sibling?.right) sibling.right.color = 'BLACK';
|
|
611
550
|
if (sibling) sibling.color = parent.color;
|
|
612
551
|
if (parent) parent.color = 'BLACK';
|
|
@@ -616,21 +555,18 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
616
555
|
}
|
|
617
556
|
}
|
|
618
557
|
|
|
619
|
-
// Ensure that the final node (possibly the root) is black
|
|
620
558
|
if (node) {
|
|
621
559
|
node.color = 'BLACK';
|
|
622
560
|
}
|
|
623
561
|
}
|
|
624
562
|
|
|
625
563
|
/**
|
|
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.
|
|
564
|
+
* (Protected) Perform a left rotation around x.
|
|
565
|
+
* @remarks Time O(1), Space O(1)
|
|
566
|
+
* @param x - Pivot node to rotate around.
|
|
567
|
+
* @returns void
|
|
633
568
|
*/
|
|
569
|
+
|
|
634
570
|
protected _leftRotate(x: RedBlackTreeNode<K, V> | undefined): void {
|
|
635
571
|
if (!x || !x.right) {
|
|
636
572
|
return;
|
|
@@ -658,14 +594,12 @@ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR =
|
|
|
658
594
|
}
|
|
659
595
|
|
|
660
596
|
/**
|
|
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.
|
|
597
|
+
* (Protected) Perform a right rotation around y.
|
|
598
|
+
* @remarks Time O(1), Space O(1)
|
|
599
|
+
* @param y - Pivot node to rotate around.
|
|
600
|
+
* @returns void
|
|
668
601
|
*/
|
|
602
|
+
|
|
669
603
|
protected _rightRotate(y: RedBlackTreeNode<K, V> | undefined): void {
|
|
670
604
|
if (!y || !y.left) {
|
|
671
605
|
return;
|