min-heap-typed 1.50.5 → 1.50.6

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