min-heap-typed 1.42.5 → 1.42.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,7 +12,8 @@ import {IBinaryTree} from '../../interfaces';
12
12
  import {Queue} from '../queue';
13
13
 
14
14
  export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extends BinaryTreeNode<V, N> {
15
- override parent: N | undefined;
15
+ override parent?: N ;
16
+
16
17
  constructor(key: BTNKey, value?: V) {
17
18
  super(key, value);
18
19
  this.parent = undefined;
@@ -20,7 +21,7 @@ export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extend
20
21
  this._right = undefined;
21
22
  }
22
23
 
23
- protected override _left: N | undefined;
24
+ protected override _left?: N ;
24
25
 
25
26
  /**
26
27
  * Get the left child node.
@@ -41,7 +42,7 @@ export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extend
41
42
  }
42
43
 
43
44
 
44
- protected override _right: N | undefined;
45
+ protected override _right?: N ;
45
46
 
46
47
  /**
47
48
  * Get the right child node.
@@ -64,8 +65,7 @@ export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extend
64
65
 
65
66
  export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>>
66
67
  extends BinaryTree<V, N>
67
- implements IBinaryTree<V, N>
68
- {
68
+ implements IBinaryTree<V, N> {
69
69
  /**
70
70
  * The constructor function initializes a binary search tree object with an optional comparator
71
71
  * function.
@@ -82,7 +82,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
82
82
  }
83
83
  }
84
84
  }
85
- protected override _root: N | undefined = undefined;
85
+
86
+ protected override _root?: N ;
86
87
 
87
88
  /**
88
89
  * Get the root node of the binary tree.
@@ -114,16 +115,13 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
114
115
  * was not added or if the parameters were invalid, it returns undefined or undefined.
115
116
  */
116
117
  override add(keyOrNode: BTNKey | N | null | undefined, value?: V): N | undefined {
117
- if (keyOrNode === 8) {
118
- debugger
119
- }
120
118
  if (keyOrNode === null) return undefined;
121
119
  // TODO support node as a parameter
122
- let inserted:N | undefined;
123
- let newNode:N | undefined;
120
+ let inserted: N | undefined;
121
+ let newNode: N | undefined;
124
122
  if (keyOrNode instanceof BSTNode) {
125
123
  newNode = keyOrNode;
126
- } else if (typeof keyOrNode === 'number') {
124
+ } else if (this.isNodeKey(keyOrNode)) {
127
125
  newNode = this.createNode(keyOrNode, value);
128
126
  } else {
129
127
  newNode = undefined;
@@ -196,59 +194,60 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
196
194
  * It can have two possible values:
197
195
  * @returns The `addMany` function returns an array of `N`, `undefined`, or `undefined` values.
198
196
  */
199
-
200
197
  override addMany(
201
- keysOrNodes: (BTNKey | undefined)[] | (N | undefined)[],
202
- data?: V[],
198
+ keysOrNodes: (BTNKey | N | undefined)[],
199
+ data?: (V | undefined)[],
203
200
  isBalanceAdd = true,
204
201
  iterationType = this.iterationType
205
202
  ): (N | undefined)[] {
206
203
  // TODO this addMany function is inefficient, it should be optimized
207
- function hasNoNull(arr: (BTNKey | undefined)[] | (N | undefined)[]): arr is BTNKey[] | N[] {
204
+ function hasNoUndefined(arr: (BTNKey | N | undefined)[]): arr is (BTNKey | N)[] {
208
205
  return arr.indexOf(undefined) === -1;
209
206
  }
210
207
 
211
- if (!isBalanceAdd || !hasNoNull(keysOrNodes)) {
208
+ if (!isBalanceAdd || !hasNoUndefined(keysOrNodes)) {
212
209
  return super.addMany(keysOrNodes, data).map(n => n ?? undefined);
213
210
  }
211
+
214
212
  const inserted: (N | undefined)[] = [];
215
213
  const combinedArr: [BTNKey | N, V][] = keysOrNodes.map(
216
214
  (value: BTNKey | N, index) => [value, data?.[index]] as [BTNKey | N, V]
217
215
  );
216
+
218
217
  let sorted = [];
219
218
 
220
- function isNodeOrNullTuple(arr: [BTNKey | N, V][]): arr is [N, V][] {
219
+ function _isNodeOrUndefinedTuple(arr: [BTNKey | N, V][]): arr is [N, V][] {
221
220
  for (const [keyOrNode] of arr) if (keyOrNode instanceof BSTNode) return true;
222
221
  return false;
223
222
  }
224
223
 
225
- function isBinaryTreeKeyOrNullTuple(arr: [BTNKey | N, V][]): arr is [BTNKey, V][] {
226
- for (const [keyOrNode] of arr) if (typeof keyOrNode === 'number') return true;
224
+ const _isBinaryTreeKeyOrNullTuple = (arr: [BTNKey | N, V][]): arr is [BTNKey, V][] => {
225
+ for (const [keyOrNode] of arr) if (this.isNodeKey(keyOrNode)) return true;
227
226
  return false;
228
227
  }
229
228
 
230
229
  let sortedKeysOrNodes: (number | N | undefined)[] = [],
231
230
  sortedData: (V | undefined)[] | undefined = [];
232
231
 
233
- if (isNodeOrNullTuple(combinedArr)) {
232
+ if (_isNodeOrUndefinedTuple(combinedArr)) {
234
233
  sorted = combinedArr.sort((a, b) => a[0].key - b[0].key);
235
- } else if (isBinaryTreeKeyOrNullTuple(combinedArr)) {
234
+ } else if (_isBinaryTreeKeyOrNullTuple(combinedArr)) {
236
235
  sorted = combinedArr.sort((a, b) => a[0] - b[0]);
237
236
  } else {
238
237
  throw new Error('Invalid input keysOrNodes');
239
238
  }
240
239
  sortedKeysOrNodes = sorted.map(([keyOrNode]) => keyOrNode);
241
240
  sortedData = sorted.map(([, value]) => value);
242
- const recursive = (arr: (BTNKey | undefined | N)[], data?: (V | undefined)[]) => {
241
+ const _dfs = (arr: (BTNKey | undefined | N)[], data?: (V | undefined)[]) => {
243
242
  if (arr.length === 0) return;
244
243
 
245
244
  const mid = Math.floor((arr.length - 1) / 2);
246
245
  const newNode = this.add(arr[mid], data?.[mid]);
247
246
  inserted.push(newNode);
248
- recursive(arr.slice(0, mid), data?.slice(0, mid));
249
- recursive(arr.slice(mid + 1), data?.slice(mid + 1));
247
+ _dfs(arr.slice(0, mid), data?.slice(0, mid));
248
+ _dfs(arr.slice(mid + 1), data?.slice(mid + 1));
250
249
  };
251
- const iterative = () => {
250
+ const _iterate = () => {
252
251
  const n = sorted.length;
253
252
  const stack: [[number, number]] = [[0, n - 1]];
254
253
  while (stack.length > 0) {
@@ -266,9 +265,9 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
266
265
  }
267
266
  };
268
267
  if (iterationType === IterationType.RECURSIVE) {
269
- recursive(sortedKeysOrNodes, sortedData);
268
+ _dfs(sortedKeysOrNodes, sortedData);
270
269
  } else {
271
- iterative();
270
+ _iterate();
272
271
  }
273
272
 
274
273
  return inserted;
@@ -289,12 +288,61 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
289
288
  * the key of the leftmost node if the comparison result is greater than, and the key of the
290
289
  * rightmost node otherwise. If no node is found, it returns 0.
291
290
  */
292
- lastKey(beginRoot: N | undefined = this.root, iterationType = this.iterationType): BTNKey {
291
+ lastKey(beginRoot: BTNKey | N | undefined = this.root, iterationType = this.iterationType): BTNKey {
293
292
  if (this._compare(0, 1) === CP.lt) return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
294
293
  else if (this._compare(0, 1) === CP.gt) return this.getLeftMost(beginRoot, iterationType)?.key ?? 0;
295
294
  else return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
296
295
  }
297
296
 
297
+ /**
298
+ * The function `getNodeByKey` searches for a node in a binary tree based on a given key, using
299
+ * either recursive or iterative methods.
300
+ * @param {BTNKey} key - The `key` parameter is the key value that we are searching for in the tree.
301
+ * It is used to find the node with the matching key value.
302
+ * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
303
+ * type of iteration to use when searching for a node in the binary tree. It can have two possible
304
+ * values:
305
+ * @returns The function `getNodeByKey` returns a node (`N`) if a node with the specified key is
306
+ * found in the binary tree. If no node is found, it returns `undefined`.
307
+ */
308
+ override getNodeByKey(key: BTNKey, iterationType = IterationType.ITERATIVE): N | undefined {
309
+ if (!this.root) return undefined;
310
+ if (iterationType === IterationType.RECURSIVE) {
311
+ const _dfs = (cur: N): N | undefined => {
312
+ if (cur.key === key) return cur;
313
+ if (!cur.left && !cur.right) return;
314
+
315
+ if (this._compare(cur.key, key) === CP.gt && cur.left) return _dfs(cur.left);
316
+ if (this._compare(cur.key, key) === CP.lt && cur.right) return _dfs(cur.right);
317
+ };
318
+
319
+ return _dfs(this.root);
320
+ } else {
321
+ const queue = new Queue<N>([this.root]);
322
+ while (queue.size > 0) {
323
+ const cur = queue.shift();
324
+ if (cur) {
325
+ if (this._compare(cur.key, key) === CP.eq) return cur;
326
+ if (this._compare(cur.key, key) === CP.gt) cur.left && queue.push(cur.left);
327
+ if (this._compare(cur.key, key) === CP.lt) cur.right && queue.push(cur.right);
328
+ }
329
+ }
330
+ }
331
+ }
332
+
333
+ /**
334
+ * The function `ensureNotKey` returns the node corresponding to the given key if it is a node key,
335
+ * otherwise it returns the key itself.
336
+ * @param {BTNKey | N | undefined} key - The `key` parameter can be of type `BTNKey`, `N`, or
337
+ * `undefined`.
338
+ * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
339
+ * type of iteration to be performed. It has a default value of `IterationType.ITERATIVE`.
340
+ * @returns either a node object (N) or undefined.
341
+ */
342
+ override ensureNotKey(key: BTNKey | N | undefined, iterationType = IterationType.ITERATIVE): N | undefined {
343
+ return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key;
344
+ }
345
+
298
346
  /**
299
347
  * The function `getNodes` retrieves nodes from a binary tree based on a given node property or key,
300
348
  * using either recursive or iterative traversal.
@@ -303,7 +351,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
303
351
  * generic type `N`.
304
352
  * @param callback - The `callback` parameter is a function that takes a node as input and returns a
305
353
  * value. This value is compared with the `nodeProperty` parameter to determine if the node should be
306
- * included in the result. The default value for `callback` is `this.defaultOneParamCallback`, which is
354
+ * included in the result. The default value for `callback` is `this._defaultOneParamCallback`, which is
307
355
  * a
308
356
  * @param [onlyOne=false] - A boolean value indicating whether to stop the traversal after finding
309
357
  * the first node that matches the nodeProperty. If set to true, the function will return an array
@@ -318,11 +366,12 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
318
366
  */
319
367
  override getNodes<C extends BTNCallback<N>>(
320
368
  identifier: ReturnType<C> | undefined,
321
- callback: C = this.defaultOneParamCallback as C,
369
+ callback: C = this._defaultOneParamCallback as C,
322
370
  onlyOne = false,
323
- beginRoot: N | undefined = this.root,
371
+ beginRoot: BTNKey | N | undefined = this.root,
324
372
  iterationType = this.iterationType
325
373
  ): N[] {
374
+ beginRoot = this.ensureNotKey(beginRoot);
326
375
  if (!beginRoot) return [];
327
376
  const ans: N[] = [];
328
377
 
@@ -336,7 +385,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
336
385
 
337
386
  if (!cur.left && !cur.right) return;
338
387
  // TODO potential bug
339
- if (callback === this.defaultOneParamCallback) {
388
+ if (callback === this._defaultOneParamCallback) {
340
389
  if (this._compare(cur.key, identifier as number) === CP.gt) cur.left && _traverse(cur.left);
341
390
  if (this._compare(cur.key, identifier as number) === CP.lt) cur.right && _traverse(cur.right);
342
391
  } else {
@@ -357,7 +406,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
357
406
  if (onlyOne) return ans;
358
407
  }
359
408
  // TODO potential bug
360
- if (callback === this.defaultOneParamCallback) {
409
+ if (callback === this._defaultOneParamCallback) {
361
410
  if (this._compare(cur.key, identifier as number) === CP.gt) cur.left && queue.push(cur.left);
362
411
  if (this._compare(cur.key, identifier as number) === CP.lt) cur.right && queue.push(cur.right);
363
412
  } else {
@@ -391,17 +440,18 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
391
440
  * @returns The function `lesserOrGreaterTraverse` returns an array of `ReturnType<BTNCallback<N>>`.
392
441
  */
393
442
  lesserOrGreaterTraverse<C extends BTNCallback<N>>(
394
- callback: C = this.defaultOneParamCallback as C,
443
+ callback: C = this._defaultOneParamCallback as C,
395
444
  lesserOrGreater: CP = CP.lt,
396
445
  targetNode: BTNKey | N | undefined = this.root,
397
446
  iterationType = this.iterationType
398
447
  ): ReturnType<C>[] {
399
- if (typeof targetNode === 'number') targetNode = this.getNode(targetNode) ?? undefined;
448
+ targetNode = this.ensureNotKey(targetNode);
400
449
  const ans: ReturnType<BTNCallback<N>>[] = [];
401
450
  if (!targetNode) return ans;
402
- const targetKey = targetNode.key;
403
451
  if (!this.root) return ans;
404
452
 
453
+ const targetKey = targetNode.key;
454
+
405
455
  if (iterationType === IterationType.RECURSIVE) {
406
456
  const _traverse = (cur: N) => {
407
457
  const compared = this._compare(cur.key, targetKey);
@@ -509,7 +559,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
509
559
  } else {
510
560
  const stack: N[] = [];
511
561
  let node: N | undefined = this.root,
512
- last:N | undefined = undefined;
562
+ last: N | undefined = undefined;
513
563
  const depths: Map<N, number> = new Map();
514
564
 
515
565
  while (stack.length > 0 || node) {
@@ -7,19 +7,19 @@
7
7
  */
8
8
 
9
9
  import {
10
- BinaryTreeDeletedResult,
10
+ BiTreeDeleteResult,
11
11
  BTNCallback,
12
12
  BTNKey,
13
13
  IterationType,
14
14
  RBTNColor,
15
- RBTreeNodeNested,
15
+ RedBlackTreeNodeNested,
16
16
  RBTreeOptions
17
17
  } from '../../types';
18
18
  import {BST, BSTNode} from "./bst";
19
19
  import {IBinaryTree} from "../../interfaces";
20
20
  import {BinaryTreeNode} from "./binary-tree";
21
21
 
22
- export class RBTreeNode<V = any, N extends RBTreeNode<V, N> = RBTreeNodeNested<V>> extends BSTNode<V, N> {
22
+ export class RedBlackTreeNode<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTreeNodeNested<V>> extends BSTNode<V, N> {
23
23
  color: RBTNColor;
24
24
  constructor(key: BTNKey, value?: V, color: RBTNColor = RBTNColor.BLACK) {
25
25
  super(key, value);
@@ -34,7 +34,7 @@ export class RBTreeNode<V = any, N extends RBTreeNode<V, N> = RBTreeNodeNested<V
34
34
  * 4. Red nodes must have black children.
35
35
  * 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.
36
36
  */
37
- export class RedBlackTree<V = any, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNested<V>>>
37
+ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTreeNode<V, RedBlackTreeNodeNested<V>>>
38
38
  extends BST<V, N>
39
39
  implements IBinaryTree<V, N>
40
40
  {
@@ -56,13 +56,21 @@ export class RedBlackTree<V = any, N extends RBTreeNode<V, N> = RBTreeNode<V, RB
56
56
  return this._size;
57
57
  }
58
58
 
59
- NIL: N = new RBTreeNode<V>(NaN) as unknown as N;
59
+ NIL: N = new RedBlackTreeNode<V>(NaN) as unknown as N;
60
60
 
61
+ /**
62
+ * The `add` function adds a new node to a Red-Black Tree data structure.
63
+ * @param {BTNKey | N | null | undefined} keyOrNode - The `keyOrNode` parameter can be one of the
64
+ * following types:
65
+ * @param {V} [value] - The `value` parameter is an optional value that can be associated with the
66
+ * key in the node being added to the Red-Black Tree.
67
+ * @returns The method returns either a node (`N`) or `undefined`.
68
+ */
61
69
  override add(keyOrNode: BTNKey | N | null | undefined, value?: V): N | undefined {
62
70
  let node: N;
63
- if (typeof keyOrNode === 'number') {
71
+ if (this.isNodeKey(keyOrNode)) {
64
72
  node = this.createNode(keyOrNode, value, RBTNColor.RED);
65
- } else if(keyOrNode instanceof RBTreeNode) {
73
+ } else if(keyOrNode instanceof RedBlackTreeNode) {
66
74
  node = keyOrNode;
67
75
  } else if (keyOrNode === null) {
68
76
  return;
@@ -112,15 +120,26 @@ export class RedBlackTree<V = any, N extends RBTreeNode<V, N> = RBTreeNode<V, RB
112
120
  }
113
121
 
114
122
  override createNode(key: BTNKey, value?: V, color: RBTNColor = RBTNColor.BLACK): N {
115
- return new RBTreeNode<V, N>(key, value, color) as N;
123
+ return new RedBlackTreeNode<V, N>(key, value, color) as N;
116
124
  }
117
-
118
-
125
+
126
+ /**
127
+ * The `delete` function removes a node from a binary tree based on a given identifier and updates
128
+ * the tree accordingly.
129
+ * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
130
+ * that you want to use to identify the node that you want to delete from the binary tree. It can be
131
+ * of any type that is returned by the callback function `C`. It can also be `null` or `undefined` if
132
+ * you don't want to
133
+ * @param {C} callback - The `callback` parameter is a function that takes a node of type `N` and
134
+ * returns a value of type `ReturnType<C>`. It is used to determine if a node should be deleted based
135
+ * on its identifier. The `callback` function is optional and defaults to `this._defaultOneParam
136
+ * @returns an array of `BiTreeDeleteResult<N>`.
137
+ */
119
138
  delete<C extends BTNCallback<N>>(
120
139
  identifier: ReturnType<C> | null | undefined,
121
- callback: C = this.defaultOneParamCallback as C
122
- ): BinaryTreeDeletedResult<N>[] {
123
- const ans: BinaryTreeDeletedResult<N>[] = [];
140
+ callback: C = this._defaultOneParamCallback as C
141
+ ): BiTreeDeleteResult<N>[] {
142
+ const ans: BiTreeDeleteResult<N>[] = [];
124
143
  if (identifier === null) return ans;
125
144
  const helper = (node: N | undefined): void => {
126
145
  let z: N = this.NIL;
@@ -151,7 +170,7 @@ export class RedBlackTree<V = any, N extends RBTreeNode<V, N> = RBTreeNode<V, RB
151
170
  x = z.left;
152
171
  this._rbTransplant(z, z.left!);
153
172
  } else {
154
- y = this.getLeftMost(z.right);
173
+ y = this.getLeftMost(z.right)!;
155
174
  yOriginalColor = y.color;
156
175
  x = y.right;
157
176
  if (y.parent === z) {
@@ -177,7 +196,7 @@ export class RedBlackTree<V = any, N extends RBTreeNode<V, N> = RBTreeNode<V, RB
177
196
  return ans;
178
197
  }
179
198
 
180
- isNode(node: N | undefined): node is N {
199
+ override isRealNode(node: N | undefined): node is N {
181
200
  return node !== this.NIL && node !== undefined;
182
201
  }
183
202
 
@@ -210,7 +229,7 @@ export class RedBlackTree<V = any, N extends RBTreeNode<V, N> = RBTreeNode<V, RB
210
229
  * @param callback - The `callback` parameter is a function that is used to determine whether a node
211
230
  * matches the desired criteria. It takes a node as input and returns a boolean value indicating
212
231
  * whether the node matches the criteria or not. The default callback function
213
- * (`this.defaultOneParamCallback`) is used if no callback function is
232
+ * (`this._defaultOneParamCallback`) is used if no callback function is
214
233
  * @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
215
234
  * the root node from which the search should begin.
216
235
  * @param iterationType - The `iterationType` parameter specifies the type of iteration to be
@@ -219,48 +238,23 @@ export class RedBlackTree<V = any, N extends RBTreeNode<V, N> = RBTreeNode<V, RB
219
238
  */
220
239
  getNode<C extends BTNCallback<N>>(
221
240
  identifier: ReturnType<C> | undefined,
222
- callback: C = this.defaultOneParamCallback as C,
223
- beginRoot = this.root,
241
+ callback: C = this._defaultOneParamCallback as C,
242
+ beginRoot: BTNKey | N | undefined = this.root,
224
243
  iterationType = this.iterationType
225
244
  ): N | null | undefined {
226
245
  if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
227
-
246
+ beginRoot = this.ensureNotKey(beginRoot);
228
247
  return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined;
229
248
  }
230
249
 
231
- /**
232
- * The function returns the leftmost node in a red-black tree.
233
- * @param {RBTreeNode} node - The parameter "node" is of type RBTreeNode, which represents a node in
234
- * a Red-Black Tree.
235
- * @returns The leftmost node in the given RBTreeNode.
236
- */
237
- getLeftMost(node: N = this.root): N {
238
- while (node.left !== undefined && node.left !== this.NIL) {
239
- node = node.left;
240
- }
241
- return node;
242
- }
243
-
244
- /**
245
- * The function returns the rightmost node in a red-black tree.
246
- * @param {RBTreeNode} node - The parameter "node" is of type RBTreeNode.
247
- * @returns the rightmost node in a red-black tree.
248
- */
249
- getRightMost(node: N): N {
250
- while (node.right !== undefined && node.right !== this.NIL) {
251
- node = node.right;
252
- }
253
- return node;
254
- }
255
-
256
250
  /**
257
251
  * The function returns the successor of a given node in a red-black tree.
258
- * @param {RBTreeNode} x - RBTreeNode - The node for which we want to find the successor.
259
- * @returns the successor of the given RBTreeNode.
252
+ * @param {RedBlackTreeNode} x - RedBlackTreeNode - The node for which we want to find the successor.
253
+ * @returns the successor of the given RedBlackTreeNode.
260
254
  */
261
- getSuccessor(x: N): N | undefined {
255
+ override getSuccessor(x: N): N | undefined {
262
256
  if (x.right !== this.NIL) {
263
- return this.getLeftMost(x.right);
257
+ return this.getLeftMost(x.right) ?? undefined;
264
258
  }
265
259
 
266
260
  let y: N | undefined = x.parent;
@@ -273,13 +267,13 @@ export class RedBlackTree<V = any, N extends RBTreeNode<V, N> = RBTreeNode<V, RB
273
267
 
274
268
  /**
275
269
  * The function returns the predecessor of a given node in a red-black tree.
276
- * @param {RBTreeNode} x - The parameter `x` is of type `RBTreeNode`, which represents a node in a
270
+ * @param {RedBlackTreeNode} x - The parameter `x` is of type `RedBlackTreeNode`, which represents a node in a
277
271
  * Red-Black Tree.
278
- * @returns the predecessor of the given RBTreeNode 'x'.
272
+ * @returns the predecessor of the given RedBlackTreeNode 'x'.
279
273
  */
280
- getPredecessor(x: N): N {
274
+ override getPredecessor(x: N): N {
281
275
  if (x.left !== this.NIL) {
282
- return this.getRightMost(x.left!);
276
+ return this.getRightMost(x.left!)!;
283
277
  }
284
278
 
285
279
  let y: N | undefined = x.parent;
@@ -305,7 +299,7 @@ export class RedBlackTree<V = any, N extends RBTreeNode<V, N> = RBTreeNode<V, RB
305
299
 
306
300
  /**
307
301
  * The function performs a left rotation on a red-black tree node.
308
- * @param {RBTreeNode} x - The parameter `x` is a RBTreeNode object.
302
+ * @param {RedBlackTreeNode} x - The parameter `x` is a RedBlackTreeNode object.
309
303
  */
310
304
  protected _leftRotate(x: N): void {
311
305
  if (x.right) {
@@ -329,7 +323,7 @@ export class RedBlackTree<V = any, N extends RBTreeNode<V, N> = RBTreeNode<V, RB
329
323
 
330
324
  /**
331
325
  * The function performs a right rotation on a red-black tree node.
332
- * @param {RBTreeNode} x - x is a RBTreeNode, which represents the node that needs to be right
326
+ * @param {RedBlackTreeNode} x - x is a RedBlackTreeNode, which represents the node that needs to be right
333
327
  * rotated.
334
328
  */
335
329
  protected _rightRotate(x: N): void {
@@ -354,7 +348,7 @@ export class RedBlackTree<V = any, N extends RBTreeNode<V, N> = RBTreeNode<V, RB
354
348
 
355
349
  /**
356
350
  * The _fixDelete function is used to rebalance the Red-Black Tree after a node deletion.
357
- * @param {RBTreeNode} x - The parameter `x` is of type `RBTreeNode`, which represents a node in a
351
+ * @param {RedBlackTreeNode} x - The parameter `x` is of type `RedBlackTreeNode`, which represents a node in a
358
352
  * red-black tree.
359
353
  */
360
354
  protected _fixDelete(x: N): void {
@@ -419,8 +413,8 @@ export class RedBlackTree<V = any, N extends RBTreeNode<V, N> = RBTreeNode<V, RB
419
413
 
420
414
  /**
421
415
  * The function `_rbTransplant` replaces one node in a red-black tree with another node.
422
- * @param {RBTreeNode} u - The parameter "u" represents a RBTreeNode object.
423
- * @param {RBTreeNode} v - The parameter "v" is a RBTreeNode object.
416
+ * @param {RedBlackTreeNode} u - The parameter "u" represents a RedBlackTreeNode object.
417
+ * @param {RedBlackTreeNode} v - The parameter "v" is a RedBlackTreeNode object.
424
418
  */
425
419
  protected _rbTransplant(u: N, v: N): void {
426
420
  if (u.parent === undefined) {
@@ -435,7 +429,7 @@ export class RedBlackTree<V = any, N extends RBTreeNode<V, N> = RBTreeNode<V, RB
435
429
 
436
430
  /**
437
431
  * The `_fixInsert` function is used to fix the red-black tree after an insertion operation.
438
- * @param {RBTreeNode} k - The parameter `k` is a RBTreeNode object, which represents a node in a
432
+ * @param {RedBlackTreeNode} k - The parameter `k` is a RedBlackTreeNode object, which represents a node in a
439
433
  * red-black tree.
440
434
  */
441
435
  protected _fixInsert(k: N): void {