data-structure-typed 1.42.3 → 1.42.4

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 (47) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/dist/cjs/src/data-structures/binary-tree/avl-tree.d.ts +2 -2
  3. package/dist/cjs/src/data-structures/binary-tree/avl-tree.js +5 -3
  4. package/dist/cjs/src/data-structures/binary-tree/avl-tree.js.map +1 -1
  5. package/dist/cjs/src/data-structures/binary-tree/binary-tree.d.ts +56 -52
  6. package/dist/cjs/src/data-structures/binary-tree/binary-tree.js +115 -53
  7. package/dist/cjs/src/data-structures/binary-tree/binary-tree.js.map +1 -1
  8. package/dist/cjs/src/data-structures/binary-tree/bst.d.ts +42 -15
  9. package/dist/cjs/src/data-structures/binary-tree/bst.js +77 -21
  10. package/dist/cjs/src/data-structures/binary-tree/bst.js.map +1 -1
  11. package/dist/cjs/src/data-structures/binary-tree/rb-tree.d.ts +28 -51
  12. package/dist/cjs/src/data-structures/binary-tree/rb-tree.js +148 -180
  13. package/dist/cjs/src/data-structures/binary-tree/rb-tree.js.map +1 -1
  14. package/dist/cjs/src/data-structures/binary-tree/tree-multiset.d.ts +10 -10
  15. package/dist/cjs/src/data-structures/binary-tree/tree-multiset.js +20 -17
  16. package/dist/cjs/src/data-structures/binary-tree/tree-multiset.js.map +1 -1
  17. package/dist/cjs/src/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
  18. package/dist/cjs/src/types/data-structures/binary-tree/rb-tree.d.ts +4 -0
  19. package/dist/cjs/src/types/data-structures/binary-tree/rb-tree.js +0 -5
  20. package/dist/cjs/src/types/data-structures/binary-tree/rb-tree.js.map +1 -1
  21. package/dist/mjs/src/data-structures/binary-tree/avl-tree.d.ts +2 -2
  22. package/dist/mjs/src/data-structures/binary-tree/avl-tree.js +5 -3
  23. package/dist/mjs/src/data-structures/binary-tree/binary-tree.d.ts +56 -52
  24. package/dist/mjs/src/data-structures/binary-tree/binary-tree.js +115 -53
  25. package/dist/mjs/src/data-structures/binary-tree/bst.d.ts +42 -15
  26. package/dist/mjs/src/data-structures/binary-tree/bst.js +79 -21
  27. package/dist/mjs/src/data-structures/binary-tree/rb-tree.d.ts +28 -51
  28. package/dist/mjs/src/data-structures/binary-tree/rb-tree.js +148 -184
  29. package/dist/mjs/src/data-structures/binary-tree/tree-multiset.d.ts +10 -10
  30. package/dist/mjs/src/data-structures/binary-tree/tree-multiset.js +19 -17
  31. package/dist/mjs/src/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
  32. package/dist/mjs/src/types/data-structures/binary-tree/rb-tree.d.ts +4 -0
  33. package/dist/mjs/src/types/data-structures/binary-tree/rb-tree.js +0 -5
  34. package/dist/umd/data-structure-typed.min.js +1 -1
  35. package/dist/umd/data-structure-typed.min.js.map +1 -1
  36. package/package.json +1 -1
  37. package/src/data-structures/binary-tree/avl-tree.ts +5 -4
  38. package/src/data-structures/binary-tree/binary-tree.ts +201 -131
  39. package/src/data-structures/binary-tree/bst.ts +100 -34
  40. package/src/data-structures/binary-tree/rb-tree.ts +227 -236
  41. package/src/data-structures/binary-tree/tree-multiset.ts +24 -23
  42. package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
  43. package/src/types/data-structures/binary-tree/rb-tree.ts +5 -5
  44. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +20 -1
  45. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +12 -31
  46. package/test/unit/data-structures/binary-tree/bst.test.ts +3 -3
  47. package/test/unit/data-structures/binary-tree/rb-tree.test.ts +205 -159
