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.
Files changed (28) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +13 -13
  3. package/benchmark/report.html +13 -13
  4. package/benchmark/report.json +168 -144
  5. package/dist/cjs/data-structures/binary-tree/binary-tree.js +19 -19
  6. package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
  7. package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +158 -135
  8. package/dist/cjs/data-structures/binary-tree/rb-tree.js +415 -386
  9. package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
  10. package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +1 -0
  11. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +84 -76
  12. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
  13. package/dist/mjs/data-structures/binary-tree/binary-tree.js +19 -19
  14. package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +158 -135
  15. package/dist/mjs/data-structures/binary-tree/rb-tree.js +412 -386
  16. package/dist/mjs/data-structures/binary-tree/tree-multi-map.d.ts +1 -0
  17. package/dist/mjs/data-structures/binary-tree/tree-multi-map.js +84 -76
  18. package/dist/umd/data-structure-typed.js +477 -431
  19. package/dist/umd/data-structure-typed.min.js +2 -2
  20. package/dist/umd/data-structure-typed.min.js.map +1 -1
  21. package/package.json +1 -1
  22. package/src/data-structures/binary-tree/binary-tree.ts +19 -19
  23. package/src/data-structures/binary-tree/rb-tree.ts +437 -395
  24. package/src/data-structures/binary-tree/tree-multi-map.ts +85 -82
  25. package/test/performance/data-structures/binary-tree/rb-tree.test.ts +26 -16
  26. package/test/unit/data-structures/binary-tree/overall.test.ts +23 -21
  27. package/test/unit/data-structures/binary-tree/rb-tree.test.ts +168 -105
  28. 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 protected variable `_color`.
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, which
11180
- * initializes the tree with optional nodes and options.
11181
- * @param [keysOrNodesOrEntries] - The `keysOrNodesOrEntries` parameter is an optional iterable of `KeyOrNodeOrEntry<K, V, NODE>`
11182
- * objects. It represents the initial nodes that will be added to the RBTree during its
11183
- * construction. If this parameter is provided, the `addMany` method is called to add all the
11184
- * nodes to the
11185
- * @param [options] - The `options` parameter is an optional object that allows you to customize the
11186
- * behavior of the RBTree. It is of type `Partial<RBTreeOptions>`, which means that you can provide
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, "_Sentinel", new RedBlackTreeNode(NaN));
11190
+ __publicField(this, "_SENTINEL", new RedBlackTreeNode(NaN));
11192
11191
  __publicField(this, "_root");
11193
11192
  __publicField(this, "_size", 0);
