data-structure-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.
- package/CHANGELOG.md +1 -1
- package/README.md +13 -13
- package/benchmark/report.html +13 -13
- package/benchmark/report.json +168 -144
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +19 -19
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +158 -135
- package/dist/cjs/data-structures/binary-tree/rb-tree.js +415 -386
- package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +1 -0
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +84 -76
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
- package/dist/mjs/data-structures/binary-tree/binary-tree.js +19 -19
- package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +158 -135
- package/dist/mjs/data-structures/binary-tree/rb-tree.js +412 -386
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.d.ts +1 -0
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.js +84 -76
- package/dist/umd/data-structure-typed.js +477 -431
- package/dist/umd/data-structure-typed.min.js +2 -2
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +1 -1
- package/src/data-structures/binary-tree/binary-tree.ts +19 -19
- package/src/data-structures/binary-tree/rb-tree.ts +437 -395
- package/src/data-structures/binary-tree/tree-multi-map.ts +85 -82
- package/test/performance/data-structures/binary-tree/rb-tree.test.ts +26 -16
- package/test/unit/data-structures/binary-tree/overall.test.ts +23 -21
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +168 -105
- package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +311 -192
|
@@ -8386,7 +8386,7 @@ var dataStructureTyped = (() => {
|
|
|
8386
8386
|
return true;
|
|
8387
8387
|
if (iterationType === "RECURSIVE" /* RECURSIVE */) {
|
|
8388
8388
|
const dfs = (cur, min, max) => {
|
|
8389
|
-
if (!cur)
|
|
8389
|
+
if (!this.isRealNode(cur))
|
|
8390
8390
|
return true;
|
|
8391
8391
|
const numKey = this.extractor(cur.key);
|
|
8392
8392
|
if (numKey <= min || numKey >= max)
|
|
@@ -8401,14 +8401,14 @@ var dataStructureTyped = (() => {
|
|
|
8401
8401
|
const stack = [];
|
|
8402
8402
|
let prev = checkMax ? Number.MAX_SAFE_INTEGER : Number.MIN_SAFE_INTEGER;
|
|
8403
8403
|
let curr = beginRoot;
|
|
8404
|
-
while (curr || stack.length > 0) {
|
|
8405
|
-
while (curr) {
|
|
8404
|
+
while (this.isRealNode(curr) || stack.length > 0) {
|
|
8405
|
+
while (this.isRealNode(curr)) {
|
|
8406
8406
|
stack.push(curr);
|
|
8407
8407
|
curr = curr.left;
|
|
8408
8408
|
}
|
|
8409
8409
|
curr = stack.pop();
|
|
8410
8410
|
const numKey = this.extractor(curr.key);
|
|
8411
|
-
if (!curr || !checkMax && prev >= numKey || checkMax && prev <= numKey)
|
|
8411
|
+
if (!this.isRealNode(curr) || !checkMax && prev >= numKey || checkMax && prev <= numKey)
|
|
8412
8412
|
return false;
|
|
8413
8413
|
prev = numKey;
|
|
8414
8414
|
curr = curr.right;
|
|
@@ -8473,7 +8473,7 @@ var dataStructureTyped = (() => {
|
|
|
8473
8473
|
return -1;
|
|
8474
8474
|
if (iterationType === "RECURSIVE" /* RECURSIVE */) {
|
|
8475
8475
|
const _getMaxHeight = (cur) => {
|
|
8476
|
-
if (!cur)
|
|
8476
|
+
if (!this.isRealNode(cur))
|
|
8477
8477
|
return -1;
|
|
8478
8478
|
const leftHeight = _getMaxHeight(cur.left);
|
|
8479
8479
|
const rightHeight = _getMaxHeight(cur.right);
|
|
@@ -8485,9 +8485,9 @@ var dataStructureTyped = (() => {
|
|
|
8485
8485
|
let maxHeight = 0;
|
|
8486
8486
|
while (stack.length > 0) {
|
|
8487
8487
|
const { node, depth } = stack.pop();
|
|
8488
|
-
if (node.left)
|
|
8488
|
+
if (this.isRealNode(node.left))
|
|
8489
8489
|
stack.push({ node: node.left, depth: depth + 1 });
|
|
8490
|
-
if (node.right)
|
|
8490
|
+
if (this.isRealNode(node.right))
|
|
8491
8491
|
stack.push({ node: node.right, depth: depth + 1 });
|
|
8492
8492
|
maxHeight = Math.max(maxHeight, depth);
|
|
8493
8493
|
}
|
|
@@ -8752,45 +8752,45 @@ var dataStructureTyped = (() => {
|
|
|
8752
8752
|
switch (pattern) {
|
|
8753
8753
|
case "in":
|
|
8754
8754
|
if (includeNull) {
|
|
8755
|
-
if (node && this.isNodeOrNull(node.left))
|
|
8755
|
+
if (this.isRealNode(node) && this.isNodeOrNull(node.left))
|
|
8756
8756
|
_traverse(node.left);
|
|
8757
8757
|
this.isNodeOrNull(node) && ans.push(callback(node));
|
|
8758
|
-
if (node && this.isNodeOrNull(node.right))
|
|
8758
|
+
if (this.isRealNode(node) && this.isNodeOrNull(node.right))
|
|
8759
8759
|
_traverse(node.right);
|
|
8760
8760
|
} else {
|
|
8761
|
-
if (node && node.left)
|
|
8761
|
+
if (this.isRealNode(node) && this.isRealNode(node.left))
|
|
8762
8762
|
_traverse(node.left);
|
|
8763
8763
|
this.isRealNode(node) && ans.push(callback(node));
|
|
8764
|
-
if (node && node.right)
|
|
8764
|
+
if (this.isRealNode(node) && this.isRealNode(node.right))
|
|
8765
8765
|
_traverse(node.right);
|
|
8766
8766
|
}
|
|
8767
8767
|
break;
|
|
8768
8768
|
case "pre":
|
|
8769
8769
|
if (includeNull) {
|
|
8770
8770
|
this.isNodeOrNull(node) && ans.push(callback(node));
|
|
8771
|
-
if (node && this.isNodeOrNull(node.left))
|
|
8771
|
+
if (this.isRealNode(node) && this.isNodeOrNull(node.left))
|
|
8772
8772
|
_traverse(node.left);
|
|
8773
|
-
if (node && this.isNodeOrNull(node.right))
|
|
8773
|
+
if (this.isRealNode(node) && this.isNodeOrNull(node.right))
|
|
8774
8774
|
_traverse(node.right);
|
|
8775
8775
|
} else {
|
|
8776
8776
|
this.isRealNode(node) && ans.push(callback(node));
|
|
8777
|
-
if (node && node.left)
|
|
8777
|
+
if (this.isRealNode(node) && this.isRealNode(node.left))
|
|
8778
8778
|
_traverse(node.left);
|
|
8779
|
-
if (node && node.right)
|
|
8779
|
+
if (this.isRealNode(node) && this.isRealNode(node.right))
|
|
8780
8780
|
_traverse(node.right);
|
|
8781
8781
|
}
|
|
8782
8782
|
break;
|
|
8783
8783
|
case "post":
|
|
8784
8784
|
if (includeNull) {
|
|
8785
|
-
if (node && this.isNodeOrNull(node.left))
|
|
8785
|
+
if (this.isRealNode(node) && this.isNodeOrNull(node.left))
|
|
8786
8786
|
_traverse(node.left);
|
|
8787
|
-
if (node && this.isNodeOrNull(node.right))
|
|
8787
|
+
if (this.isRealNode(node) && this.isNodeOrNull(node.right))
|
|
8788
8788
|
_traverse(node.right);
|
|
8789
8789
|
this.isNodeOrNull(node) && ans.push(callback(node));
|
|
8790
8790
|
} else {
|
|
8791
|
-
if (node && node.left)
|
|
8791
|
+
if (this.isRealNode(node) && this.isRealNode(node.left))
|
|
8792
8792
|
_traverse(node.left);
|
|
8793
|
-
if (node && node.right)
|
|
8793
|
+
if (this.isRealNode(node) && this.isRealNode(node.right))
|
|
8794
8794
|
_traverse(node.right);
|
|
8795
8795
|
this.isRealNode(node) && ans.push(callback(node));
|
|
8796
8796
|
}
|
|
@@ -11161,7 +11161,7 @@ var dataStructureTyped = (() => {
|
|
|
11161
11161
|
}
|
|
11162
11162
|
/**
|
|
11163
11163
|
* The function returns the color value of a variable.
|
|
11164
|
-
* @returns The color value stored in the
|
|
11164
|
+
* @returns The color value stored in the private variable `_color`.
|
|
11165
11165
|
*/
|
|
11166
11166
|
get color() {
|
|
11167
11167
|
return this._color;
|
|
@@ -11176,35 +11176,35 @@ var dataStructureTyped = (() => {
|
|
|
11176
11176
|
};
|
|
11177
11177
|
var RedBlackTree = class _RedBlackTree extends BST {
|
|
11178
11178
|
/**
|
|
11179
|
-
* This is the constructor function for a Red-Black Tree data structure in TypeScript
|
|
11180
|
-
*
|
|
11181
|
-
*
|
|
11182
|
-
*
|
|
11183
|
-
*
|
|
11184
|
-
*
|
|
11185
|
-
*
|
|
11186
|
-
*
|
|
11187
|
-
* only a subset of the properties defined in the `RBTreeOptions` interface.
|
|
11179
|
+
* This is the constructor function for a Red-Black Tree data structure in TypeScript.
|
|
11180
|
+
* @param keysOrNodesOrEntries - The `keysOrNodesOrEntries` parameter is an iterable object that can
|
|
11181
|
+
* contain keys, nodes, or entries. It is used to initialize the RBTree with the provided keys,
|
|
11182
|
+
* nodes, or entries.
|
|
11183
|
+
* @param [options] - The `options` parameter is an optional object that can be passed to the
|
|
11184
|
+
* constructor. It allows you to customize the behavior of the RBTree. It can include properties such
|
|
11185
|
+
* as `compareKeys`, `compareValues`, `allowDuplicates`, etc. These properties define how the RBTree
|
|
11186
|
+
* should compare keys and
|
|
11188
11187
|
*/
|
|
11189
11188
|
constructor(keysOrNodesOrEntries = [], options) {
|
|
11190
11189
|
super([], options);
|
|
11191
|
-
__publicField(this, "
|
|
11190
|
+
__publicField(this, "_SENTINEL", new RedBlackTreeNode(NaN));
|
|
11192
11191
|
__publicField(this, "_root");
|
|
11193
11192
|
__publicField(this, "_size", 0);
|
|
11194
|
-
this._root = this.
|
|
11195
|
-
if (keysOrNodesOrEntries)
|
|
11196
|
-
|
|
11193
|
+
this._root = this.SENTINEL;
|
|
11194
|
+
if (keysOrNodesOrEntries) {
|
|
11195
|
+
this.addMany(keysOrNodesOrEntries);
|
|
11196
|
+
}
|
|
11197
11197
|
}
|
|
11198
11198
|
/**
|
|
11199
|
-
* The function returns the value of the
|
|
11200
|
-
* @returns The method is returning the value of the `
|
|
11199
|
+
* The function returns the value of the _SENTINEL property.
|
|
11200
|
+
* @returns The method is returning the value of the `_SENTINEL` property.
|
|
11201
11201
|
*/
|
|
11202
|
-
get
|
|
11203
|
-
return this.
|
|
11202
|
+
get SENTINEL() {
|
|
11203
|
+
return this._SENTINEL;
|
|
11204
11204
|
}
|
|
11205
11205
|
/**
|
|
11206
|
-
* The function returns the root node.
|
|
11207
|
-
* @returns The root node of the
|
|
11206
|
+
* The function returns the root node of a tree or undefined if there is no root.
|
|
11207
|
+
* @returns The root node of the tree structure, or undefined if there is no root node.
|
|
11208
11208
|
*/
|
|
11209
11209
|
get root() {
|
|
11210
11210
|
return this._root;
|
|
@@ -11218,13 +11218,13 @@ var dataStructureTyped = (() => {
|
|
|
11218
11218
|
}
|
|
11219
11219
|
/**
|
|
11220
11220
|
* The function creates a new Red-Black Tree node with the specified key, value, and color.
|
|
11221
|
-
* @param {K} key - The key parameter
|
|
11222
|
-
*
|
|
11221
|
+
* @param {K} key - The key parameter represents the key of the node being created. It is of type K,
|
|
11222
|
+
* which is a generic type representing the key's data type.
|
|
11223
11223
|
* @param {V} [value] - The `value` parameter is an optional parameter that represents the value
|
|
11224
|
-
* associated with the node. It is
|
|
11225
|
-
* specific type when using the `createNode` method.
|
|
11224
|
+
* associated with the key in the node. It is not required and can be omitted if not needed.
|
|
11226
11225
|
* @param {RBTNColor} color - The "color" parameter is used to specify the color of the node in a
|
|
11227
|
-
* Red-Black Tree. It
|
|
11226
|
+
* Red-Black Tree. It is an optional parameter with a default value of "RBTNColor.BLACK". The color
|
|
11227
|
+
* can be either "RBTNColor.RED" or "RBTNColor.BLACK".
|
|
11228
11228
|
* @returns The method is returning a new instance of a RedBlackTreeNode with the specified key,
|
|
11229
11229
|
* value, and color.
|
|
11230
11230
|
*/
|
|
@@ -11232,10 +11232,10 @@ var dataStructureTyped = (() => {
|
|
|
11232
11232
|
return new RedBlackTreeNode(key, value, color);
|
|
11233
11233
|
}
|
|
11234
11234
|
/**
|
|
11235
|
-
* The function creates a Red-Black Tree with the
|
|
11236
|
-
* @param
|
|
11237
|
-
*
|
|
11238
|
-
*
|
|
11235
|
+
* The function creates a Red-Black Tree with the given options and returns it.
|
|
11236
|
+
* @param [options] - The `options` parameter is an optional object that contains configuration
|
|
11237
|
+
* options for creating the Red-Black Tree. It is of type `RBTreeOptions<K>`, where `K` represents
|
|
11238
|
+
* the type of keys in the tree.
|
|
11239
11239
|
* @returns a new instance of a RedBlackTree object.
|
|
11240
11240
|
*/
|
|
11241
11241
|
createTree(options) {
|
|
@@ -11244,12 +11244,18 @@ var dataStructureTyped = (() => {
|
|
|
11244
11244
|
}, options));
|
|
11245
11245
|
}
|
|
11246
11246
|
/**
|
|
11247
|
-
*
|
|
11248
|
-
*
|
|
11249
|
-
|
|
11250
|
-
|
|
11251
|
-
*
|
|
11252
|
-
*
|
|
11247
|
+
* Time Complexity: O(1)
|
|
11248
|
+
* Space Complexity: O(1)
|
|
11249
|
+
*/
|
|
11250
|
+
/**
|
|
11251
|
+
* Time Complexity: O(1)
|
|
11252
|
+
* Space Complexity: O(1)
|
|
11253
|
+
*
|
|
11254
|
+
* The function `keyValueOrEntryToNode` takes a key, value, or entry and returns a node if it is
|
|
11255
|
+
* valid, otherwise it returns undefined.
|
|
11256
|
+
* @param {KeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntry - The key, value, or entry to convert.
|
|
11257
|
+
* @param {V} [value] - The value associated with the key (if `keyOrNodeOrEntry` is a key).
|
|
11258
|
+
* @returns {NODE | undefined} - The corresponding Red-Black Tree node, or `undefined` if conversion fails.
|
|
11253
11259
|
*/
|
|
11254
11260
|
keyValueOrEntryToNode(keyOrNodeOrEntry, value) {
|
|
11255
11261
|
let node;
|
|
@@ -11272,183 +11278,63 @@ var dataStructureTyped = (() => {
|
|
|
11272
11278
|
return node;
|
|
11273
11279
|
}
|
|
11274
11280
|
/**
|
|
11275
|
-
|
|
11276
|
-
|
|
11277
|
-
|
|
11278
|
-
|
|
11279
|
-
|
|
11281
|
+
* Time Complexity: O(1)
|
|
11282
|
+
* Space Complexity: O(1)
|
|
11283
|
+
* /
|
|
11284
|
+
|
|
11285
|
+
/**
|
|
11286
|
+
* Time Complexity: O(1)
|
|
11287
|
+
* Space Complexity: O(1)
|
|
11288
|
+
*
|
|
11289
|
+
* The function checks if the input is an instance of the RedBlackTreeNode class.
|
|
11290
|
+
* @param {KeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntry - The object to check.
|
|
11291
|
+
* @returns {boolean} - `true` if the object is a Red-Black Tree node, `false` otherwise.
|
|
11292
|
+
*/
|
|
11280
11293
|
isNode(keyOrNodeOrEntry) {
|
|
11281
11294
|
return keyOrNodeOrEntry instanceof RedBlackTreeNode;
|
|
11282
11295
|
}
|
|
11283
11296
|
/**
|
|
11297
|
+
* Time Complexity: O(1)
|
|
11298
|
+
* Space Complexity: O(1)
|
|
11299
|
+
*/
|
|
11300
|
+
/**
|
|
11301
|
+
* Time Complexity: O(1)
|
|
11302
|
+
* Space Complexity: O(1)
|
|
11303
|
+
*
|
|
11284
11304
|
* The function checks if a given node is a real node in a Red-Black Tree.
|
|
11285
11305
|
* @param {NODE | undefined} node - The `node` parameter is of type `NODE | undefined`, which means
|
|
11286
11306
|
* it can either be of type `NODE` or `undefined`.
|
|
11287
11307
|
* @returns a boolean value.
|
|
11288
11308
|
*/
|
|
11289
11309
|
isRealNode(node) {
|
|
11290
|
-
if (node === this.
|
|
11310
|
+
if (node === this._SENTINEL || node === void 0)
|
|
11291
11311
|
return false;
|
|
11292
11312
|
return node instanceof RedBlackTreeNode;
|
|
11293
11313
|
}
|
|
11294
11314
|
/**
|
|
11295
11315
|
* Time Complexity: O(log n)
|
|
11296
11316
|
* Space Complexity: O(1)
|
|
11297
|
-
* On average (where n is the number of nodes in the tree)
|
|
11298
11317
|
*/
|
|
11299
11318
|
/**
|
|
11300
11319
|
* Time Complexity: O(log n)
|
|
11301
11320
|
* Space Complexity: O(1)
|
|
11302
11321
|
*
|
|
11303
|
-
* The `
|
|
11304
|
-
* color changes to maintain the red-black tree properties.
|
|
11305
|
-
* @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be either a key, a node, or an
|
|
11306
|
-
* entry.
|
|
11307
|
-
* @param {V} [value] - The `value` parameter represents the value associated with the key that is
|
|
11308
|
-
* being added to the binary search tree.
|
|
11309
|
-
* @returns The method `add` returns either the newly added node (`NODE`) or `undefined`.
|
|
11310
|
-
*/
|
|
11311
|
-
add(keyOrNodeOrEntry, value) {
|
|
11312
|
-
const newNode = this.keyValueOrEntryToNode(keyOrNodeOrEntry, value);
|
|
11313
|
-
if (newNode === void 0)
|
|
11314
|
-
return false;
|
|
11315
|
-
newNode.left = this._Sentinel;
|
|
11316
|
-
newNode.right = this._Sentinel;
|
|
11317
|
-
let y = void 0;
|
|
11318
|
-
let x = this.root;
|
|
11319
|
-
while (x !== this._Sentinel) {
|
|
11320
|
-
y = x;
|
|
11321
|
-
if (x) {
|
|
11322
|
-
if (newNode.key < x.key) {
|
|
11323
|
-
x = x.left;
|
|
11324
|
-
} else if (newNode.key > x.key) {
|
|
11325
|
-
x = x == null ? void 0 : x.right;
|
|
11326
|
-
} else {
|
|
11327
|
-
if (newNode !== x) {
|
|
11328
|
-
this._replaceNode(x, newNode);
|
|
11329
|
-
}
|
|
11330
|
-
return false;
|
|
11331
|
-
}
|
|
11332
|
-
}
|
|
11333
|
-
}
|
|
11334
|
-
newNode.parent = y;
|
|
11335
|
-
if (y === void 0) {
|
|
11336
|
-
this._setRoot(newNode);
|
|
11337
|
-
} else if (newNode.key < y.key) {
|
|
11338
|
-
y.left = newNode;
|
|
11339
|
-
} else {
|
|
11340
|
-
y.right = newNode;
|
|
11341
|
-
}
|
|
11342
|
-
if (newNode.parent === void 0) {
|
|
11343
|
-
newNode.color = 0 /* BLACK */;
|
|
11344
|
-
this._size++;
|
|
11345
|
-
return false;
|
|
11346
|
-
}
|
|
11347
|
-
if (newNode.parent.parent === void 0) {
|
|
11348
|
-
this._size++;
|
|
11349
|
-
return false;
|
|
11350
|
-
}
|
|
11351
|
-
this._fixInsert(newNode);
|
|
11352
|
-
this._size++;
|
|
11353
|
-
return true;
|
|
11354
|
-
}
|
|
11355
|
-
/**
|
|
11356
|
-
* Time Complexity: O(log n)
|
|
11357
|
-
* Space Complexity: O(1)
|
|
11358
|
-
*/
|
|
11359
|
-
/**
|
|
11360
|
-
* Time Complexity: O(log n)
|
|
11361
|
-
* Space Complexity: O(1)
|
|
11362
|
-
*
|
|
11363
|
-
* The `delete` function removes a node from a binary tree based on a given identifier and updates
|
|
11364
|
-
* the tree accordingly.
|
|
11365
|
-
* @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
|
|
11366
|
-
* that you want to use to identify the node that you want to delete from the binary tree. It can be
|
|
11367
|
-
* of any type that is returned by the callback function `C`. It can also be `null` or `undefined` if
|
|
11368
|
-
* you don't want to
|
|
11369
|
-
* @param {C} callback - The `callback` parameter is a function that takes a node of type `NODE` and
|
|
11370
|
-
* returns a value of type `ReturnType<C>`. It is used to determine if a node should be deleted based
|
|
11371
|
-
* on its identifier. The `callback` function is optional and defaults to `this._defaultOneParam
|
|
11372
|
-
* @returns an array of `BinaryTreeDeleteResult<NODE>`.
|
|
11373
|
-
*/
|
|
11374
|
-
delete(identifier, callback = this._defaultOneParamCallback) {
|
|
11375
|
-
const ans = [];
|
|
11376
|
-
if (identifier === null)
|
|
11377
|
-
return ans;
|
|
11378
|
-
const helper = (node) => {
|
|
11379
|
-
let z = this._Sentinel;
|
|
11380
|
-
let x, y;
|
|
11381
|
-
while (node !== this._Sentinel) {
|
|
11382
|
-
if (node && callback(node) === identifier) {
|
|
11383
|
-
z = node;
|
|
11384
|
-
}
|
|
11385
|
-
if (node && identifier && callback(node) <= identifier) {
|
|
11386
|
-
node = node.right;
|
|
11387
|
-
} else {
|
|
11388
|
-
node = node == null ? void 0 : node.left;
|
|
11389
|
-
}
|
|
11390
|
-
}
|
|
11391
|
-
if (z === this._Sentinel) {
|
|
11392
|
-
this._size--;
|
|
11393
|
-
return;
|
|
11394
|
-
}
|
|
11395
|
-
y = z;
|
|
11396
|
-
let yOriginalColor = y.color;
|
|
11397
|
-
if (z.left === this._Sentinel) {
|
|
11398
|
-
x = z.right;
|
|
11399
|
-
this._rbTransplant(z, z.right);
|
|
11400
|
-
} else if (z.right === this._Sentinel) {
|
|
11401
|
-
x = z.left;
|
|
11402
|
-
this._rbTransplant(z, z.left);
|
|
11403
|
-
} else {
|
|
11404
|
-
y = this.getLeftMost(z.right);
|
|
11405
|
-
yOriginalColor = y.color;
|
|
11406
|
-
x = y.right;
|
|
11407
|
-
if (y.parent === z) {
|
|
11408
|
-
x.parent = y;
|
|
11409
|
-
} else {
|
|
11410
|
-
this._rbTransplant(y, y.right);
|
|
11411
|
-
y.right = z.right;
|
|
11412
|
-
y.right.parent = y;
|
|
11413
|
-
}
|
|
11414
|
-
this._rbTransplant(z, y);
|
|
11415
|
-
y.left = z.left;
|
|
11416
|
-
y.left.parent = y;
|
|
11417
|
-
y.color = z.color;
|
|
11418
|
-
}
|
|
11419
|
-
if (yOriginalColor === 0 /* BLACK */) {
|
|
11420
|
-
this._fixDelete(x);
|
|
11421
|
-
}
|
|
11422
|
-
this._size--;
|
|
11423
|
-
ans.push({ deleted: z, needBalanced: void 0 });
|
|
11424
|
-
};
|
|
11425
|
-
helper(this.root);
|
|
11426
|
-
return ans;
|
|
11427
|
-
}
|
|
11428
|
-
/**
|
|
11429
|
-
* Time Complexity: O(log n)
|
|
11430
|
-
* Space Complexity: O(1)
|
|
11431
|
-
*/
|
|
11432
|
-
/**
|
|
11433
|
-
* Time Complexity: O(log n)
|
|
11434
|
-
* Space Complexity: O(1)
|
|
11435
|
-
*
|
|
11436
|
-
* The function `getNode` retrieves a single node from a binary tree based on a given identifier and
|
|
11322
|
+
* The `getNode` function retrieves a node from a Red-Black Tree based on the provided identifier and
|
|
11437
11323
|
* callback function.
|
|
11438
|
-
* @param {ReturnType<C> | undefined} identifier - The `identifier` parameter is the value
|
|
11439
|
-
*
|
|
11440
|
-
*
|
|
11441
|
-
* node that matches the other criteria
|
|
11324
|
+
* @param {ReturnType<C> | undefined} identifier - The `identifier` parameter is the value or key
|
|
11325
|
+
* that you want to search for in the binary search tree. It can be of any type that is compatible
|
|
11326
|
+
* with the type of nodes in the tree.
|
|
11442
11327
|
* @param {C} callback - The `callback` parameter is a function that will be called for each node in
|
|
11443
|
-
* the
|
|
11444
|
-
* function should take a
|
|
11445
|
-
*
|
|
11446
|
-
*
|
|
11447
|
-
*
|
|
11448
|
-
*
|
|
11449
|
-
*
|
|
11450
|
-
*
|
|
11451
|
-
*
|
|
11328
|
+
* the tree. It is used to determine whether a node matches the given identifier. The `callback`
|
|
11329
|
+
* function should take a node as its parameter and return a value that can be compared to the
|
|
11330
|
+
* `identifier` parameter.
|
|
11331
|
+
* @param beginRoot - The `beginRoot` parameter is the starting point for the search in the binary
|
|
11332
|
+
* search tree. It can be either a key or a node. If it is a key, it will be converted to a node
|
|
11333
|
+
* using the `ensureNode` method. If it is not provided, the `root`
|
|
11334
|
+
* @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
|
|
11335
|
+
* be performed when searching for nodes in the binary search tree. It is an optional parameter and
|
|
11336
|
+
* its default value is taken from the `iterationType` property of the class.
|
|
11337
|
+
* @returns The method is returning a value of type `NODE | null | undefined`.
|
|
11452
11338
|
*/
|
|
11453
11339
|
getNode(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
|
|
11454
11340
|
var _a;
|
|
@@ -11465,10 +11351,11 @@ var dataStructureTyped = (() => {
|
|
|
11465
11351
|
* Time Complexity: O(1)
|
|
11466
11352
|
* Space Complexity: O(1)
|
|
11467
11353
|
*
|
|
11468
|
-
* The "clear" function sets the root node to
|
|
11354
|
+
* The "clear" function sets the root node of a data structure to a sentinel value and resets the
|
|
11355
|
+
* size counter to zero.
|
|
11469
11356
|
*/
|
|
11470
11357
|
clear() {
|
|
11471
|
-
this._root = this.
|
|
11358
|
+
this._root = this.SENTINEL;
|
|
11472
11359
|
this._size = 0;
|
|
11473
11360
|
}
|
|
11474
11361
|
/**
|
|
@@ -11479,27 +11366,102 @@ var dataStructureTyped = (() => {
|
|
|
11479
11366
|
* Time Complexity: O(log n)
|
|
11480
11367
|
* Space Complexity: O(1)
|
|
11481
11368
|
*
|
|
11482
|
-
* The function
|
|
11483
|
-
*
|
|
11484
|
-
*
|
|
11485
|
-
*
|
|
11369
|
+
* The function adds a new node to a Red-Black Tree data structure and returns a boolean indicating
|
|
11370
|
+
* whether the operation was successful.
|
|
11371
|
+
* @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be either a key, a node, or an
|
|
11372
|
+
* entry.
|
|
11373
|
+
* @param {V} [value] - The `value` parameter is the value associated with the key that is being
|
|
11374
|
+
* added to the tree.
|
|
11375
|
+
* @returns The method is returning a boolean value. It returns true if the node was successfully
|
|
11376
|
+
* added or updated, and false otherwise.
|
|
11377
|
+
*/
|
|
11378
|
+
add(keyOrNodeOrEntry, value) {
|
|
11379
|
+
const newNode = this.keyValueOrEntryToNode(keyOrNodeOrEntry, value);
|
|
11380
|
+
if (!this.isRealNode(newNode))
|
|
11381
|
+
return false;
|
|
11382
|
+
const insertStatus = this._insert(newNode);
|
|
11383
|
+
if (insertStatus === "inserted") {
|
|
11384
|
+
if (this.isRealNode(this._root)) {
|
|
11385
|
+
this._root.color = 0 /* BLACK */;
|
|
11386
|
+
} else {
|
|
11387
|
+
return false;
|
|
11388
|
+
}
|
|
11389
|
+
this._size++;
|
|
11390
|
+
return true;
|
|
11391
|
+
} else
|
|
11392
|
+
return insertStatus === "updated";
|
|
11393
|
+
}
|
|
11394
|
+
/**
|
|
11395
|
+
* Time Complexity: O(log n)
|
|
11396
|
+
* Space Complexity: O(1)
|
|
11397
|
+
*/
|
|
11398
|
+
/**
|
|
11399
|
+
* Time Complexity: O(log n)
|
|
11400
|
+
* Space Complexity: O(1)
|
|
11401
|
+
*
|
|
11402
|
+
* The function `delete` in a binary tree class deletes a node from the tree and fixes the tree if
|
|
11403
|
+
* necessary.
|
|
11404
|
+
* @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the
|
|
11405
|
+
* identifier of the node that needs to be deleted from the binary tree. It can be of any type that
|
|
11406
|
+
* is returned by the callback function `C`. It can also be `null` or `undefined` if the node to be
|
|
11407
|
+
* deleted is not found.
|
|
11408
|
+
* @param {C} callback - The `callback` parameter is a function that is used to retrieve a node from
|
|
11409
|
+
* the binary tree based on its identifier. It is an optional parameter and if not provided, the
|
|
11410
|
+
* `_defaultOneParamCallback` function is used as the default callback. The callback function should
|
|
11411
|
+
* return the identifier of the node to
|
|
11412
|
+
* @returns an array of BinaryTreeDeleteResult<NODE> objects.
|
|
11486
11413
|
*/
|
|
11487
|
-
|
|
11488
|
-
if (
|
|
11489
|
-
return
|
|
11414
|
+
delete(identifier, callback = this._defaultOneParamCallback) {
|
|
11415
|
+
if (identifier === null)
|
|
11416
|
+
return [];
|
|
11417
|
+
const results = [];
|
|
11418
|
+
const nodeToDelete = this.isRealNode(identifier) ? identifier : this.getNode(identifier, callback);
|
|
11419
|
+
if (!nodeToDelete) {
|
|
11420
|
+
return results;
|
|
11421
|
+
}
|
|
11422
|
+
let originalColor = nodeToDelete.color;
|
|
11423
|
+
let replacementNode;
|
|
11424
|
+
if (!this.isRealNode(nodeToDelete.left)) {
|
|
11425
|
+
replacementNode = nodeToDelete.right;
|
|
11426
|
+
this._transplant(nodeToDelete, nodeToDelete.right);
|
|
11427
|
+
} else if (!this.isRealNode(nodeToDelete.right)) {
|
|
11428
|
+
replacementNode = nodeToDelete.left;
|
|
11429
|
+
this._transplant(nodeToDelete, nodeToDelete.left);
|
|
11430
|
+
} else {
|
|
11431
|
+
const successor = this.getLeftMost(nodeToDelete.right);
|
|
11432
|
+
if (successor) {
|
|
11433
|
+
originalColor = successor.color;
|
|
11434
|
+
replacementNode = successor.right;
|
|
11435
|
+
if (successor.parent === nodeToDelete) {
|
|
11436
|
+
if (this.isRealNode(replacementNode)) {
|
|
11437
|
+
replacementNode.parent = successor;
|
|
11438
|
+
}
|
|
11439
|
+
} else {
|
|
11440
|
+
this._transplant(successor, successor.right);
|
|
11441
|
+
successor.right = nodeToDelete.right;
|
|
11442
|
+
if (this.isRealNode(successor.right)) {
|
|
11443
|
+
successor.right.parent = successor;
|
|
11444
|
+
}
|
|
11445
|
+
}
|
|
11446
|
+
this._transplant(nodeToDelete, successor);
|
|
11447
|
+
successor.left = nodeToDelete.left;
|
|
11448
|
+
if (this.isRealNode(successor.left)) {
|
|
11449
|
+
successor.left.parent = successor;
|
|
11450
|
+
}
|
|
11451
|
+
successor.color = nodeToDelete.color;
|
|
11452
|
+
}
|
|
11490
11453
|
}
|
|
11491
|
-
|
|
11492
|
-
|
|
11493
|
-
|
|
11494
|
-
y = y.parent;
|
|
11454
|
+
this._size--;
|
|
11455
|
+
if (originalColor === 0 /* BLACK */) {
|
|
11456
|
+
this._deleteFixup(replacementNode);
|
|
11495
11457
|
}
|
|
11496
|
-
|
|
11458
|
+
results.push({ deleted: nodeToDelete, needBalanced: void 0 });
|
|
11459
|
+
return results;
|
|
11497
11460
|
}
|
|
11498
11461
|
/**
|
|
11499
|
-
* The function sets the root
|
|
11500
|
-
* root
|
|
11501
|
-
* @param {NODE} v -
|
|
11502
|
-
* structure.
|
|
11462
|
+
* The function sets the root of a tree-like structure and updates the parent property of the new
|
|
11463
|
+
* root.
|
|
11464
|
+
* @param {NODE | undefined} v - v is a parameter of type NODE or undefined.
|
|
11503
11465
|
*/
|
|
11504
11466
|
_setRoot(v) {
|
|
11505
11467
|
if (v) {
|
|
@@ -11515,28 +11477,61 @@ var dataStructureTyped = (() => {
|
|
|
11515
11477
|
* Time Complexity: O(1)
|
|
11516
11478
|
* Space Complexity: O(1)
|
|
11517
11479
|
*
|
|
11518
|
-
* The function
|
|
11519
|
-
* @param {
|
|
11480
|
+
* The function replaces an old node with a new node while preserving the color of the old node.
|
|
11481
|
+
* @param {NODE} oldNode - The `oldNode` parameter represents the node that needs to be replaced in
|
|
11482
|
+
* the data structure.
|
|
11483
|
+
* @param {NODE} newNode - The `newNode` parameter is the new node that will replace the old node in
|
|
11484
|
+
* the data structure.
|
|
11485
|
+
* @returns The method is returning the result of calling the `_replaceNode` method from the
|
|
11486
|
+
* superclass, with the `oldNode` and `newNode` parameters.
|
|
11520
11487
|
*/
|
|
11521
|
-
|
|
11522
|
-
|
|
11523
|
-
|
|
11524
|
-
|
|
11525
|
-
|
|
11526
|
-
|
|
11527
|
-
|
|
11528
|
-
|
|
11529
|
-
|
|
11530
|
-
|
|
11531
|
-
|
|
11532
|
-
|
|
11533
|
-
|
|
11488
|
+
_replaceNode(oldNode, newNode) {
|
|
11489
|
+
newNode.color = oldNode.color;
|
|
11490
|
+
return super._replaceNode(oldNode, newNode);
|
|
11491
|
+
}
|
|
11492
|
+
/**
|
|
11493
|
+
* Time Complexity: O(log n)
|
|
11494
|
+
* Space Complexity: O(1)
|
|
11495
|
+
*/
|
|
11496
|
+
/**
|
|
11497
|
+
* Time Complexity: O(log n)
|
|
11498
|
+
* Space Complexity: O(1)
|
|
11499
|
+
*
|
|
11500
|
+
* The `_insert` function inserts or updates a node in a binary search tree and performs necessary
|
|
11501
|
+
* fix-ups to maintain the red-black tree properties.
|
|
11502
|
+
* @param {NODE} node - The `node` parameter represents the node that needs to be inserted into a
|
|
11503
|
+
* binary search tree. It contains a `key` property that is used to determine the position of the
|
|
11504
|
+
* node in the tree.
|
|
11505
|
+
* @returns {'inserted' | 'updated'} - The result of the insertion.
|
|
11506
|
+
*/
|
|
11507
|
+
_insert(node) {
|
|
11508
|
+
var _a, _b;
|
|
11509
|
+
let current = this.root;
|
|
11510
|
+
let parent = void 0;
|
|
11511
|
+
while (this.isRealNode(current)) {
|
|
11512
|
+
parent = current;
|
|
11513
|
+
if (node.key < current.key) {
|
|
11514
|
+
current = (_a = current.left) != null ? _a : this.SENTINEL;
|
|
11515
|
+
} else if (node.key > current.key) {
|
|
11516
|
+
current = (_b = current.right) != null ? _b : this.SENTINEL;
|
|
11534
11517
|
} else {
|
|
11535
|
-
|
|
11518
|
+
this._replaceNode(current, node);
|
|
11519
|
+
return "updated";
|
|
11536
11520
|
}
|
|
11537
|
-
y.left = x;
|
|
11538
|
-
x.parent = y;
|
|
11539
11521
|
}
|
|
11522
|
+
node.parent = parent;
|
|
11523
|
+
if (!parent) {
|
|
11524
|
+
this._setRoot(node);
|
|
11525
|
+
} else if (node.key < parent.key) {
|
|
11526
|
+
parent.left = node;
|
|
11527
|
+
} else {
|
|
11528
|
+
parent.right = node;
|
|
11529
|
+
}
|
|
11530
|
+
node.left = this.SENTINEL;
|
|
11531
|
+
node.right = this.SENTINEL;
|
|
11532
|
+
node.color = 1 /* RED */;
|
|
11533
|
+
this._insertFixup(node);
|
|
11534
|
+
return "inserted";
|
|
11540
11535
|
}
|
|
11541
11536
|
/**
|
|
11542
11537
|
* Time Complexity: O(1)
|
|
@@ -11546,28 +11541,21 @@ var dataStructureTyped = (() => {
|
|
|
11546
11541
|
* Time Complexity: O(1)
|
|
11547
11542
|
* Space Complexity: O(1)
|
|
11548
11543
|
*
|
|
11549
|
-
* The function
|
|
11550
|
-
* @param {
|
|
11551
|
-
*
|
|
11544
|
+
* The function `_transplant` is used to replace a node `u` with another node `v` in a binary tree.
|
|
11545
|
+
* @param {NODE} u - The parameter "u" represents a node in a binary tree.
|
|
11546
|
+
* @param {NODE | undefined} v - The parameter `v` is of type `NODE | undefined`, which means it can
|
|
11547
|
+
* either be a `NODE` object or `undefined`.
|
|
11552
11548
|
*/
|
|
11553
|
-
|
|
11554
|
-
if (
|
|
11555
|
-
|
|
11556
|
-
|
|
11557
|
-
|
|
11558
|
-
|
|
11559
|
-
|
|
11560
|
-
|
|
11561
|
-
|
|
11562
|
-
|
|
11563
|
-
this._setRoot(y);
|
|
11564
|
-
} else if (x === x.parent.right) {
|
|
11565
|
-
x.parent.right = y;
|
|
11566
|
-
} else {
|
|
11567
|
-
x.parent.left = y;
|
|
11568
|
-
}
|
|
11569
|
-
y.right = x;
|
|
11570
|
-
x.parent = y;
|
|
11549
|
+
_transplant(u, v) {
|
|
11550
|
+
if (!u.parent) {
|
|
11551
|
+
this._setRoot(v);
|
|
11552
|
+
} else if (u === u.parent.left) {
|
|
11553
|
+
u.parent.left = v;
|
|
11554
|
+
} else {
|
|
11555
|
+
u.parent.right = v;
|
|
11556
|
+
}
|
|
11557
|
+
if (v) {
|
|
11558
|
+
v.parent = u.parent;
|
|
11571
11559
|
}
|
|
11572
11560
|
}
|
|
11573
11561
|
/**
|
|
@@ -11578,55 +11566,53 @@ var dataStructureTyped = (() => {
|
|
|
11578
11566
|
* Time Complexity: O(log n)
|
|
11579
11567
|
* Space Complexity: O(1)
|
|
11580
11568
|
*
|
|
11581
|
-
* The `
|
|
11582
|
-
* @param {
|
|
11583
|
-
*
|
|
11584
|
-
*/
|
|
11585
|
-
|
|
11586
|
-
|
|
11587
|
-
while (
|
|
11588
|
-
if (
|
|
11589
|
-
|
|
11590
|
-
if (
|
|
11591
|
-
|
|
11592
|
-
|
|
11593
|
-
|
|
11594
|
-
|
|
11569
|
+
* The `_insertFixup` function is used to fix the Red-Black Tree after inserting a new node.
|
|
11570
|
+
* @param {NODE | undefined} z - The parameter `z` represents a node in the Red-Black Tree. It can
|
|
11571
|
+
* either be a valid node object or `undefined`.
|
|
11572
|
+
*/
|
|
11573
|
+
_insertFixup(z) {
|
|
11574
|
+
var _a, _b, _c, _d;
|
|
11575
|
+
while (((_a = z == null ? void 0 : z.parent) == null ? void 0 : _a.color) === 1 /* RED */) {
|
|
11576
|
+
if (z.parent === ((_b = z.parent.parent) == null ? void 0 : _b.left)) {
|
|
11577
|
+
const y = z.parent.parent.right;
|
|
11578
|
+
if ((y == null ? void 0 : y.color) === 1 /* RED */) {
|
|
11579
|
+
z.parent.color = 0 /* BLACK */;
|
|
11580
|
+
y.color = 0 /* BLACK */;
|
|
11581
|
+
z.parent.parent.color = 1 /* RED */;
|
|
11582
|
+
z = z.parent.parent;
|
|
11595
11583
|
} else {
|
|
11596
|
-
if (
|
|
11597
|
-
|
|
11598
|
-
this.
|
|
11584
|
+
if (z === z.parent.right) {
|
|
11585
|
+
z = z.parent;
|
|
11586
|
+
this._leftRotate(z);
|
|
11599
11587
|
}
|
|
11600
|
-
if (
|
|
11601
|
-
|
|
11602
|
-
|
|
11588
|
+
if (z && this.isRealNode(z.parent) && this.isRealNode(z.parent.parent)) {
|
|
11589
|
+
z.parent.color = 0 /* BLACK */;
|
|
11590
|
+
z.parent.parent.color = 1 /* RED */;
|
|
11591
|
+
this._rightRotate(z.parent.parent);
|
|
11603
11592
|
}
|
|
11604
|
-
this._leftRotate(k.parent.parent);
|
|
11605
11593
|
}
|
|
11606
11594
|
} else {
|
|
11607
|
-
|
|
11608
|
-
if (
|
|
11609
|
-
|
|
11610
|
-
|
|
11611
|
-
|
|
11612
|
-
|
|
11595
|
+
const y = (_d = (_c = z == null ? void 0 : z.parent) == null ? void 0 : _c.parent) == null ? void 0 : _d.left;
|
|
11596
|
+
if ((y == null ? void 0 : y.color) === 1 /* RED */) {
|
|
11597
|
+
z.parent.color = 0 /* BLACK */;
|
|
11598
|
+
y.color = 0 /* BLACK */;
|
|
11599
|
+
z.parent.parent.color = 1 /* RED */;
|
|
11600
|
+
z = z.parent.parent;
|
|
11613
11601
|
} else {
|
|
11614
|
-
if (
|
|
11615
|
-
|
|
11616
|
-
this.
|
|
11602
|
+
if (z === z.parent.left) {
|
|
11603
|
+
z = z.parent;
|
|
11604
|
+
this._rightRotate(z);
|
|
11617
11605
|
}
|
|
11618
|
-
if (
|
|
11619
|
-
|
|
11620
|
-
|
|
11606
|
+
if (z && this.isRealNode(z.parent) && this.isRealNode(z.parent.parent)) {
|
|
11607
|
+
z.parent.color = 0 /* BLACK */;
|
|
11608
|
+
z.parent.parent.color = 1 /* RED */;
|
|
11609
|
+
this._leftRotate(z.parent.parent);
|
|
11621
11610
|
}
|
|
11622
|
-
this._rightRotate(k.parent.parent);
|
|
11623
11611
|
}
|
|
11624
11612
|
}
|
|
11625
|
-
if (k === this.root) {
|
|
11626
|
-
break;
|
|
11627
|
-
}
|
|
11628
11613
|
}
|
|
11629
|
-
this.
|
|
11614
|
+
if (this.isRealNode(this._root))
|
|
11615
|
+
this._root.color = 0 /* BLACK */;
|
|
11630
11616
|
}
|
|
11631
11617
|
/**
|
|
11632
11618
|
* Time Complexity: O(log n)
|
|
@@ -11636,69 +11622,75 @@ var dataStructureTyped = (() => {
|
|
|
11636
11622
|
* Time Complexity: O(log n)
|
|
11637
11623
|
* Space Complexity: O(1)
|
|
11638
11624
|
*
|
|
11639
|
-
* The
|
|
11640
|
-
*
|
|
11625
|
+
* The `_deleteFixup` function is used to fix the red-black tree after a node deletion by adjusting
|
|
11626
|
+
* the colors and performing rotations.
|
|
11627
|
+
* @param {NODE | undefined} node - The `node` parameter represents a node in a Red-Black Tree data
|
|
11628
|
+
* structure. It can be either a valid node object or `undefined`.
|
|
11629
|
+
* @returns The function does not return any value. It has a return type of `void`.
|
|
11641
11630
|
*/
|
|
11642
|
-
|
|
11643
|
-
|
|
11644
|
-
|
|
11645
|
-
if (
|
|
11646
|
-
|
|
11647
|
-
|
|
11648
|
-
|
|
11649
|
-
|
|
11650
|
-
|
|
11651
|
-
|
|
11631
|
+
_deleteFixup(node) {
|
|
11632
|
+
var _a, _b, _c, _d;
|
|
11633
|
+
if (!node || node === this.root || node.color === 0 /* BLACK */) {
|
|
11634
|
+
if (node) {
|
|
11635
|
+
node.color = 0 /* BLACK */;
|
|
11636
|
+
}
|
|
11637
|
+
return;
|
|
11638
|
+
}
|
|
11639
|
+
while (node && node !== this.root && node.color === 0 /* BLACK */) {
|
|
11640
|
+
const parent = node.parent;
|
|
11641
|
+
if (!parent) {
|
|
11642
|
+
break;
|
|
11643
|
+
}
|
|
11644
|
+
if (node === parent.left) {
|
|
11645
|
+
let sibling = parent.right;
|
|
11646
|
+
if ((sibling == null ? void 0 : sibling.color) === 1 /* RED */) {
|
|
11647
|
+
sibling.color = 0 /* BLACK */;
|
|
11648
|
+
parent.color = 1 /* RED */;
|
|
11649
|
+
this._leftRotate(parent);
|
|
11650
|
+
sibling = parent.right;
|
|
11652
11651
|
}
|
|
11653
|
-
if (
|
|
11654
|
-
|
|
11655
|
-
|
|
11652
|
+
if (((_b = (_a = sibling == null ? void 0 : sibling.left) == null ? void 0 : _a.color) != null ? _b : 0 /* BLACK */) === 0 /* BLACK */) {
|
|
11653
|
+
if (sibling)
|
|
11654
|
+
sibling.color = 1 /* RED */;
|
|
11655
|
+
node = parent;
|
|
11656
11656
|
} else {
|
|
11657
|
-
if (
|
|
11658
|
-
|
|
11659
|
-
|
|
11660
|
-
|
|
11661
|
-
|
|
11662
|
-
|
|
11663
|
-
|
|
11664
|
-
if (s)
|
|
11665
|
-
s.color = x.parent.color;
|
|
11666
|
-
x.parent.color = 0 /* BLACK */;
|
|
11667
|
-
if (s && s.right)
|
|
11668
|
-
s.right.color = 0 /* BLACK */;
|
|
11669
|
-
this._leftRotate(x.parent);
|
|
11670
|
-
x = this.root;
|
|
11657
|
+
if (sibling == null ? void 0 : sibling.left)
|
|
11658
|
+
sibling.left.color = 0 /* BLACK */;
|
|
11659
|
+
if (sibling)
|
|
11660
|
+
sibling.color = parent.color;
|
|
11661
|
+
parent.color = 0 /* BLACK */;
|
|
11662
|
+
this._rightRotate(parent);
|
|
11663
|
+
node = this.root;
|
|
11671
11664
|
}
|
|
11672
11665
|
} else {
|
|
11673
|
-
|
|
11674
|
-
if (
|
|
11675
|
-
|
|
11676
|
-
|
|
11677
|
-
|
|
11678
|
-
|
|
11666
|
+
let sibling = parent.left;
|
|
11667
|
+
if ((sibling == null ? void 0 : sibling.color) === 1 /* RED */) {
|
|
11668
|
+
sibling.color = 0 /* BLACK */;
|
|
11669
|
+
if (parent)
|
|
11670
|
+
parent.color = 1 /* RED */;
|
|
11671
|
+
this._rightRotate(parent);
|
|
11672
|
+
if (parent)
|
|
11673
|
+
sibling = parent.left;
|
|
11679
11674
|
}
|
|
11680
|
-
if (
|
|
11681
|
-
|
|
11682
|
-
|
|
11675
|
+
if (((_d = (_c = sibling == null ? void 0 : sibling.right) == null ? void 0 : _c.color) != null ? _d : 0 /* BLACK */) === 0 /* BLACK */) {
|
|
11676
|
+
if (sibling)
|
|
11677
|
+
sibling.color = 1 /* RED */;
|
|
11678
|
+
node = parent;
|
|
11683
11679
|
} else {
|
|
11684
|
-
if (
|
|
11685
|
-
|
|
11686
|
-
|
|
11687
|
-
|
|
11688
|
-
|
|
11689
|
-
|
|
11690
|
-
|
|
11691
|
-
|
|
11692
|
-
s.color = x.parent.color;
|
|
11693
|
-
x.parent.color = 0 /* BLACK */;
|
|
11694
|
-
if (s && s.left)
|
|
11695
|
-
s.left.color = 0 /* BLACK */;
|
|
11696
|
-
this._rightRotate(x.parent);
|
|
11697
|
-
x = this.root;
|
|
11680
|
+
if (sibling == null ? void 0 : sibling.right)
|
|
11681
|
+
sibling.right.color = 0 /* BLACK */;
|
|
11682
|
+
if (sibling)
|
|
11683
|
+
sibling.color = parent.color;
|
|
11684
|
+
if (parent)
|
|
11685
|
+
parent.color = 0 /* BLACK */;
|
|
11686
|
+
this._leftRotate(parent);
|
|
11687
|
+
node = this.root;
|
|
11698
11688
|
}
|
|
11699
11689
|
}
|
|
11700
11690
|
}
|
|
11701
|
-
|
|
11691
|
+
if (node) {
|
|
11692
|
+
node.color = 0 /* BLACK */;
|
|
11693
|
+
}
|
|
11702
11694
|
}
|
|
11703
11695
|
/**
|
|
11704
11696
|
* Time Complexity: O(1)
|
|
@@ -11708,32 +11700,63 @@ var dataStructureTyped = (() => {
|
|
|
11708
11700
|
* Time Complexity: O(1)
|
|
11709
11701
|
* Space Complexity: O(1)
|
|
11710
11702
|
*
|
|
11711
|
-
* The
|
|
11712
|
-
* @param {
|
|
11713
|
-
*
|
|
11703
|
+
* The `_leftRotate` function performs a left rotation on a given node in a binary tree.
|
|
11704
|
+
* @param {NODE | undefined} x - The parameter `x` is of type `NODE | undefined`. It represents a
|
|
11705
|
+
* node in a binary tree or `undefined` if there is no node.
|
|
11706
|
+
* @returns void, which means it does not return any value.
|
|
11714
11707
|
*/
|
|
11715
|
-
|
|
11716
|
-
if (
|
|
11717
|
-
|
|
11718
|
-
}
|
|
11719
|
-
|
|
11708
|
+
_leftRotate(x) {
|
|
11709
|
+
if (!x || !x.right) {
|
|
11710
|
+
return;
|
|
11711
|
+
}
|
|
11712
|
+
const y = x.right;
|
|
11713
|
+
x.right = y.left;
|
|
11714
|
+
if (this.isRealNode(y.left)) {
|
|
11715
|
+
y.left.parent = x;
|
|
11716
|
+
}
|
|
11717
|
+
y.parent = x.parent;
|
|
11718
|
+
if (!x.parent) {
|
|
11719
|
+
this._setRoot(y);
|
|
11720
|
+
} else if (x === x.parent.left) {
|
|
11721
|
+
x.parent.left = y;
|
|
11720
11722
|
} else {
|
|
11721
|
-
|
|
11723
|
+
x.parent.right = y;
|
|
11722
11724
|
}
|
|
11723
|
-
|
|
11725
|
+
y.left = x;
|
|
11726
|
+
x.parent = y;
|
|
11724
11727
|
}
|
|
11725
11728
|
/**
|
|
11726
|
-
*
|
|
11727
|
-
*
|
|
11728
|
-
* data structure. It is of type `NODE`, which is the type of the nodes in the data structure.
|
|
11729
|
-
* @param {NODE} newNode - The `newNode` parameter is the node that will replace the `oldNode` in the
|
|
11730
|
-
* data structure.
|
|
11731
|
-
* @returns The method is returning the result of calling the `_replaceNode` method from the
|
|
11732
|
-
* superclass, passing in the `oldNode` and `newNode` as arguments.
|
|
11729
|
+
* Time Complexity: O(1)
|
|
11730
|
+
* Space Complexity: O(1)
|
|
11733
11731
|
*/
|
|
11734
|
-
|
|
11735
|
-
|
|
11736
|
-
|
|
11732
|
+
/**
|
|
11733
|
+
* Time Complexity: O(1)
|
|
11734
|
+
* Space Complexity: O(1)
|
|
11735
|
+
*
|
|
11736
|
+
* The `_rightRotate` function performs a right rotation on a given node in a binary tree.
|
|
11737
|
+
* @param {NODE | undefined} y - The parameter `y` is of type `NODE | undefined`. It represents a
|
|
11738
|
+
* node in a binary tree or `undefined` if there is no node.
|
|
11739
|
+
* @returns void, which means it does not return any value.
|
|
11740
|
+
*/
|
|
11741
|
+
_rightRotate(y) {
|
|
11742
|
+
if (!y || !y.left) {
|
|
11743
|
+
return;
|
|
11744
|
+
}
|
|
11745
|
+
const x = y.left;
|
|
11746
|
+
y.left = x.right;
|
|
11747
|
+
if (this.isRealNode(x.right)) {
|
|
11748
|
+
x.right.parent = y;
|
|
11749
|
+
}
|
|
11750
|
+
x.parent = y.parent;
|
|
11751
|
+
if (!y.parent) {
|
|
11752
|
+
this._setRoot(x);
|
|
11753
|
+
} else if (y === y.parent.left) {
|
|
11754
|
+
y.parent.left = x;
|
|
11755
|
+
} else {
|
|
11756
|
+
y.parent.right = x;
|
|
11757
|
+
}
|
|
11758
|
+
x.right = y;
|
|
11759
|
+
y.parent = x;
|
|
11737
11760
|
}
|
|
11738
11761
|
};
|
|
11739
11762
|
|
|
@@ -12140,6 +12163,9 @@ var dataStructureTyped = (() => {
|
|
|
12140
12163
|
* @returns the sum of the count property of all nodes in the tree.
|
|
12141
12164
|
*/
|
|
12142
12165
|
get count() {
|
|
12166
|
+
return this._count;
|
|
12167
|
+
}
|
|
12168
|
+
getMutableCount() {
|
|
12143
12169
|
let sum = 0;
|
|
12144
12170
|
this.dfs((node) => sum += node.count);
|
|
12145
12171
|
return sum;
|
|
@@ -12232,14 +12258,14 @@ var dataStructureTyped = (() => {
|
|
|
12232
12258
|
*/
|
|
12233
12259
|
add(keyOrNodeOrEntry, value, count = 1) {
|
|
12234
12260
|
const newNode = this.keyValueOrEntryToNode(keyOrNodeOrEntry, value, count);
|
|
12235
|
-
|
|
12261
|
+
const orgCount = (newNode == null ? void 0 : newNode.count) || 0;
|
|
12262
|
+
const isSuccessAdded = super.add(newNode);
|
|
12263
|
+
if (isSuccessAdded) {
|
|
12264
|
+
this._count += orgCount;
|
|
12265
|
+
return true;
|
|
12266
|
+
} else {
|
|
12236
12267
|
return false;
|
|
12237
|
-
const orgNodeCount = (newNode == null ? void 0 : newNode.count) || 0;
|
|
12238
|
-
const inserted = super.add(newNode);
|
|
12239
|
-
if (inserted) {
|
|
12240
|
-
this._count += orgNodeCount;
|
|
12241
12268
|
}
|
|
12242
|
-
return true;
|
|
12243
12269
|
}
|
|
12244
12270
|
/**
|
|
12245
12271
|
* Time Complexity: O(log n)
|
|
@@ -12266,63 +12292,83 @@ var dataStructureTyped = (() => {
|
|
|
12266
12292
|
* @returns an array of BinaryTreeDeleteResult<NODE> objects.
|
|
12267
12293
|
*/
|
|
12268
12294
|
delete(identifier, callback = this._defaultOneParamCallback, ignoreCount = false) {
|
|
12269
|
-
const deleteResults = [];
|
|
12270
12295
|
if (identifier === null)
|
|
12271
|
-
return
|
|
12272
|
-
const
|
|
12273
|
-
|
|
12274
|
-
|
|
12275
|
-
|
|
12276
|
-
|
|
12277
|
-
|
|
12278
|
-
|
|
12279
|
-
|
|
12280
|
-
|
|
12281
|
-
|
|
12282
|
-
|
|
12283
|
-
|
|
12284
|
-
}
|
|
12285
|
-
|
|
12286
|
-
|
|
12296
|
+
return [];
|
|
12297
|
+
const results = [];
|
|
12298
|
+
const nodeToDelete = this.isRealNode(identifier) ? identifier : this.getNode(identifier, callback);
|
|
12299
|
+
if (!nodeToDelete) {
|
|
12300
|
+
return results;
|
|
12301
|
+
}
|
|
12302
|
+
let originalColor = nodeToDelete.color;
|
|
12303
|
+
let replacementNode;
|
|
12304
|
+
if (!this.isRealNode(nodeToDelete.left)) {
|
|
12305
|
+
replacementNode = nodeToDelete.right;
|
|
12306
|
+
if (ignoreCount || nodeToDelete.count <= 1) {
|
|
12307
|
+
this._transplant(nodeToDelete, nodeToDelete.right);
|
|
12308
|
+
this._count -= nodeToDelete.count;
|
|
12309
|
+
} else {
|
|
12310
|
+
nodeToDelete.count--;
|
|
12311
|
+
this._count--;
|
|
12312
|
+
results.push({ deleted: nodeToDelete, needBalanced: void 0 });
|
|
12313
|
+
return results;
|
|
12314
|
+
}
|
|
12315
|
+
} else if (!this.isRealNode(nodeToDelete.right)) {
|
|
12316
|
+
replacementNode = nodeToDelete.left;
|
|
12317
|
+
if (ignoreCount || nodeToDelete.count <= 1) {
|
|
12318
|
+
this._transplant(nodeToDelete, nodeToDelete.left);
|
|
12319
|
+
this._count -= nodeToDelete.count;
|
|
12320
|
+
} else {
|
|
12321
|
+
nodeToDelete.count--;
|
|
12322
|
+
this._count--;
|
|
12323
|
+
results.push({ deleted: nodeToDelete, needBalanced: void 0 });
|
|
12324
|
+
return results;
|
|
12287
12325
|
}
|
|
12288
|
-
|
|
12289
|
-
|
|
12290
|
-
|
|
12291
|
-
|
|
12292
|
-
|
|
12293
|
-
|
|
12294
|
-
|
|
12295
|
-
|
|
12296
|
-
|
|
12326
|
+
} else {
|
|
12327
|
+
const successor = this.getLeftMost(nodeToDelete.right);
|
|
12328
|
+
if (successor) {
|
|
12329
|
+
originalColor = successor.color;
|
|
12330
|
+
replacementNode = successor.right;
|
|
12331
|
+
if (successor.parent === nodeToDelete) {
|
|
12332
|
+
if (this.isRealNode(replacementNode)) {
|
|
12333
|
+
replacementNode.parent = successor;
|
|
12334
|
+
}
|
|
12297
12335
|
} else {
|
|
12298
|
-
|
|
12299
|
-
|
|
12300
|
-
|
|
12301
|
-
if (parentNode.parent === targetNode) {
|
|
12302
|
-
currentNode.parent = parentNode;
|
|
12336
|
+
if (ignoreCount || nodeToDelete.count <= 1) {
|
|
12337
|
+
this._transplant(successor, successor.right);
|
|
12338
|
+
this._count -= nodeToDelete.count;
|
|
12303
12339
|
} else {
|
|
12304
|
-
|
|
12305
|
-
|
|
12306
|
-
|
|
12340
|
+
nodeToDelete.count--;
|
|
12341
|
+
this._count--;
|
|
12342
|
+
results.push({ deleted: nodeToDelete, needBalanced: void 0 });
|
|
12343
|
+
return results;
|
|
12344
|
+
}
|
|
12345
|
+
successor.right = nodeToDelete.right;
|
|
12346
|
+
if (this.isRealNode(successor.right)) {
|
|
12347
|
+
successor.right.parent = successor;
|
|
12307
12348
|
}
|
|
12308
|
-
this._rbTransplant(targetNode, parentNode);
|
|
12309
|
-
parentNode.left = targetNode.left;
|
|
12310
|
-
parentNode.left.parent = parentNode;
|
|
12311
|
-
parentNode.color = targetNode.color;
|
|
12312
12349
|
}
|
|
12313
|
-
if (
|
|
12314
|
-
this.
|
|
12350
|
+
if (ignoreCount || nodeToDelete.count <= 1) {
|
|
12351
|
+
this._transplant(nodeToDelete, successor);
|
|
12352
|
+
this._count -= nodeToDelete.count;
|
|
12353
|
+
} else {
|
|
12354
|
+
nodeToDelete.count--;
|
|
12355
|
+
this._count--;
|
|
12356
|
+
results.push({ deleted: nodeToDelete, needBalanced: void 0 });
|
|
12357
|
+
return results;
|
|
12315
12358
|
}
|
|
12316
|
-
|
|
12317
|
-
this.
|
|
12318
|
-
|
|
12319
|
-
|
|
12320
|
-
|
|
12321
|
-
this._count--;
|
|
12359
|
+
successor.left = nodeToDelete.left;
|
|
12360
|
+
if (this.isRealNode(successor.left)) {
|
|
12361
|
+
successor.left.parent = successor;
|
|
12362
|
+
}
|
|
12363
|
+
successor.color = nodeToDelete.color;
|
|
12322
12364
|
}
|
|
12323
|
-
}
|
|
12324
|
-
|
|
12325
|
-
|
|
12365
|
+
}
|
|
12366
|
+
this._size--;
|
|
12367
|
+
if (originalColor === 0 /* BLACK */) {
|
|
12368
|
+
this._deleteFixup(replacementNode);
|
|
12369
|
+
}
|
|
12370
|
+
results.push({ deleted: nodeToDelete, needBalanced: void 0 });
|
|
12371
|
+
return results;
|
|
12326
12372
|
}
|
|
12327
12373
|
/**
|
|
12328
12374
|
* Time Complexity: O(1)
|