min-heap-typed 1.50.5 → 1.50.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.
@@ -51,6 +51,7 @@ export declare class TreeMultiMap<K = any, V = any, NODE extends TreeMultiMapNod
51
51
  * @returns the sum of the count property of all nodes in the tree.
52
52
  */
53
53
  get count(): number;
54
+ getMutableCount(): number;
54
55
  /**
55
56
  * The function creates a new TreeMultiMapNode object with the specified key, value, and count.
56
57
  * @param {K} key - The key parameter represents the key of the node being created. It is of type K,
@@ -58,10 +58,12 @@ class TreeMultiMap extends rb_tree_1.RedBlackTree {
58
58
  * @returns the sum of the count property of all nodes in the tree.
59
59
  */
60
60
  get count() {
61
+ return this._count;
62
+ }
63
+ getMutableCount() {
61
64
  let sum = 0;
62
65
  this.dfs(node => (sum += node.count));
63
66
  return sum;
64
- // return this._count;
65
67
  }
66
68
  /**
67
69
  * The function creates a new TreeMultiMapNode object with the specified key, value, and count.
@@ -154,14 +156,15 @@ class TreeMultiMap extends rb_tree_1.RedBlackTree {
154
156
  */
155
157
  add(keyOrNodeOrEntry, value, count = 1) {
156
158
  const newNode = this.keyValueOrEntryToNode(keyOrNodeOrEntry, value, count);
157
- if (newNode === undefined)
159
+ const orgCount = (newNode === null || newNode === void 0 ? void 0 : newNode.count) || 0;
160
+ const isSuccessAdded = super.add(newNode);
161
+ if (isSuccessAdded) {
162
+ this._count += orgCount;
163
+ return true;
164
+ }
165
+ else {
158
166
  return false;
159
- const orgNodeCount = (newNode === null || newNode === void 0 ? void 0 : newNode.count) || 0;
160
- const inserted = super.add(newNode);
161
- if (inserted) {
162
- this._count += orgNodeCount;
163
167
  }
164
- return true;
165
168
  }
166
169
  /**
167
170
  * Time Complexity: O(log n)
@@ -188,86 +191,91 @@ class TreeMultiMap extends rb_tree_1.RedBlackTree {
188
191
  * @returns an array of BinaryTreeDeleteResult<NODE> objects.
189
192
  */
190
193
  delete(identifier, callback = this._defaultOneParamCallback, ignoreCount = false) {
191
- const deleteResults = [];
192
194
  if (identifier === null)
193
- return deleteResults;
194
- // Helper function to perform deletion
195
- const deleteHelper = (node) => {
196
- // Initialize targetNode to the sentinel node
197
- let targetNode = this._Sentinel;
198
- let currentNode;
199
- // Find the node to be deleted based on the identifier
200
- while (node !== this._Sentinel) {
201
- // Update targetNode if the current node matches the identifier
202
- if (node && callback(node) === identifier) {
203
- targetNode = node;
204
- }
205
- // Move to the right or left based on the comparison with the identifier
206
- if (node && identifier && callback(node) <= identifier) {
207
- node = node.right;
208
- }
209
- else {
210
- node = node === null || node === void 0 ? void 0 : node.left;
211
- }
195
+ return [];
196
+ const results = [];
197
+ const nodeToDelete = this.isRealNode(identifier) ? identifier : this.getNode(identifier, callback);
198
+ if (!nodeToDelete) {
199
+ return results;
200
+ }
201
+ let originalColor = nodeToDelete.color;
202
+ let replacementNode;
203
+ if (!this.isRealNode(nodeToDelete.left)) {
204
+ replacementNode = nodeToDelete.right;
205
+ if (ignoreCount || nodeToDelete.count <= 1) {
206
+ this._transplant(nodeToDelete, nodeToDelete.right);
207
+ this._count -= nodeToDelete.count;
212
208
  }
213
- // If the target node is not found, decrement size and return
214
- if (targetNode === this._Sentinel) {
215
- return;
209
+ else {
210
+ nodeToDelete.count--;
211
+ this._count--;
212
+ results.push({ deleted: nodeToDelete, needBalanced: undefined });
213
+ return results;
216
214
  }
217
- if (ignoreCount || targetNode.count <= 1) {
218
- // Store the parent of the target node and its original color
219
- let parentNode = targetNode;
220
- let parentNodeOriginalColor = parentNode.color;
221
- // Handle deletion based on the number of children of the target node
222
- if (targetNode.left === this._Sentinel) {
223
- // Target node has no left child - deletion case 1
224
- currentNode = targetNode.right;
225
- this._rbTransplant(targetNode, targetNode.right);
226
- }
227
- else if (targetNode.right === this._Sentinel) {
228
- // Target node has no right child - deletion case 2
229
- currentNode = targetNode.left;
230
- this._rbTransplant(targetNode, targetNode.left);
215
+ }
216
+ else if (!this.isRealNode(nodeToDelete.right)) {
217
+ replacementNode = nodeToDelete.left;
218
+ if (ignoreCount || nodeToDelete.count <= 1) {
219
+ this._transplant(nodeToDelete, nodeToDelete.left);
220
+ this._count -= nodeToDelete.count;
221
+ }
222
+ else {
223
+ nodeToDelete.count--;
224
+ this._count--;
225
+ results.push({ deleted: nodeToDelete, needBalanced: undefined });
226
+ return results;
227
+ }
228
+ }
229
+ else {
230
+ const successor = this.getLeftMost(nodeToDelete.right);
231
+ if (successor) {
232
+ originalColor = successor.color;
233
+ replacementNode = successor.right;
234
+ if (successor.parent === nodeToDelete) {
235
+ if (this.isRealNode(replacementNode)) {
236
+ replacementNode.parent = successor;
237
+ }
231
238
  }
232
239
  else {
233
- // Target node has both left and right children - deletion case 3
234
- parentNode = this.getLeftMost(targetNode.right);
235
- parentNodeOriginalColor = parentNode.color;
236
- currentNode = parentNode.right;
237
- if (parentNode.parent === targetNode) {
238
- // Target node's right child becomes its parent's left child
239
- currentNode.parent = parentNode;
240
+ if (ignoreCount || nodeToDelete.count <= 1) {
241
+ this._transplant(successor, successor.right);
242
+ this._count -= nodeToDelete.count;
240
243
  }
241
244
  else {
242
- // Replace parentNode with its right child and update connections
243
- this._rbTransplant(parentNode, parentNode.right);
244
- parentNode.right = targetNode.right;
245
- parentNode.right.parent = parentNode;
245
+ nodeToDelete.count--;
246
+ this._count--;
247
+ results.push({ deleted: nodeToDelete, needBalanced: undefined });
248
+ return results;
249
+ }
250
+ successor.right = nodeToDelete.right;
251
+ if (this.isRealNode(successor.right)) {
252
+ successor.right.parent = successor;
246
253
  }
247
- // Replace the target node with its in-order successor
248
- this._rbTransplant(targetNode, parentNode);
249
- parentNode.left = targetNode.left;
250
- parentNode.left.parent = parentNode;
251
- parentNode.color = targetNode.color;
252
254
  }
253
- // Fix the Red-Black Tree properties after deletion
254
- if (parentNodeOriginalColor === types_1.RBTNColor.BLACK) {
255
- this._fixDelete(currentNode);
255
+ if (ignoreCount || nodeToDelete.count <= 1) {
256
+ this._transplant(nodeToDelete, successor);
257
+ this._count -= nodeToDelete.count;
256
258
  }
257
- // Decrement the size and store information about the deleted node
258
- this._size--;
259
- this._count -= targetNode.count;
260
- deleteResults.push({ deleted: targetNode, needBalanced: undefined });
261
- }
262
- else {
263
- targetNode.count--;
264
- this._count--;
259
+ else {
260
+ nodeToDelete.count--;
261
+ this._count--;
262
+ results.push({ deleted: nodeToDelete, needBalanced: undefined });
263
+ return results;
264
+ }
265
+ successor.left = nodeToDelete.left;
266
+ if (this.isRealNode(successor.left)) {
267
+ successor.left.parent = successor;
268
+ }
269
+ successor.color = nodeToDelete.color;
265
270
  }
266
- };
267
- // Call the helper function with the root of the tree
268
- deleteHelper(this.root);
269
- // Return the result array
270
- return deleteResults;
271
+ }
272
+ this._size--;
273
+ // If the original color was black, fix the tree
274
+ if (originalColor === types_1.RBTNColor.BLACK) {
275
+ this._deleteFixup(replacementNode);
276
+ }
277
+ results.push({ deleted: nodeToDelete, needBalanced: undefined });
278
+ return results;
271
279
  }
272
280
  /**
273
281
  * Time Complexity: O(1)
@@ -52,3 +52,9 @@ export type BinaryTreeDeleteResult<N> = {
52
52
  deleted: N | null | undefined;
53
53
  needBalanced: N | null | undefined;
54
54
  };
55
+ export declare enum CRUD {
56
+ CREATED = "CREATED",
57
+ READ = "READ",
58
+ UPDATED = "UPDATED",
59
+ DELETED = "DELETED"
60
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FamilyPosition = exports.IterationType = exports.CP = exports.BSTVariant = void 0;
3
+ exports.CRUD = exports.FamilyPosition = exports.IterationType = exports.CP = exports.BSTVariant = void 0;
4
4
  var BSTVariant;
5
5
  (function (BSTVariant) {
6
6
  BSTVariant["STANDARD"] = "STANDARD";
@@ -33,3 +33,10 @@ var FamilyPosition;
33
33
  FamilyPosition["ISOLATED"] = "ISOLATED";
34
34
  FamilyPosition["MAL_NODE"] = "MAL_NODE";
35
35
  })(FamilyPosition = exports.FamilyPosition || (exports.FamilyPosition = {}));
36
+ var CRUD;
37
+ (function (CRUD) {
38
+ CRUD["CREATED"] = "CREATED";
39
+ CRUD["READ"] = "READ";
40
+ CRUD["UPDATED"] = "UPDATED";
41
+ CRUD["DELETED"] = "DELETED";
42
+ })(CRUD = exports.CRUD || (exports.CRUD = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "min-heap-typed",
3
- "version": "1.50.5",
3
+ "version": "1.50.7",
4
4
  "description": "Min Heap. Javascript & Typescript Data Structure.",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -132,6 +132,6 @@
132
132
  "typescript": "^4.9.5"
133
133
  },
134
134
  "dependencies": {
135
- "data-structure-typed": "^1.50.4"
135
+ "data-structure-typed": "^1.50.7"
136
136
  }
137
137
  }
@@ -83,6 +83,10 @@ export class AVLTreeMultiMap<
83
83
  * @returns the sum of the count property of all nodes in the tree.
84
84
  */
85
85
  get count(): number {
86
+ return this._count;
87
+ }
88
+
89
+ getMutableCount(): number {
86
90
  let sum = 0;
87
91
  this.dfs(node => (sum += node.count));
88
92
  return sum;
@@ -414,7 +418,7 @@ export class AVLTreeMultiMap<
414
418
  * @returns The method is returning the result of calling the `_replaceNode` method from the
415
419
  * superclass, after updating the `count` property of the `newNode` object.
416
420
  */
417
- protected _replaceNode(oldNode: NODE, newNode: NODE): NODE {
421
+ protected override _replaceNode(oldNode: NODE, newNode: NODE): NODE {
418
422
  newNode.count = oldNode.count + newNode.count;
419
423
  return super._replaceNode(oldNode, newNode);
420
424
  }
@@ -522,7 +522,7 @@ export class AVLTree<
522
522
  * @returns the result of calling the `_replaceNode` method on the superclass, passing in the
523
523
  * `oldNode` and `newNode` as arguments.
524
524
  */
525
- protected _replaceNode(oldNode: NODE, newNode: NODE): NODE {
525
+ protected override _replaceNode(oldNode: NODE, newNode: NODE): NODE {
526
526
  newNode.height = oldNode.height;
527
527
 
528
528
  return super._replaceNode(oldNode, newNode);
@@ -934,7 +934,7 @@ export class BinaryTree<
934
934
 
935
935
  if (iterationType === IterationType.RECURSIVE) {
936
936
  const dfs = (cur: NODE | null | undefined, min: number, max: number): boolean => {
937
- if (!cur) return true;
937
+ if (!this.isRealNode(cur)) return true;
938
938
  const numKey = this.extractor(cur.key);
939
939
  if (numKey <= min || numKey >= max) return false;
940
940
  return dfs(cur.left, min, numKey) && dfs(cur.right, numKey, max);
@@ -949,14 +949,14 @@ export class BinaryTree<
949
949
  let prev = checkMax ? Number.MAX_SAFE_INTEGER : Number.MIN_SAFE_INTEGER;
950
950
  // @ts-ignore
951
951
  let curr: NODE | null | undefined = beginRoot;
952
- while (curr || stack.length > 0) {
953
- while (curr) {
952
+ while (this.isRealNode(curr) || stack.length > 0) {
953
+ while (this.isRealNode(curr)) {
954
954
  stack.push(curr);
955
955
  curr = curr.left;
956
956
  }
957
957
  curr = stack.pop()!;
958
958
  const numKey = this.extractor(curr.key);
959
- if (!curr || (!checkMax && prev >= numKey) || (checkMax && prev <= numKey)) return false;
959
+ if (!this.isRealNode(curr) || (!checkMax && prev >= numKey) || (checkMax && prev <= numKey)) return false;
960
960
  prev = numKey;
961
961
  curr = curr.right;
962
962
  }
@@ -1021,11 +1021,11 @@ export class BinaryTree<
1021
1021
  */
1022
1022
  getHeight(beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root, iterationType = this.iterationType): number {
1023
1023
  beginRoot = this.ensureNode(beginRoot);
1024
- if (!beginRoot) return -1;
1024
+ if (!this.isRealNode(beginRoot)) return -1;
1025
1025
 
1026
1026
  if (iterationType === IterationType.RECURSIVE) {
1027
1027
  const _getMaxHeight = (cur: NODE | null | undefined): number => {
1028
- if (!cur) return -1;
1028
+ if (!this.isRealNode(cur)) return -1;
1029
1029
  const leftHeight = _getMaxHeight(cur.left);
1030
1030
  const rightHeight = _getMaxHeight(cur.right);
1031
1031
  return Math.max(leftHeight, rightHeight) + 1;
@@ -1039,8 +1039,8 @@ export class BinaryTree<
1039
1039
  while (stack.length > 0) {
1040
1040
  const { node, depth } = stack.pop()!;
1041
1041
 
1042
- if (node.left) stack.push({ node: node.left, depth: depth + 1 });
1043
- if (node.right) stack.push({ node: node.right, depth: depth + 1 });
1042
+ if (this.isRealNode(node.left)) stack.push({ node: node.left, depth: depth + 1 });
1043
+ if (this.isRealNode(node.right)) stack.push({ node: node.right, depth: depth + 1 });
1044
1044
 
1045
1045
  maxHeight = Math.max(maxHeight, depth);
1046
1046
  }
@@ -1073,8 +1073,8 @@ export class BinaryTree<
1073
1073
 
1074
1074
  if (iterationType === IterationType.RECURSIVE) {
1075
1075
  const _getMinHeight = (cur: NODE | null | undefined): number => {
1076
- if (!cur) return 0;
1077
- if (!cur.left && !cur.right) return 0;
1076
+ if (!this.isRealNode(cur)) return 0;
1077
+ if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return 0;
1078
1078
  const leftMinHeight = _getMinHeight(cur.left);
1079
1079
  const rightMinHeight = _getMinHeight(cur.right);
1080
1080
  return Math.min(leftMinHeight, rightMinHeight) + 1;
@@ -1088,16 +1088,16 @@ export class BinaryTree<
1088
1088
  const depths: Map<NODE, number> = new Map();
1089
1089
 
1090
1090
  while (stack.length > 0 || node) {
1091
- if (node) {
1091
+ if (this.isRealNode(node)) {
1092
1092
  stack.push(node);
1093
1093
  node = node.left;
1094
1094
  } else {
1095
1095
  node = stack[stack.length - 1];
1096
- if (!node.right || last === node.right) {
1096
+ if (!this.isRealNode(node.right) || last === node.right) {
1097
1097
  node = stack.pop();
1098
- if (node) {
1099
- const leftMinHeight = node.left ? depths.get(node.left) ?? -1 : -1;
1100
- const rightMinHeight = node.right ? depths.get(node.right) ?? -1 : -1;
1098
+ if (this.isRealNode(node)) {
1099
+ const leftMinHeight = this.isRealNode(node.left) ? depths.get(node.left) ?? -1 : -1;
1100
+ const rightMinHeight = this.isRealNode(node.right) ? depths.get(node.right) ?? -1 : -1;
1101
1101
  depths.set(node, 1 + Math.min(leftMinHeight, rightMinHeight));
1102
1102
  last = node;
1103
1103
  node = null;
@@ -1169,9 +1169,10 @@ export class BinaryTree<
1169
1169
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
1170
1170
  iterationType = this.iterationType
1171
1171
  ): NODE | null | undefined {
1172
+ if (this.isNIL(beginRoot)) return beginRoot as NODE;
1172
1173
  beginRoot = this.ensureNode(beginRoot);
1173
1174
 
1174
- if (!beginRoot) return beginRoot;
1175
+ if (!this.isRealNode(beginRoot)) return beginRoot;
1175
1176
 
1176
1177
  if (iterationType === IterationType.RECURSIVE) {
1177
1178
  const _traverse = (cur: NODE): NODE => {
@@ -1215,6 +1216,7 @@ export class BinaryTree<
1215
1216
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
1216
1217
  iterationType = this.iterationType
1217
1218
  ): NODE | null | undefined {
1219
+ if (this.isNIL(beginRoot)) return beginRoot as NODE;
1218
1220
  // TODO support get right most by passing key in
1219
1221
  beginRoot = this.ensureNode(beginRoot);
1220
1222
  if (!beginRoot) return beginRoot;
@@ -1354,34 +1356,34 @@ export class BinaryTree<
1354
1356
  switch (pattern) {
1355
1357
  case 'in':
1356
1358
  if (includeNull) {
1357
- if (node && this.isNodeOrNull(node.left)) _traverse(node.left);
1359
+ if (this.isRealNode(node) && this.isNodeOrNull(node.left)) _traverse(node.left);
1358
1360
  this.isNodeOrNull(node) && ans.push(callback(node));
1359
- if (node && this.isNodeOrNull(node.right)) _traverse(node.right);
1361
+ if (this.isRealNode(node) && this.isNodeOrNull(node.right)) _traverse(node.right);
1360
1362
  } else {
1361
- if (node && node.left) _traverse(node.left);
1363
+ if (this.isRealNode(node) && this.isRealNode(node.left)) _traverse(node.left);
1362
1364
  this.isRealNode(node) && ans.push(callback(node));
1363
- if (node && node.right) _traverse(node.right);
1365
+ if (this.isRealNode(node) && this.isRealNode(node.right)) _traverse(node.right);
1364
1366
  }
1365
1367
  break;
1366
1368
  case 'pre':
1367
1369
  if (includeNull) {
1368
1370
  this.isNodeOrNull(node) && ans.push(callback(node));
1369
- if (node && this.isNodeOrNull(node.left)) _traverse(node.left);
1370
- if (node && this.isNodeOrNull(node.right)) _traverse(node.right);
1371
+ if (this.isRealNode(node) && this.isNodeOrNull(node.left)) _traverse(node.left);
1372
+ if (this.isRealNode(node) && this.isNodeOrNull(node.right)) _traverse(node.right);
1371
1373
  } else {
1372
1374
  this.isRealNode(node) && ans.push(callback(node));
1373
- if (node && node.left) _traverse(node.left);
1374
- if (node && node.right) _traverse(node.right);
1375
+ if (this.isRealNode(node) && this.isRealNode(node.left)) _traverse(node.left);
1376
+ if (this.isRealNode(node) && this.isRealNode(node.right)) _traverse(node.right);
1375
1377
  }
1376
1378
  break;
1377
1379
  case 'post':
1378
1380
  if (includeNull) {
1379
- if (node && this.isNodeOrNull(node.left)) _traverse(node.left);
1380
- if (node && this.isNodeOrNull(node.right)) _traverse(node.right);
1381
+ if (this.isRealNode(node) && this.isNodeOrNull(node.left)) _traverse(node.left);
1382
+ if (this.isRealNode(node) && this.isNodeOrNull(node.right)) _traverse(node.right);
1381
1383
  this.isNodeOrNull(node) && ans.push(callback(node));
1382
1384
  } else {
1383
- if (node && node.left) _traverse(node.left);
1384
- if (node && node.right) _traverse(node.right);
1385
+ if (this.isRealNode(node) && this.isRealNode(node.left)) _traverse(node.left);
1386
+ if (this.isRealNode(node) && this.isRealNode(node.right)) _traverse(node.right);
1385
1387
  this.isRealNode(node) && ans.push(callback(node));
1386
1388
  }
1387
1389
 
@@ -1837,7 +1839,7 @@ export class BinaryTree<
1837
1839
  * following types:
1838
1840
  * @param {BinaryTreePrintOptions} [options={ isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false}] - Options object that controls printing behavior. You can specify whether to display undefined, null, or sentinel nodes.
1839
1841
  */
1840
- print(beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root, options?: BinaryTreePrintOptions): void {
1842
+ override print(beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root, options?: BinaryTreePrintOptions): void {
1841
1843
  const opts = { isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false, ...options };
1842
1844
  beginRoot = this.ensureNode(beginRoot);
1843
1845
  if (!beginRoot) return;
@@ -426,14 +426,14 @@ export class BST<
426
426
  * found in the binary tree. If no node is found, it returns `undefined`.
427
427
  */
428
428
  override getNodeByKey(key: K, iterationType = IterationType.ITERATIVE): NODE | undefined {
429
- if (!this.root) return undefined;
429
+ if (!this.isRealNode(this.root)) return undefined;
430
430
  if (iterationType === IterationType.RECURSIVE) {
431
431
  const _dfs = (cur: NODE): NODE | undefined => {
432
432
  if (cur.key === key) return cur;
433
- if (!cur.left && !cur.right) return;
433
+ if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
434
434
 
435
- if (this._compare(cur.key, key) === CP.gt && cur.left) return _dfs(cur.left);
436
- if (this._compare(cur.key, key) === CP.lt && cur.right) return _dfs(cur.right);
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);
437
437
  };
438
438
 
439
439
  return _dfs(this.root);
@@ -441,10 +441,10 @@ export class BST<
441
441
  const queue = new Queue<NODE>([this.root]);
442
442
  while (queue.size > 0) {
443
443
  const cur = queue.shift();
444
- if (cur) {
444
+ if (this.isRealNode(cur)) {
445
445
  if (this._compare(cur.key, key) === CP.eq) return cur;
446
- if (this._compare(cur.key, key) === CP.gt) cur.left && queue.push(cur.left);
447
- if (this._compare(cur.key, key) === CP.lt) cur.right && queue.push(cur.right);
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);
448
448
  }
449
449
  }
450
450
  }
@@ -497,14 +497,14 @@ export class BST<
497
497
  if (onlyOne) return;
498
498
  }
499
499
 
500
- if (!cur.left && !cur.right) return;
500
+ if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
501
501
  // TODO potential bug
502
502
  if (callback === this._defaultOneParamCallback) {
503
- if (this._compare(cur.key, identifier as K) === CP.gt) cur.left && _traverse(cur.left);
504
- if (this._compare(cur.key, identifier as K) === CP.lt) cur.right && _traverse(cur.right);
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);
505
505
  } else {
506
- cur.left && _traverse(cur.left);
507
- cur.right && _traverse(cur.right);
506
+ this.isRealNode(cur.left) && _traverse(cur.left);
507
+ this.isRealNode(cur.right) && _traverse(cur.right);
508
508
  }
509
509
  };
510
510
 
@@ -513,7 +513,7 @@ export class BST<
513
513
  const queue = new Queue<NODE>([beginRoot]);
514
514
  while (queue.size > 0) {
515
515
  const cur = queue.shift();
516
- if (cur) {
516
+ if (this.isRealNode(cur)) {
517
517
  const callbackResult = callback(cur);
518
518
  if (callbackResult === identifier) {
519
519
  ans.push(cur);
@@ -521,11 +521,11 @@ export class BST<
521
521
  }
522
522
  // TODO potential bug
523
523
  if (callback === this._defaultOneParamCallback) {
524
- if (this._compare(cur.key, identifier as K) === CP.gt) cur.left && queue.push(cur.left);
525
- if (this._compare(cur.key, identifier as K) === CP.lt) cur.right && queue.push(cur.right);
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);
526
526
  } else {
527
- cur.left && queue.push(cur.left);
528
- cur.right && queue.push(cur.right);
527
+ this.isRealNode(cur.left) && queue.push(cur.left);
528
+ this.isRealNode(cur.right) && queue.push(cur.right);
529
529
  }
530
530
  }
531
531
  }
@@ -856,7 +856,7 @@ export class BST<
856
856
  * @param {NODE | undefined} v - The parameter `v` is of type `NODE | undefined`. This means that it
857
857
  * can either be an object of type `NODE` or it can be `undefined`.
858
858
  */
859
- protected _setRoot(v: NODE | undefined) {
859
+ protected override _setRoot(v: NODE | undefined) {
860
860
  if (v) {
861
861
  v.parent = undefined;
862
862
  }