11194
- this._root = this._Sentinel;
11195
- if (keysOrNodesOrEntries)
11196
- super.addMany(keysOrNodesOrEntries);
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 `_Sentinel` property.
11200
- * @returns The method is returning the value of the `_Sentinel` property.
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 Sentinel() {
11203
- return this._Sentinel;
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 data structure.
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 is the key value associated with the node. It is used to
11222
- * identify and compare nodes in the Red-Black Tree.
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 of type `V`, which is a generic type that can be replaced with any
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 can be either "RED" or "BLACK". By default, the color is set to "BLACK".
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 specified options and returns it.
11236
- * @param {RBTreeOptions} [options] - The `options` parameter is an optional object that can be
11237
- * passed to the `createTree` function. It is used to customize the behavior of the `RedBlackTree`
11238
- * class.
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
- * The function `keyValueOrEntryToNode` takes an keyOrNodeOrEntry and converts it into a node object if possible.
11248
- * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter is of type `KeyOrNodeOrEntry<K, V, NODE>`, where:
11249
- * @param {V} [value] - The `value` parameter is an optional value that can be passed to the
11250
- * `keyValueOrEntryToNode` function. It represents the value associated with the keyOrNodeOrEntry node. If a value
11251
- * is provided, it will be used when creating the new node. If no value is provided, the new node
11252
- * @returns a node of type NODE or undefined.
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
- * The function checks if an keyOrNodeOrEntry is an instance of the RedBlackTreeNode class.
11276
- * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter is of type `KeyOrNodeOrEntry<K, V, NODE>`.
11277
- * @returns a boolean value indicating whether the keyOrNodeOrEntry is an instance of the RedBlackTreeNode
11278
- * class.
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._Sentinel || node === void 0)
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 `add` function adds a new node to a binary search tree and performs necessary rotations and
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 used to
11439
- * identify the node you want to retrieve. It can be of any type that is the return type of the `C`
11440
- * callback function. If the `identifier` is `undefined`, it means you want to retrieve the first
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 binary tree. It is used to determine if a node matches the given identifier. The `callback`
11444
- * function should take a single parameter of type `NODE` (the type of the nodes in the binary tree) and
11445
- * @param {K | NODE | undefined} beginRoot - The `beginRoot` parameter is the starting point for
11446
- * searching for a node in a binary tree. It can be either a key value or a node object. If it is not
11447
- * provided, the search will start from the root of the binary tree.
11448
- * @param iterationType - The `iterationType` parameter is a variable that determines the type of
11449
- * iteration to be performed when searching for nodes in the binary tree. It is used in the
11450
- * `getNodes` method, which is called within the `getNode` method.
11451
- * @returns a value of type `NODE`, `null`, or `undefined`.
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 the sentinel node and resets the size to 0.
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._Sentinel;
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 returns the predecessor of a given node in a red-black tree.
11483
- * @param {RedBlackTreeNode} x - The parameter `x` is of type `RedBlackTreeNode`, which represents a node in a
11484
- * Red-Black Tree.
11485
- * @returns the predecessor of the given RedBlackTreeNode 'x'.
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
- getPredecessor(x) {
11488
- if (this.isRealNode(x.left)) {
11489
- return this.getRightMost(x.left);
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
- let y = x.parent;
11492
- while (this.isRealNode(y) && x === y.left) {
11493
- x = y;
11494
- y = y.parent;
11454
+ this._size--;
11455
+ if (originalColor === 0 /* BLACK */) {
11456
+ this._deleteFixup(replacementNode);
11495
11457
  }
11496
- return y;
11458
+ results.push({ deleted: nodeToDelete, needBalanced: void 0 });
11459
+ return results;
11497
11460
  }
11498
11461
  /**
11499
- * The function sets the root node of a tree structure and updates the parent property of the new
11500
- * root node.
11501
- * @param {NODE} v - The parameter "v" is of type "NODE", which represents a node in a data
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 performs a left rotation on a binary tree node.
11519
- * @param {RedBlackTreeNode} x - The parameter `x` is of type `NODE`, which likely represents a node in a binary tree.
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
- _leftRotate(x) {
11522
- if (x.right) {
11523
- const y = x.right;
11524
- x.right = y.left;
11525
- if (y.left !== this._Sentinel) {
11526
- if (y.left)
11527
- y.left.parent = x;
11528
- }
11529
- y.parent = x.parent;
11530
- if (x.parent === void 0) {
11531
- this._setRoot(y);
11532
- } else if (x === x.parent.left) {
11533
- x.parent.left = y;
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
- x.parent.right = y;
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 performs a right rotation on a red-black tree node.
11550
- * @param {RedBlackTreeNode} x - x is a RedBlackTreeNode, which represents the node that needs to be right
11551
- * rotated.
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
- _rightRotate(x) {
11554
- if (x.left) {
11555
- const y = x.left;
11556
- x.left = y.right;
11557
- if (y.right !== this._Sentinel) {
11558
- if (y.right)
11559
- y.right.parent = x;
11560
- }
11561
- y.parent = x.parent;
11562
- if (x.parent === void 0) {
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 `_fixInsert` function is used to fix the red-black tree after an insertion operation.
11582
- * @param {RedBlackTreeNode} k - The parameter `k` is a RedBlackTreeNode object, which represents a node in a
11583
- * red-black tree.
11584
- */
11585
- _fixInsert(k) {
11586
- let u;
11587
- while (k.parent && k.parent.color === 1 /* RED */) {
11588
- if (k.parent.parent && k.parent === k.parent.parent.right) {
11589
- u = k.parent.parent.left;
11590
- if (u && u.color === 1 /* RED */) {
11591
- k.parent.color = 0 /* BLACK */;
11592
- u.color = 0 /* BLACK */;
11593
- k.parent.parent.color = 1 /* RED */;
11594
- k = k.parent.parent;
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 (k === k.parent.left) {
11597
- k = k.parent;
11598
- this._rightRotate(k);
11584
+ if (z === z.parent.right) {
11585
+ z = z.parent;
11586
+ this._leftRotate(z);
11599
11587
  }
11600
- if (k.parent.color === 1 /* RED */) {
11601
- k.parent.color = 0 /* BLACK */;
11602
- k.parent.parent.color = 1 /* RED */;
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
- u = k.parent.parent.right;
11608
- if (u && u.color === 1 /* RED */) {
11609
- k.parent.color = 0 /* BLACK */;
11610
- u.color = 0 /* BLACK */;
11611
- k.parent.parent.color = 1 /* RED */;
11612
- k = k.parent.parent;
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 (k === k.parent.right) {
11615
- k = k.parent;
11616
- this._leftRotate(k);
11602
+ if (z === z.parent.left) {
11603
+ z = z.parent;
11604
+ this._rightRotate(z);
11617
11605
  }
11618
- if (k.parent.color === 1 /* RED */) {
11619
- k.parent.color = 0 /* BLACK */;
11620
- k.parent.parent.color = 1 /* RED */;
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.root.color = 0 /* BLACK */;
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 function `_fixDelete` is used to fix the red-black tree after a node deletion.
11640
- * @param {RedBlackTreeNode} x - The parameter `x` represents a node in a Red-Black Tree (RBT).
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
- _fixDelete(x) {
11643
- let s;
11644
- while (x !== this.root && x.color === 0 /* BLACK */) {
11645
- if (x.parent && x === x.parent.left) {
11646
- s = x.parent.right;
11647
- if (s.color === 1) {
11648
- s.color = 0 /* BLACK */;
11649
- x.parent.color = 1 /* RED */;
11650
- this._leftRotate(x.parent);
11651
- s = x.parent.right;
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 (s.left !== void 0 && s.left.color === 0 /* BLACK */ && s.right && s.right.color === 0 /* BLACK */) {
11654
- s.color = 1 /* RED */;
11655
- x = x.parent;
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 (s.right && s.right.color === 0 /* BLACK */) {
11658
- if (s.left)
11659
- s.left.color = 0 /* BLACK */;
11660
- s.color = 1 /* RED */;
11661
- this._rightRotate(s);
11662
- s = x.parent.right;
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
- s = x.parent.left;
11674
- if (s.color === 1) {
11675
- s.color = 0 /* BLACK */;
11676
- x.parent.color = 1 /* RED */;
11677
- this._rightRotate(x.parent);
11678
- s = x.parent.left;
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 (s && s.right && s.right.color === 0 /* BLACK */ && s.right.color === 0 /* BLACK */) {
11681
- s.color = 1 /* RED */;
11682
- x = x.parent;
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 (s && s.left && s.left.color === 0 /* BLACK */) {
11685
- if (s.right)
11686
- s.right.color = 0 /* BLACK */;
11687
- s.color = 1 /* RED */;
11688
- this._leftRotate(s);
11689
- s = x.parent.left;
11690
- }
11691
- if (s)
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
- x.color = 0 /* BLACK */;
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 function `_rbTransplant` replaces one node in a red-black tree with another node.
11712
- * @param {RedBlackTreeNode} u - The parameter "u" represents a RedBlackTreeNode object.
11713
- * @param {RedBlackTreeNode} v - The parameter "v" is a RedBlackTreeNode object.
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
- _rbTransplant(u, v) {
11716
- if (u.parent === void 0) {
11717
- this._setRoot(v);
11718
- } else if (u === u.parent.left) {
11719
- u.parent.left = v;
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
- u.parent.right = v;
11723
+ x.parent.right = y;
11722
11724
  }
11723
- v.parent = u.parent;
11725
+ y.left = x;
11726
+ x.parent = y;
11724
11727
  }
11725
11728
  /**
11726
- * The function replaces an old node with a new node while preserving the color of the old node.
11727
- * @param {NODE} oldNode - The `oldNode` parameter represents the node that needs to be replaced in a
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
- _replaceNode(oldNode, newNode) {
11735
- newNode.color = oldNode.color;
11736
- return super._replaceNode(oldNode, newNode);
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
- if (newNode === void 0)
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 deleteResults;
12272
- const deleteHelper = (node) => {
12273
- let targetNode = this._Sentinel;
12274
- let currentNode;
12275
- while (node !== this._Sentinel) {
12276
- if (node && callback(node) === identifier) {
12277
- targetNode = node;
12278
- }
12279
- if (node && identifier && callback(node) <= identifier) {
12280
- node = node.right;
12281
- } else {
12282
- node = node == null ? void 0 : node.left;
12283
- }
12284
- }
12285
- if (targetNode === this._Sentinel) {
12286
- return;
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
- if (ignoreCount || targetNode.count <= 1) {
12289
- let parentNode = targetNode;
12290
- let parentNodeOriginalColor = parentNode.color;
12291
- if (targetNode.left === this._Sentinel) {
12292
- currentNode = targetNode.right;
12293
- this._rbTransplant(targetNode, targetNode.right);
12294
- } else if (targetNode.right === this._Sentinel) {
12295
- currentNode = targetNode.left;
12296
- this._rbTransplant(targetNode, targetNode.left);
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
- parentNode = this.getLeftMost(targetNode.right);
12299
- parentNodeOriginalColor = parentNode.color;
12300
- currentNode = parentNode.right;
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
- this._rbTransplant(parentNode, parentNode.right);
12305
- parentNode.right = targetNode.right;
12306
- parentNode.right.parent = parentNode;
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 (parentNodeOriginalColor === 0 /* BLACK */) {
12314
- this._fixDelete(currentNode);
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
- this._size--;
12317
- this._count -= targetNode.count;
12318
- deleteResults.push({ deleted: targetNode, needBalanced: void 0 });
12319
- } else {
12320
- targetNode.count--;
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
- deleteHelper(this.root);
12325
- return deleteResults;
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)