@@ -7,24 +7,18 @@
7
7
  * @license MIT License
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.RedBlackTree = exports.NIL = exports.RBTreeNode = void 0;
10
+ exports.RedBlackTree = exports.RBTreeNode = void 0;
11
11
  const types_1 = require("../../types");
12
- class RBTreeNode {
13
- key;
14
- parent;
15
- left;
16
- right;
17
- color = types_1.RBTNColor.BLACK;
18
- constructor(key, color = types_1.RBTNColor.BLACK) {
19
- this.key = key;
12
+ const bst_1 = require("./bst");
13
+ const binary_tree_1 = require("./binary-tree");
14
+ class RBTreeNode extends bst_1.BSTNode {
15
+ color;
16
+ constructor(key, value, color = types_1.RBTNColor.BLACK) {
17
+ super(key, value);
20
18
  this.color = color;
21
- this.parent = null;
22
- this.left = null;
23
- this.right = null;
24
19
  }
25
20
  }
26
21
  exports.RBTreeNode = RBTreeNode;
27
- exports.NIL = new RBTreeNode(0);
28
22
  /**
29
23
  * 1. Each node is either red or black.
30
24
  * 2. The root node is always black.
@@ -32,9 +26,10 @@ exports.NIL = new RBTreeNode(0);
32
26
  * 4. Red nodes must have black children.
33
27
  * 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.
34
28
  */
35
- class RedBlackTree {
36
- constructor() {
37
- this._root = exports.NIL;
29
+ class RedBlackTree extends bst_1.BST {
30
+ constructor(options) {
31
+ super(options);
32
+ this._root = this.NIL;
38
33
  }
39
34
  _root;
40
35
  get root() {
@@ -44,31 +39,40 @@ class RedBlackTree {
44
39
  get size() {
45
40
  return this._size;
46
41
  }
47
- /**
48
- * The `insert` function inserts a new node with a given key into a red-black tree and fixes any
49
- * violations of the red-black tree properties.
50
- * @param {number} key - The key parameter is a number that represents the value to be inserted into
51
- * the RBTree.
52
- * @returns The function does not explicitly return anything.
53
- */
54
- add(key) {
55
- const node = new RBTreeNode(key, types_1.RBTNColor.RED);
56
- node.left = exports.NIL;
57
- node.right = exports.NIL;
58
- let y = null;
42
+ NIL = new RBTreeNode(NaN);
43
+ add(keyOrNode, value) {
44
+ let node;
45
+ if (typeof keyOrNode === 'number') {
46
+ node = this.createNode(keyOrNode, value, types_1.RBTNColor.RED);
47
+ }
48
+ else if (keyOrNode instanceof RBTreeNode) {
49
+ node = keyOrNode;
50
+ }
51
+ else if (keyOrNode === null) {
52
+ return;
53
+ }
54
+ else if (keyOrNode === undefined) {
55
+ return;
56
+ }
57
+ else {
58
+ return;
59
+ }
60
+ node.left = this.NIL;
61
+ node.right = this.NIL;
62
+ let y = undefined;
59
63
  let x = this.root;
60
- while (x !== exports.NIL) {
64
+ while (x !== this.NIL) {
61
65
  y = x;
62
- if (node.key < x.key) {
66
+ if (x && node.key < x.key) {
63
67
  x = x.left;
64
68
  }
65
69
  else {
66
- x = x.right;
70
+ x = x?.right;
67
71
  }
68
72
  }
69
73
  node.parent = y;
70
- if (y === null) {
71
- this._root = node;
74
+ if (y === undefined) {
75
+ this._setRoot(node);
72
76
  }
73
77
  else if (node.key < y.key) {
74
78
  y.left = node;
@@ -76,51 +80,50 @@ class RedBlackTree {
76
80
  else {
77
81
  y.right = node;
78
82
  }
79
- if (node.parent === null) {
83
+ if (node.parent === undefined) {
80
84
  node.color = types_1.RBTNColor.BLACK;
81
85
  this._size++;
82
86
  return;
83
87
  }
84
- if (node.parent.parent === null) {
88
+ if (node.parent.parent === undefined) {
85
89
  this._size++;
86
90
  return;
87
91
  }
88
92
  this._fixInsert(node);
89
93
  this._size++;
90
94
  }
91
- /**
92
- * The `delete` function in TypeScript is used to remove a node with a specific key from a red-black
93
- * tree.
94
- * @param {number} key - The `node` parameter is of type `RBTreeNode` and represents the current
95
- * node being processed in the delete operation.
96
- * @returns The `delete` function does not return anything. It has a return type of `void`.
97
- */
98
- delete(key) {
95
+ createNode(key, value, color = types_1.RBTNColor.BLACK) {
96
+ return new RBTreeNode(key, value, color);
97
+ }
98
+ delete(identifier, callback = this.defaultOneParamCallback) {
99
+ const ans = [];
100
+ if (identifier === null)
101
+ return ans;
99
102
  const helper = (node) => {
100
- let z = exports.NIL;
103
+ let z = this.NIL;
101
104
  let x, y;
102
- while (node !== exports.NIL) {
103
- if (node.key === key) {
105
+ while (node !== this.NIL) {
106
+ if (node && callback(node) === identifier) {
104
107
  z = node;
105
108
  }
106
- if (node.key <= key) {
109
+ if (node && identifier && callback(node) <= identifier) {
107
110
  node = node.right;
108
111
  }
109
112
  else {
110
- node = node.left;
113
+ node = node?.left;
111
114
  }
112
115
  }
113
- if (z === exports.NIL) {
116
+ if (z === this.NIL) {
114
117
  this._size--;
115
118
  return;
116
119
  }
117
120
  y = z;
118
121
  let yOriginalColor = y.color;
119
- if (z.left === exports.NIL) {
122
+ if (z.left === this.NIL) {
120
123
  x = z.right;
121
124
  this._rbTransplant(z, z.right);
122
125
  }
123
- else if (z.right === exports.NIL) {
126
+ else if (z.right === this.NIL) {
124
127
  x = z.left;
125
128
  this._rbTransplant(z, z.left);
126
129
  }
@@ -147,35 +150,31 @@ class RedBlackTree {
147
150
  this._size--;
148
151
  };
149
152
  helper(this.root);
153
+ // TODO
154
+ return ans;
150
155
  }
151
- isRealNode(node) {
152
- return node !== exports.NIL && node !== null;
156
+ isNode(node) {
157
+ return node !== this.NIL && node !== undefined;
153
158
  }
154
159
  /**
155
- * The function `getNode` is a recursive depth-first search algorithm that searches for a node with a
156
- * given key in a red-black tree.
157
- * @param {number} key - The key parameter is a number that represents the value we are searching for
158
- * in the RBTree.
159
- * @param beginRoot - The `beginRoot` parameter is an optional parameter that represents the starting
160
- * point for the search in the binary search tree. If no value is provided for `beginRoot`, it
161
- * defaults to the root of the binary search tree (`this.root`).
162
- * @returns a RBTreeNode.
160
+ * The function `get` returns the first node in a binary tree that matches the given property or key.
161
+ * @param {BTNKey | N} identifier - The `identifier` parameter is the key or value of
162
+ * the node that you want to find in the binary tree. It can be either a `BTNKey` or `N`
163
+ * type.
164
+ * @param callback - The `callback` parameter is a function that is used to determine whether a node
165
+ * matches the desired criteria. It takes a node as input and returns a boolean value indicating
166
+ * whether the node matches the criteria or not. The default callback function
167
+ * (`this.defaultOneParamCallback`) is used if no callback function is
168
+ * @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
169
+ * the root node from which the search should begin.
170
+ * @param iterationType - The `iterationType` parameter specifies the type of iteration to be
171
+ * performed when searching for a node in the binary tree. It can have one of the following values:
172
+ * @returns either the found node (of type N) or null if no node is found.
163
173
  */
164
- getNode(key, beginRoot = this.root) {
165
- const dfs = (node) => {
166
- if (this.isRealNode(node)) {
167
- if (key === node.key) {
168
- return node;
169
- }
170
- if (key < node.key)
171
- return dfs(node.left);
172
- return dfs(node.right);
173
- }
174
- else {
175
- return null;
176
- }
177
- };
178
- return dfs(beginRoot);
174
+ getNode(identifier, callback = this.defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
175
+ if (identifier instanceof binary_tree_1.BinaryTreeNode)
176
+ callback = (node => node);
177
+ return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined;
179
178
  }
180
179
  /**
181
180
  * The function returns the leftmost node in a red-black tree.
@@ -184,7 +183,7 @@ class RedBlackTree {
184
183
  * @returns The leftmost node in the given RBTreeNode.
185
184
  */
186
185
  getLeftMost(node = this.root) {
187
- while (node.left !== null && node.left !== exports.NIL) {
186
+ while (node.left !== undefined && node.left !== this.NIL) {
188
187
  node = node.left;
189
188
  }
190
189
  return node;
@@ -195,7 +194,7 @@ class RedBlackTree {
195
194
  * @returns the rightmost node in a red-black tree.
196
195
  */
197
196
  getRightMost(node) {
198
- while (node.right !== null && node.right !== exports.NIL) {
197
+ while (node.right !== undefined && node.right !== this.NIL) {
199
198
  node = node.right;
200
199
  }
201
200
  return node;
@@ -206,11 +205,11 @@ class RedBlackTree {
206
205
  * @returns the successor of the given RBTreeNode.
207
206
  */
208
207
  getSuccessor(x) {
209
- if (x.right !== exports.NIL) {
208
+ if (x.right !== this.NIL) {
210
209
  return this.getLeftMost(x.right);
211
210
  }
212
211
  let y = x.parent;
213
- while (y !== exports.NIL && y !== null && x === y.right) {
212
+ while (y !== this.NIL && y !== undefined && x === y.right) {
214
213
  x = y;
215
214
  y = y.parent;
216
215
  }
@@ -223,95 +222,51 @@ class RedBlackTree {
223
222
  * @returns the predecessor of the given RBTreeNode 'x'.
224
223
  */
225
224
  getPredecessor(x) {
226
- if (x.left !== exports.NIL) {
225
+ if (x.left !== this.NIL) {
227
226
  return this.getRightMost(x.left);
228
227
  }
229
228
  let y = x.parent;
230
- while (y !== exports.NIL && x === y.left) {
229
+ while (y !== this.NIL && x === y.left) {
231
230
  x = y;
232
231
  y = y.parent;
233
232
  }
234
233
  return y;
235
234
  }
236
235
  clear() {
237
- this._root = exports.NIL;
236
+ this._root = this.NIL;
238
237
  this._size = 0;
239
238
  }
240
- print(beginRoot = this.root) {
241
- const display = (root) => {
242
- const [lines, , ,] = _displayAux(root);
243
- for (const line of lines) {
244
- console.log(line);
245
- }
246
- };
247
- const _displayAux = (node) => {
248
- if (node === null) {
249
- return [[], 0, 0, 0];
250
- }
251
- if (node.right === null && node.left === null) {
252
- const line = `${node.key}`;
253
- const width = line.length;
254
- const height = 1;
255
- const middle = Math.floor(width / 2);
256
- return [[line], width, height, middle];
257
- }
258
- if (node.right === null) {
259
- const [lines, n, p, x] = _displayAux(node.left);
260
- const s = `${node.key}`;
261
- const u = s.length;
262
- const first_line = ' '.repeat(x + 1) + '_'.repeat(n - x - 1) + s;
263
- const second_line = ' '.repeat(x) + '/' + ' '.repeat(n - x - 1 + u);
264
- const shifted_lines = lines.map(line => line + ' '.repeat(u));
265
- return [[first_line, second_line, ...shifted_lines], n + u, p + 2, n + Math.floor(u / 2)];
266
- }
267
- if (node.left === null) {
268
- const [lines, n, p, u] = _displayAux(node.right);
269
- const s = `${node.key}`;
270
- const x = s.length;
271
- const first_line = s + '_'.repeat(x) + ' '.repeat(n - x);
272
- const second_line = ' '.repeat(u + x) + '\\' + ' '.repeat(n - x - 1);
273
- const shifted_lines = lines.map(line => ' '.repeat(u) + line);
274
- return [[first_line, second_line, ...shifted_lines], n + x, p + 2, Math.floor(u / 2)];
275
- }
276
- const [left, n, p, x] = _displayAux(node.left);
277
- const [right, m, q, y] = _displayAux(node.right);
278
- const s = `${node.key}`;
279
- const u = s.length;
280
- const first_line = ' '.repeat(x + 1) + '_'.repeat(n - x - 1) + s + '_'.repeat(y) + ' '.repeat(m - y);
281
- const second_line = ' '.repeat(x) + '/' + ' '.repeat(n - x - 1 + u + y) + '\\' + ' '.repeat(m - y - 1);
282
- if (p < q) {
283
- left.push(...new Array(q - p).fill(' '.repeat(n)));
284
- }
285
- else if (q < p) {
286
- right.push(...new Array(p - q).fill(' '.repeat(m)));
287
- }
288
- const zipped_lines = left.map((a, i) => a + ' '.repeat(u) + right[i]);
289
- return [[first_line, second_line, ...zipped_lines], n + m + u, Math.max(p, q) + 2, n + Math.floor(u / 2)];
290
- };
291
- display(beginRoot);
239
+ _setRoot(v) {
240
+ if (v) {
241
+ v.parent = undefined;
242
+ }
243
+ this._root = v;
292
244
  }
293
245
  /**
294
246
  * The function performs a left rotation on a red-black tree node.
295
247
  * @param {RBTreeNode} x - The parameter `x` is a RBTreeNode object.
296
248
  */
297
249
  _leftRotate(x) {
298
- const y = x.right;
299
- x.right = y.left;
300
- if (y.left !== exports.NIL) {
301
- y.left.parent = x;
302
- }
303
- y.parent = x.parent;
304
- if (x.parent === null) {
305
- this._root = y;
306
- }
307
- else if (x === x.parent.left) {
308
- x.parent.left = y;
309
- }
310
- else {
311
- x.parent.right = y;
250
+ if (x.right) {
251
+ const y = x.right;
252
+ x.right = y.left;
253
+ if (y.left !== this.NIL) {
254
+ if (y.left)
255
+ y.left.parent = x;
256
+ }
257
+ y.parent = x.parent;
258
+ if (x.parent === undefined) {
259
+ this._setRoot(y);
260
+ }
261
+ else if (x === x.parent.left) {
262
+ x.parent.left = y;
263
+ }
264
+ else {
265
+ x.parent.right = y;
266
+ }
267
+ y.left = x;
268
+ x.parent = y;
312
269
  }
313
- y.left = x;
314
- x.parent = y;
315
270
  }
316
271
  /**
317
272
  * The function performs a right rotation on a red-black tree node.
@@ -319,23 +274,26 @@ class RedBlackTree {
319
274
  * rotated.
320
275
  */
321
276
  _rightRotate(x) {
322
- const y = x.left;
323
- x.left = y.right;
324
- if (y.right !== exports.NIL) {
325
- y.right.parent = x;
326
- }
327
- y.parent = x.parent;
328
- if (x.parent === null) {
329
- this._root = y;
330
- }
331
- else if (x === x.parent.right) {
332
- x.parent.right = y;
333
- }
334
- else {
335
- x.parent.left = y;
277
+ if (x.left) {
278
+ const y = x.left;
279
+ x.left = y.right;
280
+ if (y.right !== this.NIL) {
281
+ if (y.right)
282
+ y.right.parent = x;
283
+ }
284
+ y.parent = x.parent;
285
+ if (x.parent === undefined) {
286
+ this._setRoot(y);
287
+ }
288
+ else if (x === x.parent.right) {
289
+ x.parent.right = y;
290
+ }
291
+ else {
292
+ x.parent.left = y;
293
+ }
294
+ y.right = x;
295
+ x.parent = y;
336
296
  }
337
- y.right = x;
338
- x.parent = y;
339
297
  }
340
298
  /**
341
299
  * The _fixDelete function is used to rebalance the Red-Black Tree after a node deletion.
@@ -345,7 +303,7 @@ class RedBlackTree {
345
303
  _fixDelete(x) {
346
304
  let s;
347
305
  while (x !== this.root && x.color === types_1.RBTNColor.BLACK) {
348
- if (x === x.parent.left) {
306
+ if (x.parent && x === x.parent.left) {
349
307
  s = x.parent.right;
350
308
  if (s.color === 1) {
351
309
  s.color = types_1.RBTNColor.BLACK;
@@ -353,20 +311,23 @@ class RedBlackTree {
353
311
  this._leftRotate(x.parent);
354
312
  s = x.parent.right;
355
313
  }
356
- if (s.left !== null && s.left.color === types_1.RBTNColor.BLACK && s.right.color === types_1.RBTNColor.BLACK) {
314
+ if (s.left !== undefined && s.left.color === types_1.RBTNColor.BLACK && s.right && s.right.color === types_1.RBTNColor.BLACK) {
357
315
  s.color = types_1.RBTNColor.RED;
358
316
  x = x.parent;
359
317
  }
360
318
  else {
361
- if (s.right.color === types_1.RBTNColor.BLACK) {
362
- s.left.color = types_1.RBTNColor.BLACK;
319
+ if (s.right && s.right.color === types_1.RBTNColor.BLACK) {
320
+ if (s.left)
321
+ s.left.color = types_1.RBTNColor.BLACK;
363
322
  s.color = types_1.RBTNColor.RED;
364
323
  this._rightRotate(s);
365
324
  s = x.parent.right;
366
325
  }
367
- s.color = x.parent.color;
326
+ if (s)
327
+ s.color = x.parent.color;
368
328
  x.parent.color = types_1.RBTNColor.BLACK;
369
- s.right.color = types_1.RBTNColor.BLACK;
329
+ if (s && s.right)
330
+ s.right.color = types_1.RBTNColor.BLACK;
370
331
  this._leftRotate(x.parent);
371
332
  x = this.root;
372
333
  }
@@ -379,20 +340,23 @@ class RedBlackTree {
379
340
  this._rightRotate(x.parent);
380
341
  s = x.parent.left;
381
342
  }
382
- if (s.right.color === types_1.RBTNColor.BLACK && s.right.color === types_1.RBTNColor.BLACK) {
343
+ if (s && s.right && s.right.color === types_1.RBTNColor.BLACK && s.right.color === types_1.RBTNColor.BLACK) {
383
344
  s.color = types_1.RBTNColor.RED;
384
345
  x = x.parent;
385
346
  }
386
347
  else {
387
- if (s.left.color === types_1.RBTNColor.BLACK) {
388
- s.right.color = types_1.RBTNColor.BLACK;
348
+ if (s && s.left && s.left.color === types_1.RBTNColor.BLACK) {
349
+ if (s.right)
350
+ s.right.color = types_1.RBTNColor.BLACK;
389
351
  s.color = types_1.RBTNColor.RED;
390
352
  this._leftRotate(s);
391
353
  s = x.parent.left;
392
354
  }
393
- s.color = x.parent.color;
355
+ if (s)
356
+ s.color = x.parent.color;
394
357
  x.parent.color = types_1.RBTNColor.BLACK;
395
- s.left.color = types_1.RBTNColor.BLACK;
358
+ if (s && s.left)
359
+ s.left.color = types_1.RBTNColor.BLACK;
396
360
  this._rightRotate(x.parent);
397
361
  x = this.root;
398
362
  }
@@ -406,8 +370,8 @@ class RedBlackTree {
406
370
  * @param {RBTreeNode} v - The parameter "v" is a RBTreeNode object.
407
371
  */
408
372
  _rbTransplant(u, v) {
409
- if (u.parent === null) {
410
- this._root = v;
373
+ if (u.parent === undefined) {
374
+ this._setRoot(v);
411
375
  }
412
376
  else if (u === u.parent.left) {
413
377
  u.parent.left = v;
@@ -424,10 +388,10 @@ class RedBlackTree {
424
388
  */
425
389
  _fixInsert(k) {
426
390
  let u;
427
- while (k.parent.color === 1) {
428
- if (k.parent === k.parent.parent.right) {
391
+ while (k.parent && k.parent.color === 1) {
392
+ if (k.parent.parent && k.parent === k.parent.parent.right) {
429
393
  u = k.parent.parent.left;
430
- if (u.color === 1) {
394
+ if (u && u.color === 1) {
431
395
  u.color = types_1.RBTNColor.BLACK;
432
396
  k.parent.color = types_1.RBTNColor.BLACK;
433
397
  k.parent.parent.color = types_1.RBTNColor.RED;
@@ -445,7 +409,7 @@ class RedBlackTree {
445
409
  }
446
410
  else {
447
411
  u = k.parent.parent.right;
448
- if (u.color === 1) {
412
+ if (u && u.color === 1) {
449
413
  u.color = types_1.RBTNColor.BLACK;
450
414
  k.parent.color = types_1.RBTNColor.BLACK;
451
415
  k.parent.parent.color = types_1.RBTNColor.RED;
@@ -49,37 +49,37 @@ export declare class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = Tr
49
49
  /**
50
50
  * The `add` function adds a new node to a binary search tree, updating the count if the key already
51
51
  * exists, and balancing the tree if necessary.
52
- * @param {BTNKey | N | null} keyOrNode - The `keyOrNode` parameter can be either a
52
+ * @param {BTNKey | N | undefined} keyOrNode - The `keyOrNode` parameter can be either a
53
53
  * `BTNKey` (which represents the key of the node to be added), a `N` (which represents a
54
- * node to be added), or `null` (which represents a null node).
54
+ * node to be added), or `undefined` (which represents a undefined node).
55
55
  * @param [value] - The `value` parameter represents the value associated with the key that is being
56
56
  * added to the binary tree.
57
57
  * @param [count=1] - The `count` parameter represents the number of occurrences of the key/value
58
58
  * pair that will be added to the binary tree. It has a default value of 1, which means that if no
59
59
  * count is specified, the default count will be 1.
60
- * @returns The function `add` returns a value of type `N | null | undefined`.
60
+ * @returns The function `add` returns a value of type `N | undefined | undefined`.
61
61
  */
62
- add(keyOrNode: BTNKey | N | null, value?: V, count?: number): N | null | undefined;
62
+ add(keyOrNode: BTNKey | N | null | undefined, value?: V, count?: number): N | undefined;
63
63
  /**
64
64
  * The function adds a new node to a binary tree if there is an available slot in the parent node.
65
- * @param {N | null} newNode - The `newNode` parameter represents the node that needs to be added to
66
- * the tree. It can be either a node object (`N`) or `null`.
65
+ * @param {N | undefined} newNode - The `newNode` parameter represents the node that needs to be added to
66
+ * the tree. It can be either a node object (`N`) or `undefined`.
67
67
  * @param {N} parent - The `parent` parameter represents the parent node to which the new node will
68
68
  * be added as a child.
69
69
  * @returns The method `_addTo` returns either the `parent.left`, `parent.right`, or `undefined`.
70
70
  */
71
- _addTo(newNode: N | null, parent: N): N | null | undefined;
71
+ _addTo(newNode: N | undefined, parent: N): N | undefined;
72
72
  /**
73
73
  * The `addMany` function adds multiple keys or nodes to a TreeMultiset and returns an array of the
74
74
  * inserted nodes.
75
- * @param {(BTNKey | null)[] | (N | null)[]} keysOrNodes - An array of keys or nodes to be
75
+ * @param {(BTNKey | undefined)[] | (N | undefined)[]} keysOrNodes - An array of keys or nodes to be
76
76
  * added to the multiset. Each element can be either a BTNKey or a TreeMultisetNode.
77
77
  * @param {V[]} [data] - The `data` parameter is an optional array of values that correspond
78
78
  * to the keys or nodes being added to the multiset. It is used to associate additional data with
79
79
  * each key or node.
80
- * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
80
+ * @returns The function `addMany` returns an array of `N`, `undefined`, or `undefined` values.
81
81
  */
82
- addMany(keysOrNodes: (BTNKey | null)[] | (N | null)[], data?: V[]): (N | null | undefined)[];
82
+ addMany(keysOrNodes: (BTNKey | undefined)[] | (N | undefined)[], data?: V[]): (N | undefined)[];
83
83
  /**
84
84
  * The `perfectlyBalance` function in TypeScript takes a sorted array of nodes and builds a balanced
85
85
  * binary search tree using either a recursive or iterative approach.