min-heap-typed 1.50.5 → 1.50.7
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/binary-tree/avl-tree-multi-map.d.ts +1 -0
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +3 -0
- package/dist/data-structures/binary-tree/binary-tree.js +32 -28
- package/dist/data-structures/binary-tree/bst.js +17 -17
- package/dist/data-structures/binary-tree/rb-tree.d.ts +158 -141
- package/dist/data-structures/binary-tree/rb-tree.js +416 -396
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +1 -0
- package/dist/data-structures/binary-tree/tree-multi-map.js +84 -76
- package/dist/types/common.d.ts +6 -0
- package/dist/types/common.js +8 -1
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +5 -1
- package/src/data-structures/binary-tree/avl-tree.ts +1 -1
- package/src/data-structures/binary-tree/binary-tree.ts +31 -29
- package/src/data-structures/binary-tree/bst.ts +18 -18
- package/src/data-structures/binary-tree/rb-tree.ts +436 -405
- package/src/data-structures/binary-tree/tree-multi-map.ts +85 -82
- package/src/types/common.ts +7 -0
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* data-structure-typed
|
|
4
|
-
*
|
|
5
|
-
* @author Tyler Zeng
|
|
6
|
-
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
7
|
-
* @license MIT License
|
|
8
|
-
*/
|
|
9
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
3
|
exports.RedBlackTree = exports.RedBlackTreeNode = void 0;
|
|
11
4
|
const types_1 = require("../../types");
|
|
@@ -28,7 +21,7 @@ class RedBlackTreeNode extends bst_1.BSTNode {
|
|
|
28
21
|
}
|
|
29
22
|
/**
|
|
30
23
|
* The function returns the color value of a variable.
|
|
31
|
-
* @returns The color value stored in the
|
|
24
|
+
* @returns The color value stored in the private variable `_color`.
|
|
32
25
|
*/
|
|
33
26
|
get color() {
|
|
34
27
|
return this._color;
|
|
@@ -42,63 +35,48 @@ class RedBlackTreeNode extends bst_1.BSTNode {
|
|
|
42
35
|
}
|
|
43
36
|
}
|
|
44
37
|
exports.RedBlackTreeNode = RedBlackTreeNode;
|
|
45
|
-
/**
|
|
46
|
-
* 1. Each node is either red or black.
|
|
47
|
-
* 2. The root node is always black.
|
|
48
|
-
* 3. Leaf nodes are typically Sentinel nodes and are considered black.
|
|
49
|
-
* 4. Red nodes must have black children.
|
|
50
|
-
* 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.
|
|
51
|
-
*/
|
|
52
38
|
class RedBlackTree extends bst_1.BST {
|
|
53
39
|
/**
|
|
54
|
-
* This is the constructor function for a Red-Black Tree data structure in TypeScript
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* only a subset of the properties defined in the `RBTreeOptions` interface.
|
|
40
|
+
* This is the constructor function for a Red-Black Tree data structure in TypeScript.
|
|
41
|
+
* @param keysOrNodesOrEntries - The `keysOrNodesOrEntries` parameter is an iterable object that can
|
|
42
|
+
* contain keys, nodes, or entries. It is used to initialize the RBTree with the provided keys,
|
|
43
|
+
* nodes, or entries.
|
|
44
|
+
* @param [options] - The `options` parameter is an optional object that can be passed to the
|
|
45
|
+
* constructor. It allows you to customize the behavior of the RBTree. It can include properties such
|
|
46
|
+
* as `compareKeys`, `compareValues`, `allowDuplicates`, etc. These properties define how the RBTree
|
|
47
|
+
* should compare keys and
|
|
63
48
|
*/
|
|
64
49
|
constructor(keysOrNodesOrEntries = [], options) {
|
|
65
50
|
super([], options);
|
|
66
|
-
this.
|
|
67
|
-
this.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
51
|
+
this._SENTINEL = new RedBlackTreeNode(NaN);
|
|
52
|
+
this._root = this.SENTINEL;
|
|
53
|
+
if (keysOrNodesOrEntries) {
|
|
54
|
+
this.addMany(keysOrNodesOrEntries);
|
|
55
|
+
}
|
|
71
56
|
}
|
|
72
57
|
/**
|
|
73
|
-
* The function returns the value of the
|
|
74
|
-
* @returns The method is returning the value of the `
|
|
58
|
+
* The function returns the value of the _SENTINEL property.
|
|
59
|
+
* @returns The method is returning the value of the `_SENTINEL` property.
|
|
75
60
|
*/
|
|
76
|
-
get
|
|
77
|
-
return this.
|
|
61
|
+
get SENTINEL() {
|
|
62
|
+
return this._SENTINEL;
|
|
78
63
|
}
|
|
79
64
|
/**
|
|
80
|
-
* The function returns the root node.
|
|
81
|
-
* @returns The root node of the
|
|
65
|
+
* The function returns the root node of a tree or undefined if there is no root.
|
|
66
|
+
* @returns The root node of the tree structure, or undefined if there is no root node.
|
|
82
67
|
*/
|
|
83
68
|
get root() {
|
|
84
69
|
return this._root;
|
|
85
70
|
}
|
|
86
|
-
/**
|
|
87
|
-
* The function returns the size of an object.
|
|
88
|
-
* @returns The size of the object, which is a number.
|
|
89
|
-
*/
|
|
90
|
-
get size() {
|
|
91
|
-
return this._size;
|
|
92
|
-
}
|
|
93
71
|
/**
|
|
94
72
|
* The function creates a new Red-Black Tree node with the specified key, value, and color.
|
|
95
|
-
* @param {K} key - The key parameter
|
|
96
|
-
*
|
|
73
|
+
* @param {K} key - The key parameter represents the key of the node being created. It is of type K,
|
|
74
|
+
* which is a generic type representing the key's data type.
|
|
97
75
|
* @param {V} [value] - The `value` parameter is an optional parameter that represents the value
|
|
98
|
-
* associated with the node. It is
|
|
99
|
-
* specific type when using the `createNode` method.
|
|
76
|
+
* associated with the key in the node. It is not required and can be omitted if not needed.
|
|
100
77
|
* @param {RBTNColor} color - The "color" parameter is used to specify the color of the node in a
|
|
101
|
-
* Red-Black Tree. It
|
|
78
|
+
* Red-Black Tree. It is an optional parameter with a default value of "RBTNColor.BLACK". The color
|
|
79
|
+
* can be either "RBTNColor.RED" or "RBTNColor.BLACK".
|
|
102
80
|
* @returns The method is returning a new instance of a RedBlackTreeNode with the specified key,
|
|
103
81
|
* value, and color.
|
|
104
82
|
*/
|
|
@@ -106,22 +84,28 @@ class RedBlackTree extends bst_1.BST {
|
|
|
106
84
|
return new RedBlackTreeNode(key, value, color);
|
|
107
85
|
}
|
|
108
86
|
/**
|
|
109
|
-
* The function creates a Red-Black Tree with the
|
|
110
|
-
* @param
|
|
111
|
-
*
|
|
112
|
-
*
|
|
87
|
+
* The function creates a Red-Black Tree with the given options and returns it.
|
|
88
|
+
* @param [options] - The `options` parameter is an optional object that contains configuration
|
|
89
|
+
* options for creating the Red-Black Tree. It is of type `RBTreeOptions<K>`, where `K` represents
|
|
90
|
+
* the type of keys in the tree.
|
|
113
91
|
* @returns a new instance of a RedBlackTree object.
|
|
114
92
|
*/
|
|
115
93
|
createTree(options) {
|
|
116
94
|
return new RedBlackTree([], Object.assign({ iterationType: this.iterationType }, options));
|
|
117
95
|
}
|
|
118
96
|
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
*
|
|
124
|
-
*
|
|
97
|
+
* Time Complexity: O(1)
|
|
98
|
+
* Space Complexity: O(1)
|
|
99
|
+
*/
|
|
100
|
+
/**
|
|
101
|
+
* Time Complexity: O(1)
|
|
102
|
+
* Space Complexity: O(1)
|
|
103
|
+
*
|
|
104
|
+
* The function `keyValueOrEntryToNode` takes a key, value, or entry and returns a node if it is
|
|
105
|
+
* valid, otherwise it returns undefined.
|
|
106
|
+
* @param {KeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntry - The key, value, or entry to convert.
|
|
107
|
+
* @param {V} [value] - The value associated with the key (if `keyOrNodeOrEntry` is a key).
|
|
108
|
+
* @returns {NODE | undefined} - The corresponding Red-Black Tree node, or `undefined` if conversion fails.
|
|
125
109
|
*/
|
|
126
110
|
keyValueOrEntryToNode(keyOrNodeOrEntry, value) {
|
|
127
111
|
let node;
|
|
@@ -149,166 +133,84 @@ class RedBlackTree extends bst_1.BST {
|
|
|
149
133
|
return node;
|
|
150
134
|
}
|
|
151
135
|
/**
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
|
|
136
|
+
* Time Complexity: O(1)
|
|
137
|
+
* Space Complexity: O(1)
|
|
138
|
+
* /
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Time Complexity: O(1)
|
|
142
|
+
* Space Complexity: O(1)
|
|
143
|
+
*
|
|
144
|
+
* The function checks if the input is an instance of the RedBlackTreeNode class.
|
|
145
|
+
* @param {KeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntry - The object to check.
|
|
146
|
+
* @returns {boolean} - `true` if the object is a Red-Black Tree node, `false` otherwise.
|
|
156
147
|
*/
|
|
157
148
|
isNode(keyOrNodeOrEntry) {
|
|
158
149
|
return keyOrNodeOrEntry instanceof RedBlackTreeNode;
|
|
159
150
|
}
|
|
160
151
|
/**
|
|
152
|
+
* Time Complexity: O(1)
|
|
153
|
+
* Space Complexity: O(1)
|
|
154
|
+
*/
|
|
155
|
+
/**
|
|
156
|
+
* Time Complexity: O(1)
|
|
157
|
+
* Space Complexity: O(1)
|
|
158
|
+
*
|
|
161
159
|
* The function checks if a given node is a real node in a Red-Black Tree.
|
|
162
160
|
* @param {NODE | undefined} node - The `node` parameter is of type `NODE | undefined`, which means
|
|
163
161
|
* it can either be of type `NODE` or `undefined`.
|
|
164
162
|
* @returns a boolean value.
|
|
165
163
|
*/
|
|
166
164
|
isRealNode(node) {
|
|
167
|
-
if (node === this.
|
|
165
|
+
if (node === this.SENTINEL || node === undefined)
|
|
168
166
|
return false;
|
|
169
167
|
return node instanceof RedBlackTreeNode;
|
|
170
168
|
}
|
|
171
169
|
/**
|
|
172
170
|
* Time Complexity: O(log n)
|
|
173
171
|
* Space Complexity: O(1)
|
|
174
|
-
* On average (where n is the number of nodes in the tree)
|
|
175
172
|
*/
|
|
176
173
|
/**
|
|
177
174
|
* Time Complexity: O(log n)
|
|
178
175
|
* Space Complexity: O(1)
|
|
179
176
|
*
|
|
180
|
-
* The `
|
|
181
|
-
*
|
|
182
|
-
* @param
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
177
|
+
* The `getNode` function retrieves a node from a Red-Black Tree based on the provided identifier and
|
|
178
|
+
* callback function.
|
|
179
|
+
* @param {ReturnType<C> | undefined} identifier - The `identifier` parameter is the value or key
|
|
180
|
+
* that you want to search for in the binary search tree. It can be of any type that is compatible
|
|
181
|
+
* with the type of nodes in the tree.
|
|
182
|
+
* @param {C} callback - The `callback` parameter is a function that will be called for each node in
|
|
183
|
+
* the tree. It is used to determine whether a node matches the given identifier. The `callback`
|
|
184
|
+
* function should take a node as its parameter and return a value that can be compared to the
|
|
185
|
+
* `identifier` parameter.
|
|
186
|
+
* @param beginRoot - The `beginRoot` parameter is the starting point for the search in the binary
|
|
187
|
+
* search tree. It can be either a key or a node. If it is a key, it will be converted to a node
|
|
188
|
+
* using the `ensureNode` method. If it is not provided, the `root`
|
|
189
|
+
* @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
|
|
190
|
+
* be performed when searching for nodes in the binary search tree. It is an optional parameter and
|
|
191
|
+
* its default value is taken from the `iterationType` property of the class.
|
|
192
|
+
* @returns The method is returning a value of type `NODE | null | undefined`.
|
|
187
193
|
*/
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if (
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
newNode.right = this._Sentinel;
|
|
194
|
-
let y = undefined;
|
|
195
|
-
let x = this.root;
|
|
196
|
-
while (x !== this._Sentinel) {
|
|
197
|
-
y = x;
|
|
198
|
-
if (x) {
|
|
199
|
-
if (newNode.key < x.key) {
|
|
200
|
-
x = x.left;
|
|
201
|
-
}
|
|
202
|
-
else if (newNode.key > x.key) {
|
|
203
|
-
x = x === null || x === void 0 ? void 0 : x.right;
|
|
204
|
-
}
|
|
205
|
-
else {
|
|
206
|
-
if (newNode !== x) {
|
|
207
|
-
this._replaceNode(x, newNode);
|
|
208
|
-
}
|
|
209
|
-
return false;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
newNode.parent = y;
|
|
214
|
-
if (y === undefined) {
|
|
215
|
-
this._setRoot(newNode);
|
|
216
|
-
}
|
|
217
|
-
else if (newNode.key < y.key) {
|
|
218
|
-
y.left = newNode;
|
|
219
|
-
}
|
|
220
|
-
else {
|
|
221
|
-
y.right = newNode;
|
|
222
|
-
}
|
|
223
|
-
if (newNode.parent === undefined) {
|
|
224
|
-
newNode.color = types_1.RBTNColor.BLACK;
|
|
225
|
-
this._size++;
|
|
226
|
-
return false;
|
|
227
|
-
}
|
|
228
|
-
if (newNode.parent.parent === undefined) {
|
|
229
|
-
this._size++;
|
|
230
|
-
return false;
|
|
231
|
-
}
|
|
232
|
-
this._fixInsert(newNode);
|
|
233
|
-
this._size++;
|
|
234
|
-
return true;
|
|
194
|
+
getNode(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
|
|
195
|
+
var _a;
|
|
196
|
+
if (identifier instanceof RedBlackTreeNode)
|
|
197
|
+
callback = (node => node);
|
|
198
|
+
return (_a = super.getNodes(identifier, callback, true, beginRoot, iterationType)[0]) !== null && _a !== void 0 ? _a : undefined;
|
|
235
199
|
}
|
|
236
200
|
/**
|
|
237
|
-
* Time Complexity: O(
|
|
201
|
+
* Time Complexity: O(1)
|
|
238
202
|
* Space Complexity: O(1)
|
|
239
203
|
*/
|
|
240
204
|
/**
|
|
241
|
-
* Time Complexity: O(
|
|
205
|
+
* Time Complexity: O(1)
|
|
242
206
|
* Space Complexity: O(1)
|
|
243
207
|
*
|
|
244
|
-
* The
|
|
245
|
-
*
|
|
246
|
-
* @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
|
|
247
|
-
* that you want to use to identify the node that you want to delete from the binary tree. It can be
|
|
248
|
-
* of any type that is returned by the callback function `C`. It can also be `null` or `undefined` if
|
|
249
|
-
* you don't want to
|
|
250
|
-
* @param {C} callback - The `callback` parameter is a function that takes a node of type `NODE` and
|
|
251
|
-
* returns a value of type `ReturnType<C>`. It is used to determine if a node should be deleted based
|
|
252
|
-
* on its identifier. The `callback` function is optional and defaults to `this._defaultOneParam
|
|
253
|
-
* @returns an array of `BinaryTreeDeleteResult<NODE>`.
|
|
208
|
+
* The "clear" function sets the root node of a data structure to a sentinel value and resets the
|
|
209
|
+
* size counter to zero.
|
|
254
210
|
*/
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
return ans;
|
|
259
|
-
const helper = (node) => {
|
|
260
|
-
let z = this._Sentinel;
|
|
261
|
-
let x, y;
|
|
262
|
-
while (node !== this._Sentinel) {
|
|
263
|
-
if (node && callback(node) === identifier) {
|
|
264
|
-
z = node;
|
|
265
|
-
}
|
|
266
|
-
if (node && identifier && callback(node) <= identifier) {
|
|
267
|
-
node = node.right;
|
|
268
|
-
}
|
|
269
|
-
else {
|
|
270
|
-
node = node === null || node === void 0 ? void 0 : node.left;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
if (z === this._Sentinel) {
|
|
274
|
-
this._size--;
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
y = z;
|
|
278
|
-
let yOriginalColor = y.color;
|
|
279
|
-
if (z.left === this._Sentinel) {
|
|
280
|
-
x = z.right;
|
|
281
|
-
this._rbTransplant(z, z.right);
|
|
282
|
-
}
|
|
283
|
-
else if (z.right === this._Sentinel) {
|
|
284
|
-
x = z.left;
|
|
285
|
-
this._rbTransplant(z, z.left);
|
|
286
|
-
}
|
|
287
|
-
else {
|
|
288
|
-
y = this.getLeftMost(z.right);
|
|
289
|
-
yOriginalColor = y.color;
|
|
290
|
-
x = y.right;
|
|
291
|
-
if (y.parent === z) {
|
|
292
|
-
x.parent = y;
|
|
293
|
-
}
|
|
294
|
-
else {
|
|
295
|
-
this._rbTransplant(y, y.right);
|
|
296
|
-
y.right = z.right;
|
|
297
|
-
y.right.parent = y;
|
|
298
|
-
}
|
|
299
|
-
this._rbTransplant(z, y);
|
|
300
|
-
y.left = z.left;
|
|
301
|
-
y.left.parent = y;
|
|
302
|
-
y.color = z.color;
|
|
303
|
-
}
|
|
304
|
-
if (yOriginalColor === types_1.RBTNColor.BLACK) {
|
|
305
|
-
this._fixDelete(x);
|
|
306
|
-
}
|
|
307
|
-
this._size--;
|
|
308
|
-
ans.push({ deleted: z, needBalanced: undefined });
|
|
309
|
-
};
|
|
310
|
-
helper(this.root);
|
|
311
|
-
return ans;
|
|
211
|
+
clear() {
|
|
212
|
+
super.clear();
|
|
213
|
+
this._root = this.SENTINEL;
|
|
312
214
|
}
|
|
313
215
|
/**
|
|
314
216
|
* Time Complexity: O(log n)
|
|
@@ -318,43 +220,33 @@ class RedBlackTree extends bst_1.BST {
|
|
|
318
220
|
* Time Complexity: O(log n)
|
|
319
221
|
* Space Complexity: O(1)
|
|
320
222
|
*
|
|
321
|
-
* The function
|
|
322
|
-
*
|
|
323
|
-
* @param
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
* @
|
|
328
|
-
*
|
|
329
|
-
* function should take a single parameter of type `NODE` (the type of the nodes in the binary tree) and
|
|
330
|
-
* @param {K | NODE | undefined} beginRoot - The `beginRoot` parameter is the starting point for
|
|
331
|
-
* searching for a node in a binary tree. It can be either a key value or a node object. If it is not
|
|
332
|
-
* provided, the search will start from the root of the binary tree.
|
|
333
|
-
* @param iterationType - The `iterationType` parameter is a variable that determines the type of
|
|
334
|
-
* iteration to be performed when searching for nodes in the binary tree. It is used in the
|
|
335
|
-
* `getNodes` method, which is called within the `getNode` method.
|
|
336
|
-
* @returns a value of type `NODE`, `null`, or `undefined`.
|
|
337
|
-
*/
|
|
338
|
-
getNode(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
|
|
339
|
-
var _a;
|
|
340
|
-
if (identifier instanceof RedBlackTreeNode)
|
|
341
|
-
callback = (node => node);
|
|
342
|
-
beginRoot = this.ensureNode(beginRoot);
|
|
343
|
-
return (_a = this.getNodes(identifier, callback, true, beginRoot, iterationType)[0]) !== null && _a !== void 0 ? _a : undefined;
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Time Complexity: O(1)
|
|
347
|
-
* Space Complexity: O(1)
|
|
348
|
-
*/
|
|
349
|
-
/**
|
|
350
|
-
* Time Complexity: O(1)
|
|
351
|
-
* Space Complexity: O(1)
|
|
352
|
-
*
|
|
353
|
-
* The "clear" function sets the root node to the sentinel node and resets the size to 0.
|
|
223
|
+
* The function adds a new node to a Red-Black Tree data structure and returns a boolean indicating
|
|
224
|
+
* whether the operation was successful.
|
|
225
|
+
* @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be either a key, a node, or an
|
|
226
|
+
* entry.
|
|
227
|
+
* @param {V} [value] - The `value` parameter is the value associated with the key that is being
|
|
228
|
+
* added to the tree.
|
|
229
|
+
* @returns The method is returning a boolean value. It returns true if the node was successfully
|
|
230
|
+
* added or updated, and false otherwise.
|
|
354
231
|
*/
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
this.
|
|
232
|
+
add(keyOrNodeOrEntry, value) {
|
|
233
|
+
const newNode = this.keyValueOrEntryToNode(keyOrNodeOrEntry, value);
|
|
234
|
+
if (!this.isRealNode(newNode))
|
|
235
|
+
return false;
|
|
236
|
+
const insertStatus = this._insert(newNode);
|
|
237
|
+
if (insertStatus === types_1.CRUD.CREATED) {
|
|
238
|
+
// Ensure the root is black
|
|
239
|
+
if (this.isRealNode(this._root)) {
|
|
240
|
+
this._root.color = types_1.RBTNColor.BLACK;
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
this._size++;
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
else
|
|
249
|
+
return insertStatus === types_1.CRUD.UPDATED;
|
|
358
250
|
}
|
|
359
251
|
/**
|
|
360
252
|
* Time Complexity: O(log n)
|
|
@@ -364,27 +256,73 @@ class RedBlackTree extends bst_1.BST {
|
|
|
364
256
|
* Time Complexity: O(log n)
|
|
365
257
|
* Space Complexity: O(1)
|
|
366
258
|
*
|
|
367
|
-
* The function
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
*
|
|
259
|
+
* The function `delete` in a binary tree class deletes a node from the tree and fixes the tree if
|
|
260
|
+
* necessary.
|
|
261
|
+
* @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the
|
|
262
|
+
* identifier of the node that needs to be deleted from the binary tree. It can be of any type that
|
|
263
|
+
* is returned by the callback function `C`. It can also be `null` or `undefined` if the node to be
|
|
264
|
+
* deleted is not found.
|
|
265
|
+
* @param {C} callback - The `callback` parameter is a function that is used to retrieve a node from
|
|
266
|
+
* the binary tree based on its identifier. It is an optional parameter and if not provided, the
|
|
267
|
+
* `_defaultOneParamCallback` function is used as the default callback. The callback function should
|
|
268
|
+
* return the identifier of the node to
|
|
269
|
+
* @returns an array of BinaryTreeDeleteResult<NODE> objects.
|
|
371
270
|
*/
|
|
372
|
-
|
|
373
|
-
if (
|
|
374
|
-
return
|
|
271
|
+
delete(identifier, callback = this._defaultOneParamCallback) {
|
|
272
|
+
if (identifier === null)
|
|
273
|
+
return [];
|
|
274
|
+
const results = [];
|
|
275
|
+
const nodeToDelete = this.isRealNode(identifier) ? identifier : this.getNode(identifier, callback);
|
|
276
|
+
if (!nodeToDelete) {
|
|
277
|
+
return results;
|
|
278
|
+
}
|
|
279
|
+
let originalColor = nodeToDelete.color;
|
|
280
|
+
let replacementNode;
|
|
281
|
+
if (!this.isRealNode(nodeToDelete.left)) {
|
|
282
|
+
replacementNode = nodeToDelete.right;
|
|
283
|
+
this._transplant(nodeToDelete, nodeToDelete.right);
|
|
375
284
|
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
y = y.parent;
|
|
285
|
+
else if (!this.isRealNode(nodeToDelete.right)) {
|
|
286
|
+
replacementNode = nodeToDelete.left;
|
|
287
|
+
this._transplant(nodeToDelete, nodeToDelete.left);
|
|
380
288
|
}
|
|
381
|
-
|
|
289
|
+
else {
|
|
290
|
+
const successor = this.getLeftMost(nodeToDelete.right);
|
|
291
|
+
if (successor) {
|
|
292
|
+
originalColor = successor.color;
|
|
293
|
+
replacementNode = successor.right;
|
|
294
|
+
if (successor.parent === nodeToDelete) {
|
|
295
|
+
if (this.isRealNode(replacementNode)) {
|
|
296
|
+
replacementNode.parent = successor;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
this._transplant(successor, successor.right);
|
|
301
|
+
successor.right = nodeToDelete.right;
|
|
302
|
+
if (this.isRealNode(successor.right)) {
|
|
303
|
+
successor.right.parent = successor;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
this._transplant(nodeToDelete, successor);
|
|
307
|
+
successor.left = nodeToDelete.left;
|
|
308
|
+
if (this.isRealNode(successor.left)) {
|
|
309
|
+
successor.left.parent = successor;
|
|
310
|
+
}
|
|
311
|
+
successor.color = nodeToDelete.color;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
this._size--;
|
|
315
|
+
// If the original color was black, fix the tree
|
|
316
|
+
if (originalColor === types_1.RBTNColor.BLACK) {
|
|
317
|
+
this._deleteFixup(replacementNode);
|
|
318
|
+
}
|
|
319
|
+
results.push({ deleted: nodeToDelete, needBalanced: undefined });
|
|
320
|
+
return results;
|
|
382
321
|
}
|
|
383
322
|
/**
|
|
384
|
-
* The function sets the root
|
|
385
|
-
* root
|
|
386
|
-
* @param {NODE} v -
|
|
387
|
-
* structure.
|
|
323
|
+
* The function sets the root of a tree-like structure and updates the parent property of the new
|
|
324
|
+
* root.
|
|
325
|
+
* @param {NODE | undefined} v - v is a parameter of type NODE or undefined.
|
|
388
326
|
*/
|
|
389
327
|
_setRoot(v) {
|
|
390
328
|
if (v) {
|
|
@@ -400,30 +338,65 @@ class RedBlackTree extends bst_1.BST {
|
|
|
400
338
|
* Time Complexity: O(1)
|
|
401
339
|
* Space Complexity: O(1)
|
|
402
340
|
*
|
|
403
|
-
* The function
|
|
404
|
-
* @param {
|
|
341
|
+
* The function replaces an old node with a new node while preserving the color of the old node.
|
|
342
|
+
* @param {NODE} oldNode - The `oldNode` parameter represents the node that needs to be replaced in
|
|
343
|
+
* the data structure.
|
|
344
|
+
* @param {NODE} newNode - The `newNode` parameter is the new node that will replace the old node in
|
|
345
|
+
* the data structure.
|
|
346
|
+
* @returns The method is returning the result of calling the `_replaceNode` method from the
|
|
347
|
+
* superclass, with the `oldNode` and `newNode` parameters.
|
|
405
348
|
*/
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
349
|
+
_replaceNode(oldNode, newNode) {
|
|
350
|
+
newNode.color = oldNode.color;
|
|
351
|
+
return super._replaceNode(oldNode, newNode);
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Time Complexity: O(log n)
|
|
355
|
+
* Space Complexity: O(1)
|
|
356
|
+
*/
|
|
357
|
+
/**
|
|
358
|
+
* Time Complexity: O(log n)
|
|
359
|
+
* Space Complexity: O(1)
|
|
360
|
+
*
|
|
361
|
+
* The `_insert` function inserts or updates a node in a binary search tree and performs necessary
|
|
362
|
+
* fix-ups to maintain the red-black tree properties.
|
|
363
|
+
* @param {NODE} node - The `node` parameter represents the node that needs to be inserted into a
|
|
364
|
+
* binary search tree. It contains a `key` property that is used to determine the position of the
|
|
365
|
+
* node in the tree.
|
|
366
|
+
* @returns {'inserted' | 'updated'} - The result of the insertion.
|
|
367
|
+
*/
|
|
368
|
+
_insert(node) {
|
|
369
|
+
var _a, _b;
|
|
370
|
+
let current = this.root;
|
|
371
|
+
let parent = undefined;
|
|
372
|
+
while (this.isRealNode(current)) {
|
|
373
|
+
parent = current;
|
|
374
|
+
if (node.key < current.key) {
|
|
375
|
+
current = (_a = current.left) !== null && _a !== void 0 ? _a : this.SENTINEL;
|
|
417
376
|
}
|
|
418
|
-
else if (
|
|
419
|
-
|
|
377
|
+
else if (node.key > current.key) {
|
|
378
|
+
current = (_b = current.right) !== null && _b !== void 0 ? _b : this.SENTINEL;
|
|
420
379
|
}
|
|
421
380
|
else {
|
|
422
|
-
|
|
381
|
+
this._replaceNode(current, node);
|
|
382
|
+
return types_1.CRUD.UPDATED;
|
|
423
383
|
}
|
|
424
|
-
y.left = x;
|
|
425
|
-
x.parent = y;
|
|
426
384
|
}
|
|
385
|
+
node.parent = parent;
|
|
386
|
+
if (!parent) {
|
|
387
|
+
this._setRoot(node);
|
|
388
|
+
}
|
|
389
|
+
else if (node.key < parent.key) {
|
|
390
|
+
parent.left = node;
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
parent.right = node;
|
|
394
|
+
}
|
|
395
|
+
node.left = this.SENTINEL;
|
|
396
|
+
node.right = this.SENTINEL;
|
|
397
|
+
node.color = types_1.RBTNColor.RED;
|
|
398
|
+
this._insertFixup(node);
|
|
399
|
+
return types_1.CRUD.CREATED;
|
|
427
400
|
}
|
|
428
401
|
/**
|
|
429
402
|
* Time Complexity: O(1)
|
|
@@ -433,30 +406,23 @@ class RedBlackTree extends bst_1.BST {
|
|
|
433
406
|
* Time Complexity: O(1)
|
|
434
407
|
* Space Complexity: O(1)
|
|
435
408
|
*
|
|
436
|
-
* The function
|
|
437
|
-
* @param {
|
|
438
|
-
*
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
x.parent.right = y;
|
|
454
|
-
}
|
|
455
|
-
else {
|
|
456
|
-
x.parent.left = y;
|
|
457
|
-
}
|
|
458
|
-
y.right = x;
|
|
459
|
-
x.parent = y;
|
|
409
|
+
* The function `_transplant` is used to replace a node `u` with another node `v` in a binary tree.
|
|
410
|
+
* @param {NODE} u - The parameter "u" represents a node in a binary tree.
|
|
411
|
+
* @param {NODE | undefined} v - The parameter `v` is of type `NODE | undefined`, which means it can
|
|
412
|
+
* either be a `NODE` object or `undefined`.
|
|
413
|
+
*/
|
|
414
|
+
_transplant(u, v) {
|
|
415
|
+
if (!u.parent) {
|
|
416
|
+
this._setRoot(v);
|
|
417
|
+
}
|
|
418
|
+
else if (u === u.parent.left) {
|
|
419
|
+
u.parent.left = v;
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
u.parent.right = v;
|
|
423
|
+
}
|
|
424
|
+
if (v) {
|
|
425
|
+
v.parent = u.parent;
|
|
460
426
|
}
|
|
461
427
|
}
|
|
462
428
|
/**
|
|
@@ -467,62 +433,68 @@ class RedBlackTree extends bst_1.BST {
|
|
|
467
433
|
* Time Complexity: O(log n)
|
|
468
434
|
* Space Complexity: O(1)
|
|
469
435
|
*
|
|
470
|
-
* The `
|
|
471
|
-
* @param {
|
|
472
|
-
*
|
|
473
|
-
*/
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
436
|
+
* The `_insertFixup` function is used to fix the Red-Black Tree after inserting a new node.
|
|
437
|
+
* @param {NODE | undefined} z - The parameter `z` represents a node in the Red-Black Tree. It can
|
|
438
|
+
* either be a valid node object or `undefined`.
|
|
439
|
+
*/
|
|
440
|
+
_insertFixup(z) {
|
|
441
|
+
var _a, _b, _c, _d;
|
|
442
|
+
// Continue fixing the tree as long as the parent of z is red
|
|
443
|
+
while (((_a = z === null || z === void 0 ? void 0 : z.parent) === null || _a === void 0 ? void 0 : _a.color) === types_1.RBTNColor.RED) {
|
|
444
|
+
// Check if the parent of z is the left child of its parent
|
|
445
|
+
if (z.parent === ((_b = z.parent.parent) === null || _b === void 0 ? void 0 : _b.left)) {
|
|
446
|
+
// Case 1: The uncle (y) of z is red
|
|
447
|
+
const y = z.parent.parent.right;
|
|
448
|
+
if ((y === null || y === void 0 ? void 0 : y.color) === types_1.RBTNColor.RED) {
|
|
449
|
+
// Set colors to restore properties of Red-Black Tree
|
|
450
|
+
z.parent.color = types_1.RBTNColor.BLACK;
|
|
451
|
+
y.color = types_1.RBTNColor.BLACK;
|
|
452
|
+
z.parent.parent.color = types_1.RBTNColor.RED;
|
|
453
|
+
// Move up the tree to continue fixing
|
|
454
|
+
z = z.parent.parent;
|
|
485
455
|
}
|
|
486
456
|
else {
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
457
|
+
// Case 2: The uncle (y) of z is black, and z is a right child
|
|
458
|
+
if (z === z.parent.right) {
|
|
459
|
+
// Perform a left rotation to transform the case into Case 3
|
|
460
|
+
z = z.parent;
|
|
461
|
+
this._leftRotate(z);
|
|
490
462
|
}
|
|
491
|
-
//
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
463
|
+
// Case 3: The uncle (y) of z is black, and z is a left child
|
|
464
|
+
// Adjust colors and perform a right rotation
|
|
465
|
+
if (z && this.isRealNode(z.parent) && this.isRealNode(z.parent.parent)) {
|
|
466
|
+
z.parent.color = types_1.RBTNColor.BLACK;
|
|
467
|
+
z.parent.parent.color = types_1.RBTNColor.RED;
|
|
468
|
+
this._rightRotate(z.parent.parent);
|
|
495
469
|
}
|
|
496
|
-
this._leftRotate(k.parent.parent);
|
|
497
470
|
}
|
|
498
471
|
}
|
|
499
472
|
else {
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
473
|
+
// Symmetric case for the right child (left and right exchanged)
|
|
474
|
+
// Follow the same logic as above with left and right exchanged
|
|
475
|
+
const y = (_d = (_c = z === null || z === void 0 ? void 0 : z.parent) === null || _c === void 0 ? void 0 : _c.parent) === null || _d === void 0 ? void 0 : _d.left;
|
|
476
|
+
if ((y === null || y === void 0 ? void 0 : y.color) === types_1.RBTNColor.RED) {
|
|
477
|
+
z.parent.color = types_1.RBTNColor.BLACK;
|
|
478
|
+
y.color = types_1.RBTNColor.BLACK;
|
|
479
|
+
z.parent.parent.color = types_1.RBTNColor.RED;
|
|
480
|
+
z = z.parent.parent;
|
|
507
481
|
}
|
|
508
482
|
else {
|
|
509
|
-
if (
|
|
510
|
-
|
|
511
|
-
this.
|
|
483
|
+
if (z === z.parent.left) {
|
|
484
|
+
z = z.parent;
|
|
485
|
+
this._rightRotate(z);
|
|
512
486
|
}
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
487
|
+
if (z && this.isRealNode(z.parent) && this.isRealNode(z.parent.parent)) {
|
|
488
|
+
z.parent.color = types_1.RBTNColor.BLACK;
|
|
489
|
+
z.parent.parent.color = types_1.RBTNColor.RED;
|
|
490
|
+
this._leftRotate(z.parent.parent);
|
|
517
491
|
}
|
|
518
|
-
this._rightRotate(k.parent.parent);
|
|
519
492
|
}
|
|
520
493
|
}
|
|
521
|
-
if (k === this.root) {
|
|
522
|
-
break;
|
|
523
|
-
}
|
|
524
494
|
}
|
|
525
|
-
|
|
495
|
+
// Ensure that the root is black after fixing
|
|
496
|
+
if (this.isRealNode(this._root))
|
|
497
|
+
this._root.color = types_1.RBTNColor.BLACK;
|
|
526
498
|
}
|
|
527
499
|
/**
|
|
528
500
|
* Time Complexity: O(log n)
|
|
@@ -532,72 +504,87 @@ class RedBlackTree extends bst_1.BST {
|
|
|
532
504
|
* Time Complexity: O(log n)
|
|
533
505
|
* Space Complexity: O(1)
|
|
534
506
|
*
|
|
535
|
-
* The
|
|
536
|
-
*
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
507
|
+
* The `_deleteFixup` function is used to fix the red-black tree after a node deletion by adjusting
|
|
508
|
+
* the colors and performing rotations.
|
|
509
|
+
* @param {NODE | undefined} node - The `node` parameter represents a node in a Red-Black Tree data
|
|
510
|
+
* structure. It can be either a valid node object or `undefined`.
|
|
511
|
+
* @returns The function does not return any value. It has a return type of `void`.
|
|
512
|
+
*/
|
|
513
|
+
_deleteFixup(node) {
|
|
514
|
+
var _a, _b, _c, _d;
|
|
515
|
+
// Early exit condition
|
|
516
|
+
if (!node || node === this.root || node.color === types_1.RBTNColor.BLACK) {
|
|
517
|
+
if (node) {
|
|
518
|
+
node.color = types_1.RBTNColor.BLACK; // Ensure the final node is black
|
|
519
|
+
}
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
while (node && node !== this.root && node.color === types_1.RBTNColor.BLACK) {
|
|
523
|
+
const parent = node.parent;
|
|
524
|
+
if (!parent) {
|
|
525
|
+
break; // Ensure the loop terminates if there's an issue with the tree structure
|
|
526
|
+
}
|
|
527
|
+
if (node === parent.left) {
|
|
528
|
+
let sibling = parent.right;
|
|
529
|
+
// Cases 1 and 2: Sibling is red or both children of sibling are black
|
|
530
|
+
if ((sibling === null || sibling === void 0 ? void 0 : sibling.color) === types_1.RBTNColor.RED) {
|
|
531
|
+
sibling.color = types_1.RBTNColor.BLACK;
|
|
532
|
+
parent.color = types_1.RBTNColor.RED;
|
|
533
|
+
this._leftRotate(parent);
|
|
534
|
+
sibling = parent.right;
|
|
548
535
|
}
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
536
|
+
// Case 3: Sibling's left child is black
|
|
537
|
+
if (((_b = (_a = sibling === null || sibling === void 0 ? void 0 : sibling.left) === null || _a === void 0 ? void 0 : _a.color) !== null && _b !== void 0 ? _b : types_1.RBTNColor.BLACK) === types_1.RBTNColor.BLACK) {
|
|
538
|
+
if (sibling)
|
|
539
|
+
sibling.color = types_1.RBTNColor.RED;
|
|
540
|
+
node = parent;
|
|
552
541
|
}
|
|
553
542
|
else {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
s.color = x.parent.color;
|
|
563
|
-
x.parent.color = types_1.RBTNColor.BLACK;
|
|
564
|
-
if (s && s.right)
|
|
565
|
-
s.right.color = types_1.RBTNColor.BLACK;
|
|
566
|
-
this._leftRotate(x.parent);
|
|
567
|
-
x = this.root;
|
|
543
|
+
// Case 4: Adjust colors and perform a right rotation
|
|
544
|
+
if (sibling === null || sibling === void 0 ? void 0 : sibling.left)
|
|
545
|
+
sibling.left.color = types_1.RBTNColor.BLACK;
|
|
546
|
+
if (sibling)
|
|
547
|
+
sibling.color = parent.color;
|
|
548
|
+
parent.color = types_1.RBTNColor.BLACK;
|
|
549
|
+
this._rightRotate(parent);
|
|
550
|
+
node = this.root;
|
|
568
551
|
}
|
|
569
552
|
}
|
|
570
553
|
else {
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
554
|
+
// Symmetric case for the right child (left and right exchanged)
|
|
555
|
+
let sibling = parent.left;
|
|
556
|
+
// Cases 1 and 2: Sibling is red or both children of sibling are black
|
|
557
|
+
if ((sibling === null || sibling === void 0 ? void 0 : sibling.color) === types_1.RBTNColor.RED) {
|
|
558
|
+
sibling.color = types_1.RBTNColor.BLACK;
|
|
559
|
+
if (parent)
|
|
560
|
+
parent.color = types_1.RBTNColor.RED;
|
|
561
|
+
this._rightRotate(parent);
|
|
562
|
+
if (parent)
|
|
563
|
+
sibling = parent.left;
|
|
577
564
|
}
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
565
|
+
// Case 3: Sibling's left child is black
|
|
566
|
+
if (((_d = (_c = sibling === null || sibling === void 0 ? void 0 : sibling.right) === null || _c === void 0 ? void 0 : _c.color) !== null && _d !== void 0 ? _d : types_1.RBTNColor.BLACK) === types_1.RBTNColor.BLACK) {
|
|
567
|
+
if (sibling)
|
|
568
|
+
sibling.color = types_1.RBTNColor.RED;
|
|
569
|
+
node = parent;
|
|
581
570
|
}
|
|
582
571
|
else {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
x.parent.color = types_1.RBTNColor.BLACK;
|
|
593
|
-
if (s && s.left)
|
|
594
|
-
s.left.color = types_1.RBTNColor.BLACK;
|
|
595
|
-
this._rightRotate(x.parent);
|
|
596
|
-
x = this.root;
|
|
572
|
+
// Case 4: Adjust colors and perform a left rotation
|
|
573
|
+
if (sibling === null || sibling === void 0 ? void 0 : sibling.right)
|
|
574
|
+
sibling.right.color = types_1.RBTNColor.BLACK;
|
|
575
|
+
if (sibling)
|
|
576
|
+
sibling.color = parent.color;
|
|
577
|
+
if (parent)
|
|
578
|
+
parent.color = types_1.RBTNColor.BLACK;
|
|
579
|
+
this._leftRotate(parent);
|
|
580
|
+
node = this.root;
|
|
597
581
|
}
|
|
598
582
|
}
|
|
599
583
|
}
|
|
600
|
-
|
|
584
|
+
// Ensure that the final node (possibly the root) is black
|
|
585
|
+
if (node) {
|
|
586
|
+
node.color = types_1.RBTNColor.BLACK;
|
|
587
|
+
}
|
|
601
588
|
}
|
|
602
589
|
/**
|
|
603
590
|
* Time Complexity: O(1)
|
|
@@ -607,34 +594,67 @@ class RedBlackTree extends bst_1.BST {
|
|
|
607
594
|
* Time Complexity: O(1)
|
|
608
595
|
* Space Complexity: O(1)
|
|
609
596
|
*
|
|
610
|
-
* The
|
|
611
|
-
* @param {
|
|
612
|
-
*
|
|
597
|
+
* The `_leftRotate` function performs a left rotation on a given node in a binary tree.
|
|
598
|
+
* @param {NODE | undefined} x - The parameter `x` is of type `NODE | undefined`. It represents a
|
|
599
|
+
* node in a binary tree or `undefined` if there is no node.
|
|
600
|
+
* @returns void, which means it does not return any value.
|
|
613
601
|
*/
|
|
614
|
-
|
|
615
|
-
if (
|
|
616
|
-
|
|
602
|
+
_leftRotate(x) {
|
|
603
|
+
if (!x || !x.right) {
|
|
604
|
+
return;
|
|
617
605
|
}
|
|
618
|
-
|
|
619
|
-
|
|
606
|
+
const y = x.right;
|
|
607
|
+
x.right = y.left;
|
|
608
|
+
if (this.isRealNode(y.left)) {
|
|
609
|
+
y.left.parent = x;
|
|
610
|
+
}
|
|
611
|
+
y.parent = x.parent;
|
|
612
|
+
if (!x.parent) {
|
|
613
|
+
this._setRoot(y);
|
|
614
|
+
}
|
|
615
|
+
else if (x === x.parent.left) {
|
|
616
|
+
x.parent.left = y;
|
|
620
617
|
}
|
|
621
618
|
else {
|
|
622
|
-
|
|
619
|
+
x.parent.right = y;
|
|
623
620
|
}
|
|
624
|
-
|
|
621
|
+
y.left = x;
|
|
622
|
+
x.parent = y;
|
|
625
623
|
}
|
|
626
624
|
/**
|
|
627
|
-
*
|
|
628
|
-
*
|
|
629
|
-
* data structure. It is of type `NODE`, which is the type of the nodes in the data structure.
|
|
630
|
-
* @param {NODE} newNode - The `newNode` parameter is the node that will replace the `oldNode` in the
|
|
631
|
-
* data structure.
|
|
632
|
-
* @returns The method is returning the result of calling the `_replaceNode` method from the
|
|
633
|
-
* superclass, passing in the `oldNode` and `newNode` as arguments.
|
|
625
|
+
* Time Complexity: O(1)
|
|
626
|
+
* Space Complexity: O(1)
|
|
634
627
|
*/
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
628
|
+
/**
|
|
629
|
+
* Time Complexity: O(1)
|
|
630
|
+
* Space Complexity: O(1)
|
|
631
|
+
*
|
|
632
|
+
* The `_rightRotate` function performs a right rotation on a given node in a binary tree.
|
|
633
|
+
* @param {NODE | undefined} y - The parameter `y` is of type `NODE | undefined`. It represents a
|
|
634
|
+
* node in a binary tree or `undefined` if there is no node.
|
|
635
|
+
* @returns void, which means it does not return any value.
|
|
636
|
+
*/
|
|
637
|
+
_rightRotate(y) {
|
|
638
|
+
if (!y || !y.left) {
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
const x = y.left;
|
|
642
|
+
y.left = x.right;
|
|
643
|
+
if (this.isRealNode(x.right)) {
|
|
644
|
+
x.right.parent = y;
|
|
645
|
+
}
|
|
646
|
+
x.parent = y.parent;
|
|
647
|
+
if (!y.parent) {
|
|
648
|
+
this._setRoot(x);
|
|
649
|
+
}
|
|
650
|
+
else if (y === y.parent.left) {
|
|
651
|
+
y.parent.left = x;
|
|
652
|
+
}
|
|
653
|
+
else {
|
|
654
|
+
y.parent.right = x;
|
|
655
|
+
}
|
|
656
|
+
x.right = y;
|
|
657
|
+
y.parent = x;
|
|
638
658
|
}
|
|
639
659
|
}
|
|
640
660
|
exports.RedBlackTree = RedBlackTree;
|