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.
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -0
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +3 -0
- package/dist/data-structures/binary-tree/binary-tree.js +32 -28
- package/dist/data-structures/binary-tree/bst.js +17 -17
- package/dist/data-structures/binary-tree/rb-tree.d.ts +158 -141
- package/dist/data-structures/binary-tree/rb-tree.js +416 -396
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +1 -0
- package/dist/data-structures/binary-tree/tree-multi-map.js +84 -76
- package/dist/types/common.d.ts +6 -0
- package/dist/types/common.js +8 -1
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +5 -1
- package/src/data-structures/binary-tree/avl-tree.ts +1 -1
- package/src/data-structures/binary-tree/binary-tree.ts +31 -29
- package/src/data-structures/binary-tree/bst.ts +18 -18
- package/src/data-structures/binary-tree/rb-tree.ts +436 -405
- package/src/data-structures/binary-tree/tree-multi-map.ts +85 -82
- package/src/types/common.ts +7 -0
|
@@ -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
|
-
|
|
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
|
|
194
|
-
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
|
|
209
|
+
else {
|
|
210
|
+
nodeToDelete.count--;
|
|
211
|
+
this._count--;
|
|
212
|
+
results.push({ deleted: nodeToDelete, needBalanced: undefined });
|
|
213
|
+
return results;
|
|
216
214
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
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
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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
|
-
|
|
243
|
-
this.
|
|
244
|
-
|
|
245
|
-
|
|
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
|
-
|
|
254
|
-
|
|
255
|
-
this.
|
|
255
|
+
if (ignoreCount || nodeToDelete.count <= 1) {
|
|
256
|
+
this._transplant(nodeToDelete, successor);
|
|
257
|
+
this._count -= nodeToDelete.count;
|
|
256
258
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
this.
|
|
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
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
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)
|
package/dist/types/common.d.ts
CHANGED
package/dist/types/common.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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
|
}
|