bst-typed 1.50.7 → 1.50.9

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.
@@ -126,7 +126,7 @@ export class BST<
126
126
  return this._root;
127
127
  }
128
128
 
129
- protected _variant = BSTVariant.STANDARD;
129
+ protected _variant: BSTVariant = 'STANDARD';
130
130
 
131
131
  /**
132
132
  * The function returns the value of the _variant property.
@@ -207,12 +207,12 @@ export class BST<
207
207
  * @param {K | NODE | undefined} keyOrNodeOrEntry - The `key` parameter can be of type `K`, `NODE`, or
208
208
  * `undefined`.
209
209
  * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
210
- * type of iteration to be performed. It has a default value of `IterationType.ITERATIVE`.
210
+ * type of iteration to be performed. It has a default value of `'ITERATIVE'`.
211
211
  * @returns either a node object (NODE) or undefined.
212
212
  */
213
213
  override ensureNode(
214
214
  keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>,
215
- iterationType = IterationType.ITERATIVE
215
+ iterationType: IterationType = 'ITERATIVE'
216
216
  ): NODE | undefined {
217
217
  let res: NODE | undefined;
218
218
  if (this.isRealNode(keyOrNodeOrEntry)) {
@@ -263,7 +263,7 @@ export class BST<
263
263
 
264
264
  let current = this.root;
265
265
  while (current !== undefined) {
266
- if (this._compare(current.key, newNode.key) === CP.eq) {
266
+ if (this._compare(current.key, newNode.key) === 'EQ') {
267
267
  // if (current !== newNode) {
268
268
  // The key value is the same but the reference is different, update the value of the existing node
269
269
  this._replaceNode(current, newNode);
@@ -275,7 +275,7 @@ export class BST<
275
275
 
276
276
  // return;
277
277
  // }
278
- } else if (this._compare(current.key, newNode.key) === CP.gt) {
278
+ } else if (this._compare(current.key, newNode.key) === 'GT') {
279
279
  if (current.left === undefined) {
280
280
  current.left = newNode;
281
281
  this._size++;
@@ -324,7 +324,7 @@ export class BST<
324
324
  keysOrNodesOrEntries: Iterable<KeyOrNodeOrEntry<K, V, NODE>>,
325
325
  values?: Iterable<V | undefined>,
326
326
  isBalanceAdd = true,
327
- iterationType = this.iterationType
327
+ iterationType: IterationType = this.iterationType
328
328
  ): boolean[] {
329
329
  const inserted: boolean[] = [];
330
330
 
@@ -397,7 +397,7 @@ export class BST<
397
397
  }
398
398
  };
399
399
 
400
- if (iterationType === IterationType.RECURSIVE) {
400
+ if (iterationType === 'RECURSIVE') {
401
401
  _dfs(sorted);
402
402
  } else {
403
403
  _iterate();
@@ -425,15 +425,16 @@ export class BST<
425
425
  * @returns The function `getNodeByKey` returns a node (`NODE`) if a node with the specified key is
426
426
  * found in the binary tree. If no node is found, it returns `undefined`.
427
427
  */
428
- override getNodeByKey(key: K, iterationType = IterationType.ITERATIVE): NODE | undefined {
428
+ override getNodeByKey(key: K, iterationType: IterationType = 'ITERATIVE'): NODE | undefined {
429
+ // return this.getNodes(key, this._defaultOneParamCallback, true, this.root, iterationType)[0];
429
430
  if (!this.isRealNode(this.root)) return undefined;
430
- if (iterationType === IterationType.RECURSIVE) {
431
+ if (iterationType === 'RECURSIVE') {
431
432
  const _dfs = (cur: NODE): NODE | undefined => {
432
433
  if (cur.key === key) return cur;
433
434
  if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
434
435
 
435
- if (this._compare(cur.key, key) === CP.gt && this.isRealNode(cur.left)) return _dfs(cur.left);
436
- if (this._compare(cur.key, key) === CP.lt && this.isRealNode(cur.right)) return _dfs(cur.right);
436
+ if (this._compare(cur.key, key) === 'GT' && this.isRealNode(cur.left)) return _dfs(cur.left);
437
+ if (this._compare(cur.key, key) === 'LT' && this.isRealNode(cur.right)) return _dfs(cur.right);
437
438
  };
438
439
 
439
440
  return _dfs(this.root);
@@ -442,9 +443,9 @@ export class BST<
442
443
  while (queue.size > 0) {
443
444
  const cur = queue.shift();
444
445
  if (this.isRealNode(cur)) {
445
- if (this._compare(cur.key, key) === CP.eq) return cur;
446
- if (this._compare(cur.key, key) === CP.gt) this.isRealNode(cur.left) && queue.push(cur.left);
447
- if (this._compare(cur.key, key) === CP.lt) this.isRealNode(cur.right) && queue.push(cur.right);
446
+ if (this._compare(cur.key, key) === 'EQ') return cur;
447
+ if (this._compare(cur.key, key) === 'GT') this.isRealNode(cur.left) && queue.push(cur.left);
448
+ if (this._compare(cur.key, key) === 'LT') this.isRealNode(cur.right) && queue.push(cur.right);
448
449
  }
449
450
  }
450
451
  }
@@ -483,13 +484,13 @@ export class BST<
483
484
  callback: C = this._defaultOneParamCallback as C,
484
485
  onlyOne = false,
485
486
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
486
- iterationType = this.iterationType
487
+ iterationType: IterationType = this.iterationType
487
488
  ): NODE[] {
488
489
  beginRoot = this.ensureNode(beginRoot);
489
490
  if (!beginRoot) return [];
490
491
  const ans: NODE[] = [];
491
492
 
492
- if (iterationType === IterationType.RECURSIVE) {
493
+ if (iterationType === 'RECURSIVE') {
493
494
  const _traverse = (cur: NODE) => {
494
495
  const callbackResult = callback(cur);
495
496
  if (callbackResult === identifier) {
@@ -500,8 +501,8 @@ export class BST<
500
501
  if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
501
502
  // TODO potential bug
502
503
  if (callback === this._defaultOneParamCallback) {
503
- if (this._compare(cur.key, identifier as K) === CP.gt) this.isRealNode(cur.left) && _traverse(cur.left);
504
- if (this._compare(cur.key, identifier as K) === CP.lt) this.isRealNode(cur.right) && _traverse(cur.right);
504
+ if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') _traverse(cur.left);
505
+ if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') _traverse(cur.right);
505
506
  } else {
506
507
  this.isRealNode(cur.left) && _traverse(cur.left);
507
508
  this.isRealNode(cur.right) && _traverse(cur.right);
@@ -510,9 +511,9 @@ export class BST<
510
511
 
511
512
  _traverse(beginRoot);
512
513
  } else {
513
- const queue = new Queue<NODE>([beginRoot]);
514
- while (queue.size > 0) {
515
- const cur = queue.shift();
514
+ const stack = [beginRoot];
515
+ while (stack.length > 0) {
516
+ const cur = stack.pop();
516
517
  if (this.isRealNode(cur)) {
517
518
  const callbackResult = callback(cur);
518
519
  if (callbackResult === identifier) {
@@ -521,11 +522,19 @@ export class BST<
521
522
  }
522
523
  // TODO potential bug
523
524
  if (callback === this._defaultOneParamCallback) {
524
- if (this._compare(cur.key, identifier as K) === CP.gt) this.isRealNode(cur.left) && queue.push(cur.left);
525
- if (this._compare(cur.key, identifier as K) === CP.lt) this.isRealNode(cur.right) && queue.push(cur.right);
525
+ if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') stack.push(cur.right);
526
+ if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') stack.push(cur.left);
527
+
528
+ // if (this.isRealNode(cur.right) && this._lt(cur.key, identifier as K)) stack.push(cur.right);
529
+ // if (this.isRealNode(cur.left) && this._gt(cur.key, identifier as K)) stack.push(cur.left);
530
+
531
+ // // @ts-ignore
532
+ // if (this.isRealNode(cur.right) && cur.key > identifier) stack.push(cur.right);
533
+ // // @ts-ignore
534
+ // if (this.isRealNode(cur.left) && cur.key < identifier) stack.push(cur.left);
526
535
  } else {
527
- this.isRealNode(cur.left) && queue.push(cur.left);
528
- this.isRealNode(cur.right) && queue.push(cur.right);
536
+ this.isRealNode(cur.right) && stack.push(cur.right);
537
+ this.isRealNode(cur.left) && stack.push(cur.left);
529
538
  }
530
539
  }
531
540
  }
@@ -560,9 +569,9 @@ export class BST<
560
569
  */
561
570
  override dfs<C extends BTNCallback<NODE>>(
562
571
  callback: C = this._defaultOneParamCallback as C,
563
- pattern: DFSOrderPattern = 'in',
572
+ pattern: DFSOrderPattern = 'IN',
564
573
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
565
- iterationType: IterationType = IterationType.ITERATIVE
574
+ iterationType: IterationType = 'ITERATIVE'
566
575
  ): ReturnType<C>[] {
567
576
  return super.dfs(callback, pattern, beginRoot, iterationType, false);
568
577
  }
@@ -592,7 +601,7 @@ export class BST<
592
601
  override bfs<C extends BTNCallback<NODE>>(
593
602
  callback: C = this._defaultOneParamCallback as C,
594
603
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
595
- iterationType = this.iterationType
604
+ iterationType: IterationType = this.iterationType
596
605
  ): ReturnType<C>[] {
597
606
  return super.bfs(callback, beginRoot, iterationType, false);
598
607
  }
@@ -623,7 +632,7 @@ export class BST<
623
632
  override listLevels<C extends BTNCallback<NODE>>(
624
633
  callback: C = this._defaultOneParamCallback as C,
625
634
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
626
- iterationType = this.iterationType
635
+ iterationType: IterationType = this.iterationType
627
636
  ): ReturnType<C>[][] {
628
637
  return super.listLevels(callback, beginRoot, iterationType, false);
629
638
  }
@@ -650,7 +659,7 @@ export class BST<
650
659
  let current = this.ensureNode(beginRoot);
651
660
  if (!current) return undefined;
652
661
 
653
- if (this._variant === BSTVariant.STANDARD) {
662
+ if (this._variant === 'STANDARD') {
654
663
  // For BSTVariant.MIN, find the rightmost node
655
664
  while (current.right !== undefined) {
656
665
  current = current.right;
@@ -692,9 +701,9 @@ export class BST<
692
701
  */
693
702
  lesserOrGreaterTraverse<C extends BTNCallback<NODE>>(
694
703
  callback: C = this._defaultOneParamCallback as C,
695
- lesserOrGreater: CP = CP.lt,
704
+ lesserOrGreater: CP = 'LT',
696
705
  targetNode: KeyOrNodeOrEntry<K, V, NODE> = this.root,
697
- iterationType = this.iterationType
706
+ iterationType: IterationType = this.iterationType
698
707
  ): ReturnType<C>[] {
699
708
  targetNode = this.ensureNode(targetNode);
700
709
  const ans: ReturnType<BTNCallback<NODE>>[] = [];
@@ -703,7 +712,7 @@ export class BST<
703
712
 
704
713
  const targetKey = targetNode.key;
705
714
 
706
- if (iterationType === IterationType.RECURSIVE) {
715
+ if (iterationType === 'RECURSIVE') {
707
716
  const _traverse = (cur: NODE) => {
708
717
  const compared = this._compare(cur.key, targetKey);
709
718
  if (compared === lesserOrGreater) ans.push(callback(cur));
@@ -746,13 +755,13 @@ export class BST<
746
755
  * values:
747
756
  * @returns The function `perfectlyBalance` returns a boolean value.
748
757
  */
749
- perfectlyBalance(iterationType = this.iterationType): boolean {
750
- const sorted = this.dfs(node => node, 'in'),
758
+ perfectlyBalance(iterationType: IterationType = this.iterationType): boolean {
759
+ const sorted = this.dfs(node => node, 'IN'),
751
760
  n = sorted.length;
752
761
  this.clear();
753
762
 
754
763
  if (sorted.length < 1) return false;
755
- if (iterationType === IterationType.RECURSIVE) {
764
+ if (iterationType === 'RECURSIVE') {
756
765
  const buildBalanceBST = (l: number, r: number) => {
757
766
  if (l > r) return;
758
767
  const m = l + Math.floor((r - l) / 2);
@@ -807,12 +816,12 @@ export class BST<
807
816
  * to check if the AVL tree is balanced. It can have two possible values:
808
817
  * @returns a boolean value.
809
818
  */
810
- isAVLBalanced(iterationType = this.iterationType): boolean {
819
+ isAVLBalanced(iterationType: IterationType = this.iterationType): boolean {
811
820
  if (!this.root) return true;
812
821
 
813
822
  let balanced = true;
814
823
 
815
- if (iterationType === IterationType.RECURSIVE) {
824
+ if (iterationType === 'RECURSIVE') {
816
825
  const _height = (cur: NODE | undefined): number => {
817
826
  if (!cur) return 0;
818
827
  const leftHeight = _height(cur.left),
@@ -868,14 +877,49 @@ export class BST<
868
877
  * is greater than, less than, or equal to the second value.
869
878
  * @param {K} a - The parameter "a" is of type K.
870
879
  * @param {K} b - The parameter "b" in the above code represents a K.
871
- * @returns a value of type CP (ComparisonResult). The possible return values are CP.gt (greater
872
- * than), CP.lt (less than), or CP.eq (equal).
880
+ * @returns a value of type CP (ComparisonResult). The possible return values are 'GT' (greater
881
+ * than), 'LT' (less than), or 'EQ' (equal).
873
882
  */
874
883
  protected _compare(a: K, b: K): CP {
875
884
  const extractedA = this.extractor(a);
876
885
  const extractedB = this.extractor(b);
877
- const compared = this.variant === BSTVariant.STANDARD ? extractedA - extractedB : extractedB - extractedA;
886
+ const compared = this.variant === 'STANDARD' ? extractedA - extractedB : extractedB - extractedA;
878
887
 
879
- return compared > 0 ? CP.gt : compared < 0 ? CP.lt : CP.eq;
888
+ return compared > 0 ? 'GT' : compared < 0 ? 'LT' : 'EQ';
889
+ }
890
+
891
+ /**
892
+ * The function `_lt` compares two values `a` and `b` using an extractor function and returns true if
893
+ * `a` is less than `b` based on the specified variant.
894
+ * @param {K} a - The parameter "a" is of type "K", which means it can be any type. It represents the
895
+ * first value to be compared in the function.
896
+ * @param {K} b - The parameter `b` is of type `K`, which means it can be any type. It is used as one
897
+ * of the arguments for the comparison in the `_lt` function.
898
+ * @returns a boolean value.
899
+ */
900
+ protected _lt(a: K, b: K): boolean {
901
+ const extractedA = this.extractor(a);
902
+ const extractedB = this.extractor(b);
903
+ // return this.variant === BSTVariant.STANDARD ? extractedA < extractedB : extractedA > extractedB;
904
+ return this.variant === 'STANDARD' ? extractedA < extractedB : extractedA > extractedB;
905
+ // return extractedA < extractedB;
906
+ // return a < b;
907
+ }
908
+
909
+ /**
910
+ * The function compares two values using a custom extractor function and returns true if the first
911
+ * value is greater than the second value.
912
+ * @param {K} a - The parameter "a" is of type K, which means it can be any type.
913
+ * @param {K} b - The parameter "b" is of type K, which means it can be any type. It is used as one
914
+ * of the arguments for the comparison in the function.
915
+ * @returns a boolean value.
916
+ */
917
+ protected _gt(a: K, b: K): boolean {
918
+ const extractedA = this.extractor(a);
919
+ const extractedB = this.extractor(b);
920
+ // return this.variant === BSTVariant.STANDARD ? extractedA > extractedB : extractedA < extractedB;
921
+ return this.variant === 'STANDARD' ? extractedA > extractedB : extractedA < extractedB;
922
+ // return extractedA > extractedB;
923
+ // return a > b;
880
924
  }
881
925
  }
@@ -2,6 +2,7 @@ import type {
2
2
  BinaryTreeDeleteResult,
3
3
  BSTNKeyOrNode,
4
4
  BTNCallback,
5
+ IterationType,
5
6
  KeyOrNodeOrEntry,
6
7
  RBTreeOptions,
7
8
  RedBlackTreeNested,
@@ -25,9 +26,9 @@ export class RedBlackTreeNode<
25
26
  * associated with the key in the Red-Black Tree Node. It is not required and can be omitted when
26
27
  * creating a new instance of the Red-Black Tree Node.
27
28
  * @param {RBTNColor} color - The `color` parameter is used to specify the color of the Red-Black
28
- * Tree Node. It is an optional parameter with a default value of `RBTNColor.BLACK`.
29
+ * Tree Node. It is an optional parameter with a default value of `'BLACK'`.
29
30
  */
30
- constructor(key: K, value?: V, color: RBTNColor = RBTNColor.BLACK) {
31
+ constructor(key: K, value?: V, color: RBTNColor = 'BLACK') {
31
32
  super(key, value);
32
33
  this._color = color;
33
34
  }
@@ -106,12 +107,12 @@ export class RedBlackTree<
106
107
  * @param {V} [value] - The `value` parameter is an optional parameter that represents the value
107
108
  * associated with the key in the node. It is not required and can be omitted if not needed.
108
109
  * @param {RBTNColor} color - The "color" parameter is used to specify the color of the node in a
109
- * Red-Black Tree. It is an optional parameter with a default value of "RBTNColor.BLACK". The color
110
- * can be either "RBTNColor.RED" or "RBTNColor.BLACK".
110
+ * Red-Black Tree. It is an optional parameter with a default value of "'BLACK'". The color
111
+ * can be either "'RED'" or "'BLACK'".
111
112
  * @returns The method is returning a new instance of a RedBlackTreeNode with the specified key,
112
113
  * value, and color.
113
114
  */
114
- override createNode(key: K, value?: V, color: RBTNColor = RBTNColor.BLACK): NODE {
115
+ override createNode(key: K, value?: V, color: RBTNColor = 'BLACK'): NODE {
115
116
  return new RedBlackTreeNode<K, V, NODE>(key, value, color) as NODE;
116
117
  }
117
118
 
@@ -156,10 +157,10 @@ export class RedBlackTree<
156
157
  if (key === undefined || key === null) {
157
158
  return;
158
159
  } else {
159
- node = this.createNode(key, value, RBTNColor.RED);
160
+ node = this.createNode(key, value, 'RED');
160
161
  }
161
162
  } else if (!this.isNode(keyOrNodeOrEntry)) {
162
- node = this.createNode(keyOrNodeOrEntry, value, RBTNColor.RED);
163
+ node = this.createNode(keyOrNodeOrEntry, value, 'RED');
163
164
  } else {
164
165
  return;
165
166
  }
@@ -232,10 +233,9 @@ export class RedBlackTree<
232
233
  identifier: ReturnType<C> | undefined,
233
234
  callback: C = this._defaultOneParamCallback as C,
234
235
  beginRoot: BSTNKeyOrNode<K, NODE> = this.root,
235
- iterationType = this.iterationType
236
+ iterationType: IterationType = this.iterationType
236
237
  ): NODE | null | undefined {
237
- if ((identifier as any) instanceof RedBlackTreeNode) callback = (node => node) as C;
238
- return super.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined;
238
+ return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined;
239
239
  }
240
240
 
241
241
  /**
@@ -279,16 +279,16 @@ export class RedBlackTree<
279
279
 
280
280
  const insertStatus = this._insert(newNode);
281
281
 
282
- if (insertStatus === CRUD.CREATED) {
282
+ if (insertStatus === 'CREATED') {
283
283
  // Ensure the root is black
284
284
  if (this.isRealNode(this._root)) {
285
- this._root.color = RBTNColor.BLACK;
285
+ this._root.color = 'BLACK';
286
286
  } else {
287
287
  return false;
288
288
  }
289
289
  this._size++;
290
290
  return true;
291
- } else return insertStatus === CRUD.UPDATED;
291
+ } else return insertStatus === 'UPDATED';
292
292
  }
293
293
 
294
294
  /**
@@ -363,7 +363,7 @@ export class RedBlackTree<
363
363
  this._size--;
364
364
 
365
365
  // If the original color was black, fix the tree
366
- if (originalColor === RBTNColor.BLACK) {
366
+ if (originalColor === 'BLACK') {
367
367
  this._deleteFixup(replacementNode);
368
368
  }
369
369
 
@@ -435,7 +435,7 @@ export class RedBlackTree<
435
435
  current = current.right ?? this.SENTINEL;
436
436
  } else {
437
437
  this._replaceNode(current, node);
438
- return CRUD.UPDATED;
438
+ return 'UPDATED';
439
439
  }
440
440
  }
441
441
 
@@ -451,10 +451,10 @@ export class RedBlackTree<
451
451
 
452
452
  node.left = this.SENTINEL;
453
453
  node.right = this.SENTINEL;
454
- node.color = RBTNColor.RED;
454
+ node.color = 'RED';
455
455
 
456
456
  this._insertFixup(node);
457
- return CRUD.CREATED;
457
+ return 'CREATED';
458
458
  }
459
459
 
460
460
  /**
@@ -500,16 +500,16 @@ export class RedBlackTree<
500
500
  */
501
501
  protected _insertFixup(z: NODE | undefined): void {
502
502
  // Continue fixing the tree as long as the parent of z is red
503
- while (z?.parent?.color === RBTNColor.RED) {
503
+ while (z?.parent?.color === 'RED') {
504
504
  // Check if the parent of z is the left child of its parent
505
505
  if (z.parent === z.parent.parent?.left) {
506
506
  // Case 1: The uncle (y) of z is red
507
507
  const y = z.parent.parent.right;
508
- if (y?.color === RBTNColor.RED) {
508
+ if (y?.color === 'RED') {
509
509
  // Set colors to restore properties of Red-Black Tree
510
- z.parent.color = RBTNColor.BLACK;
511
- y.color = RBTNColor.BLACK;
512
- z.parent.parent.color = RBTNColor.RED;
510
+ z.parent.color = 'BLACK';
511
+ y.color = 'BLACK';
512
+ z.parent.parent.color = 'RED';
513
513
  // Move up the tree to continue fixing
514
514
  z = z.parent.parent;
515
515
  } else {
@@ -523,8 +523,8 @@ export class RedBlackTree<
523
523
  // Case 3: The uncle (y) of z is black, and z is a left child
524
524
  // Adjust colors and perform a right rotation
525
525
  if (z && this.isRealNode(z.parent) && this.isRealNode(z.parent.parent)) {
526
- z.parent.color = RBTNColor.BLACK;
527
- z.parent.parent.color = RBTNColor.RED;
526
+ z.parent.color = 'BLACK';
527
+ z.parent.parent.color = 'RED';
528
528
  this._rightRotate(z.parent.parent);
529
529
  }
530
530
  }
@@ -532,10 +532,10 @@ export class RedBlackTree<
532
532
  // Symmetric case for the right child (left and right exchanged)
533
533
  // Follow the same logic as above with left and right exchanged
534
534
  const y: NODE | undefined = z?.parent?.parent?.left;
535
- if (y?.color === RBTNColor.RED) {
536
- z.parent.color = RBTNColor.BLACK;
537
- y.color = RBTNColor.BLACK;
538
- z.parent.parent!.color = RBTNColor.RED;
535
+ if (y?.color === 'RED') {
536
+ z.parent.color = 'BLACK';
537
+ y.color = 'BLACK';
538
+ z.parent.parent!.color = 'RED';
539
539
  z = z.parent.parent;
540
540
  } else {
541
541
  if (z === z.parent.left) {
@@ -544,8 +544,8 @@ export class RedBlackTree<
544
544
  }
545
545
 
546
546
  if (z && this.isRealNode(z.parent) && this.isRealNode(z.parent.parent)) {
547
- z.parent.color = RBTNColor.BLACK;
548
- z.parent.parent.color = RBTNColor.RED;
547
+ z.parent.color = 'BLACK';
548
+ z.parent.parent.color = 'RED';
549
549
  this._leftRotate(z.parent.parent);
550
550
  }
551
551
  }
@@ -553,7 +553,7 @@ export class RedBlackTree<
553
553
  }
554
554
 
555
555
  // Ensure that the root is black after fixing
556
- if (this.isRealNode(this._root)) this._root.color = RBTNColor.BLACK;
556
+ if (this.isRealNode(this._root)) this._root.color = 'BLACK';
557
557
  }
558
558
 
559
559
  /**
@@ -573,14 +573,14 @@ export class RedBlackTree<
573
573
  */
574
574
  protected _deleteFixup(node: NODE | undefined): void {
575
575
  // Early exit condition
576
- if (!node || node === this.root || node.color === RBTNColor.BLACK) {
576
+ if (!node || node === this.root || node.color === 'BLACK') {
577
577
  if (node) {
578
- node.color = RBTNColor.BLACK; // Ensure the final node is black
578
+ node.color = 'BLACK'; // Ensure the final node is black
579
579
  }
580
580
  return;
581
581
  }
582
582
 
583
- while (node && node !== this.root && node.color === RBTNColor.BLACK) {
583
+ while (node && node !== this.root && node.color === 'BLACK') {
584
584
  const parent: NODE | undefined = node.parent;
585
585
 
586
586
  if (!parent) {
@@ -591,22 +591,22 @@ export class RedBlackTree<
591
591
  let sibling = parent.right;
592
592
 
593
593
  // Cases 1 and 2: Sibling is red or both children of sibling are black
594
- if (sibling?.color === RBTNColor.RED) {
595
- sibling.color = RBTNColor.BLACK;
596
- parent.color = RBTNColor.RED;
594
+ if (sibling?.color === 'RED') {
595
+ sibling.color = 'BLACK';
596
+ parent.color = 'RED';
597
597
  this._leftRotate(parent);
598
598
  sibling = parent.right;
599
599
  }
600
600
 
601
601
  // Case 3: Sibling's left child is black
602
- if ((sibling?.left?.color ?? RBTNColor.BLACK) === RBTNColor.BLACK) {
603
- if (sibling) sibling.color = RBTNColor.RED;
602
+ if ((sibling?.left?.color ?? 'BLACK') === 'BLACK') {
603
+ if (sibling) sibling.color = 'RED';
604
604
  node = parent;
605
605
  } else {
606
606
  // Case 4: Adjust colors and perform a right rotation
607
- if (sibling?.left) sibling.left.color = RBTNColor.BLACK;
607
+ if (sibling?.left) sibling.left.color = 'BLACK';
608
608
  if (sibling) sibling.color = parent.color;
609
- parent.color = RBTNColor.BLACK;
609
+ parent.color = 'BLACK';
610
610
  this._rightRotate(parent);
611
611
  node = this.root;
612
612
  }
@@ -615,22 +615,22 @@ export class RedBlackTree<
615
615
  let sibling = parent.left;
616
616
 
617
617
  // Cases 1 and 2: Sibling is red or both children of sibling are black
618
- if (sibling?.color === RBTNColor.RED) {
619
- sibling.color = RBTNColor.BLACK;
620
- if (parent) parent.color = RBTNColor.RED;
618
+ if (sibling?.color === 'RED') {
619
+ sibling.color = 'BLACK';
620
+ if (parent) parent.color = 'RED';
621
621
  this._rightRotate(parent);
622
622
  if (parent) sibling = parent.left;
623
623
  }
624
624
 
625
625
  // Case 3: Sibling's left child is black
626
- if ((sibling?.right?.color ?? RBTNColor.BLACK) === RBTNColor.BLACK) {
627
- if (sibling) sibling.color = RBTNColor.RED;
626
+ if ((sibling?.right?.color ?? 'BLACK') === 'BLACK') {
627
+ if (sibling) sibling.color = 'RED';
628
628
  node = parent;
629
629
  } else {
630
630
  // Case 4: Adjust colors and perform a left rotation
631
- if (sibling?.right) sibling.right.color = RBTNColor.BLACK;
631
+ if (sibling?.right) sibling.right.color = 'BLACK';
632
632
  if (sibling) sibling.color = parent.color;
633
- if (parent) parent.color = RBTNColor.BLACK;
633
+ if (parent) parent.color = 'BLACK';
634
634
  this._leftRotate(parent);
635
635
  node = this.root;
636
636
  }
@@ -639,7 +639,7 @@ export class RedBlackTree<
639
639
 
640
640
  // Ensure that the final node (possibly the root) is black
641
641
  if (node) {
642
- node.color = RBTNColor.BLACK;
642
+ node.color = 'BLACK';
643
643
  }
644
644
  }
645
645