min-heap-typed 1.50.6 → 1.50.8
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 +2 -2
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +6 -4
- package/dist/data-structures/binary-tree/binary-tree.d.ts +3 -3
- package/dist/data-structures/binary-tree/binary-tree.js +36 -33
- package/dist/data-structures/binary-tree/bst.d.ts +7 -5
- package/dist/data-structures/binary-tree/bst.js +68 -47
- package/dist/data-structures/binary-tree/rb-tree.d.ts +2 -8
- package/dist/data-structures/binary-tree/rb-tree.js +7 -17
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +1 -2
- package/dist/data-structures/binary-tree/tree-multi-map.js +1 -1
- package/dist/types/common.d.ts +5 -22
- package/dist/types/common.js +0 -33
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +8 -5
- package/src/data-structures/binary-tree/avl-tree.ts +1 -1
- package/src/data-structures/binary-tree/binary-tree.ts +35 -36
- package/src/data-structures/binary-tree/bst.ts +67 -44
- package/src/data-structures/binary-tree/rb-tree.ts +11 -22
- package/src/data-structures/binary-tree/tree-multi-map.ts +2 -2
- package/src/types/common.ts +6 -23
|
@@ -49,7 +49,6 @@ class RedBlackTree extends bst_1.BST {
|
|
|
49
49
|
constructor(keysOrNodesOrEntries = [], options) {
|
|
50
50
|
super([], options);
|
|
51
51
|
this._SENTINEL = new RedBlackTreeNode(NaN);
|
|
52
|
-
this._size = 0;
|
|
53
52
|
this._root = this.SENTINEL;
|
|
54
53
|
if (keysOrNodesOrEntries) {
|
|
55
54
|
this.addMany(keysOrNodesOrEntries);
|
|
@@ -69,13 +68,6 @@ class RedBlackTree extends bst_1.BST {
|
|
|
69
68
|
get root() {
|
|
70
69
|
return this._root;
|
|
71
70
|
}
|
|
72
|
-
/**
|
|
73
|
-
* The function returns the size of an object.
|
|
74
|
-
* @returns The size of the object, which is a number.
|
|
75
|
-
*/
|
|
76
|
-
get size() {
|
|
77
|
-
return this._size;
|
|
78
|
-
}
|
|
79
71
|
/**
|
|
80
72
|
* The function creates a new Red-Black Tree node with the specified key, value, and color.
|
|
81
73
|
* @param {K} key - The key parameter represents the key of the node being created. It is of type K,
|
|
@@ -170,7 +162,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
170
162
|
* @returns a boolean value.
|
|
171
163
|
*/
|
|
172
164
|
isRealNode(node) {
|
|
173
|
-
if (node === this.
|
|
165
|
+
if (node === this.SENTINEL || node === undefined)
|
|
174
166
|
return false;
|
|
175
167
|
return node instanceof RedBlackTreeNode;
|
|
176
168
|
}
|
|
@@ -201,9 +193,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
201
193
|
*/
|
|
202
194
|
getNode(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
|
|
203
195
|
var _a;
|
|
204
|
-
if (identifier instanceof RedBlackTreeNode)
|
|
205
|
-
callback = (node => node);
|
|
206
|
-
beginRoot = this.ensureNode(beginRoot);
|
|
196
|
+
// if ((identifier as any) instanceof RedBlackTreeNode) callback = (node => node) as C;
|
|
207
197
|
return (_a = this.getNodes(identifier, callback, true, beginRoot, iterationType)[0]) !== null && _a !== void 0 ? _a : undefined;
|
|
208
198
|
}
|
|
209
199
|
/**
|
|
@@ -218,8 +208,8 @@ class RedBlackTree extends bst_1.BST {
|
|
|
218
208
|
* size counter to zero.
|
|
219
209
|
*/
|
|
220
210
|
clear() {
|
|
211
|
+
super.clear();
|
|
221
212
|
this._root = this.SENTINEL;
|
|
222
|
-
this._size = 0;
|
|
223
213
|
}
|
|
224
214
|
/**
|
|
225
215
|
* Time Complexity: O(log n)
|
|
@@ -243,7 +233,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
243
233
|
if (!this.isRealNode(newNode))
|
|
244
234
|
return false;
|
|
245
235
|
const insertStatus = this._insert(newNode);
|
|
246
|
-
if (insertStatus === '
|
|
236
|
+
if (insertStatus === 'CREATED') {
|
|
247
237
|
// Ensure the root is black
|
|
248
238
|
if (this.isRealNode(this._root)) {
|
|
249
239
|
this._root.color = types_1.RBTNColor.BLACK;
|
|
@@ -255,7 +245,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
255
245
|
return true;
|
|
256
246
|
}
|
|
257
247
|
else
|
|
258
|
-
return insertStatus === '
|
|
248
|
+
return insertStatus === 'UPDATED';
|
|
259
249
|
}
|
|
260
250
|
/**
|
|
261
251
|
* Time Complexity: O(log n)
|
|
@@ -388,7 +378,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
388
378
|
}
|
|
389
379
|
else {
|
|
390
380
|
this._replaceNode(current, node);
|
|
391
|
-
return '
|
|
381
|
+
return 'UPDATED';
|
|
392
382
|
}
|
|
393
383
|
}
|
|
394
384
|
node.parent = parent;
|
|
@@ -405,7 +395,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
405
395
|
node.right = this.SENTINEL;
|
|
406
396
|
node.color = types_1.RBTNColor.RED;
|
|
407
397
|
this._insertFixup(node);
|
|
408
|
-
return '
|
|
398
|
+
return 'CREATED';
|
|
409
399
|
}
|
|
410
400
|
/**
|
|
411
401
|
* Time Complexity: O(1)
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
8
|
import type { BinaryTreeDeleteResult, BSTNKeyOrNode, BTNCallback, KeyOrNodeOrEntry, TreeMultiMapNested, TreeMultiMapNodeNested, TreeMultiMapOptions } from '../../types';
|
|
9
|
-
import { IterationType } from '../../types';
|
|
10
9
|
import { IBinaryTree } from '../../interfaces';
|
|
11
10
|
import { RedBlackTree, RedBlackTreeNode } from './rb-tree';
|
|
12
11
|
export declare class TreeMultiMapNode<K = any, V = any, NODE extends TreeMultiMapNode<K, V, NODE> = TreeMultiMapNodeNested<K, V>> extends RedBlackTreeNode<K, V, NODE> {
|
|
@@ -164,7 +163,7 @@ export declare class TreeMultiMap<K = any, V = any, NODE extends TreeMultiMapNod
|
|
|
164
163
|
* values:
|
|
165
164
|
* @returns a boolean value.
|
|
166
165
|
*/
|
|
167
|
-
perfectlyBalance(iterationType?: IterationType): boolean;
|
|
166
|
+
perfectlyBalance(iterationType?: import("../../types").IterationType): boolean;
|
|
168
167
|
/**
|
|
169
168
|
* Time complexity: O(n)
|
|
170
169
|
* Space complexity: O(n)
|
|
@@ -312,7 +312,7 @@ class TreeMultiMap extends rb_tree_1.RedBlackTree {
|
|
|
312
312
|
if (sorted.length < 1)
|
|
313
313
|
return false;
|
|
314
314
|
this.clear();
|
|
315
|
-
if (iterationType ===
|
|
315
|
+
if (iterationType === 'RECURSIVE') {
|
|
316
316
|
const buildBalanceBST = (l, r) => {
|
|
317
317
|
if (l > r)
|
|
318
318
|
return;
|
package/dist/types/common.d.ts
CHANGED
|
@@ -1,31 +1,13 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
INVERSE = "INVERSE"
|
|
4
|
-
}
|
|
5
|
-
export declare enum CP {
|
|
6
|
-
lt = "lt",
|
|
7
|
-
eq = "eq",
|
|
8
|
-
gt = "gt"
|
|
9
|
-
}
|
|
1
|
+
export type BSTVariant = 'STANDARD' | 'INVERSE';
|
|
2
|
+
export type CP = 'LT' | 'EQ' | 'GT';
|
|
10
3
|
/**
|
|
11
4
|
* Enum representing different loop types.
|
|
12
5
|
*
|
|
13
6
|
* - `iterative`: Indicates the iterative loop type (with loops that use iterations).
|
|
14
7
|
* - `recursive`: Indicates the recursive loop type (with loops that call themselves).
|
|
15
8
|
*/
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
RECURSIVE = "RECURSIVE"
|
|
19
|
-
}
|
|
20
|
-
export declare enum FamilyPosition {
|
|
21
|
-
ROOT = "ROOT",
|
|
22
|
-
LEFT = "LEFT",
|
|
23
|
-
RIGHT = "RIGHT",
|
|
24
|
-
ROOT_LEFT = "ROOT_LEFT",
|
|
25
|
-
ROOT_RIGHT = "ROOT_RIGHT",
|
|
26
|
-
ISOLATED = "ISOLATED",
|
|
27
|
-
MAL_NODE = "MAL_NODE"
|
|
28
|
-
}
|
|
9
|
+
export type IterationType = 'ITERATIVE' | 'RECURSIVE';
|
|
10
|
+
export type FamilyPosition = 'ROOT' | 'LEFT' | 'RIGHT' | 'ROOT_LEFT' | 'ROOT_RIGHT' | 'ISOLATED' | 'MAL_NODE';
|
|
29
11
|
export type Comparator<K> = (a: K, b: K) => number;
|
|
30
12
|
export type DFSOrderPattern = 'pre' | 'in' | 'post';
|
|
31
13
|
export type NodeDisplayLayout = [string[], number, number, number];
|
|
@@ -52,3 +34,4 @@ export type BinaryTreeDeleteResult<N> = {
|
|
|
52
34
|
deleted: N | null | undefined;
|
|
53
35
|
needBalanced: N | null | undefined;
|
|
54
36
|
};
|
|
37
|
+
export type CRUD = 'CREATED' | 'READ' | 'UPDATED' | 'DELETED';
|
package/dist/types/common.js
CHANGED
|
@@ -1,35 +1,2 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FamilyPosition = exports.IterationType = exports.CP = exports.BSTVariant = void 0;
|
|
4
|
-
var BSTVariant;
|
|
5
|
-
(function (BSTVariant) {
|
|
6
|
-
BSTVariant["STANDARD"] = "STANDARD";
|
|
7
|
-
BSTVariant["INVERSE"] = "INVERSE";
|
|
8
|
-
})(BSTVariant = exports.BSTVariant || (exports.BSTVariant = {}));
|
|
9
|
-
var CP;
|
|
10
|
-
(function (CP) {
|
|
11
|
-
CP["lt"] = "lt";
|
|
12
|
-
CP["eq"] = "eq";
|
|
13
|
-
CP["gt"] = "gt";
|
|
14
|
-
})(CP = exports.CP || (exports.CP = {}));
|
|
15
|
-
/**
|
|
16
|
-
* Enum representing different loop types.
|
|
17
|
-
*
|
|
18
|
-
* - `iterative`: Indicates the iterative loop type (with loops that use iterations).
|
|
19
|
-
* - `recursive`: Indicates the recursive loop type (with loops that call themselves).
|
|
20
|
-
*/
|
|
21
|
-
var IterationType;
|
|
22
|
-
(function (IterationType) {
|
|
23
|
-
IterationType["ITERATIVE"] = "ITERATIVE";
|
|
24
|
-
IterationType["RECURSIVE"] = "RECURSIVE";
|
|
25
|
-
})(IterationType = exports.IterationType || (exports.IterationType = {}));
|
|
26
|
-
var FamilyPosition;
|
|
27
|
-
(function (FamilyPosition) {
|
|
28
|
-
FamilyPosition["ROOT"] = "ROOT";
|
|
29
|
-
FamilyPosition["LEFT"] = "LEFT";
|
|
30
|
-
FamilyPosition["RIGHT"] = "RIGHT";
|
|
31
|
-
FamilyPosition["ROOT_LEFT"] = "ROOT_LEFT";
|
|
32
|
-
FamilyPosition["ROOT_RIGHT"] = "ROOT_RIGHT";
|
|
33
|
-
FamilyPosition["ISOLATED"] = "ISOLATED";
|
|
34
|
-
FamilyPosition["MAL_NODE"] = "MAL_NODE";
|
|
35
|
-
})(FamilyPosition = exports.FamilyPosition || (exports.FamilyPosition = {}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "min-heap-typed",
|
|
3
|
-
"version": "1.50.
|
|
3
|
+
"version": "1.50.8",
|
|
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.8"
|
|
136
136
|
}
|
|
137
137
|
}
|
|
@@ -14,7 +14,6 @@ import type {
|
|
|
14
14
|
BTNCallback,
|
|
15
15
|
KeyOrNodeOrEntry
|
|
16
16
|
} from '../../types';
|
|
17
|
-
import { FamilyPosition, IterationType } from '../../types';
|
|
18
17
|
import { IBinaryTree } from '../../interfaces';
|
|
19
18
|
import { AVLTree, AVLTreeNode } from './avl-tree';
|
|
20
19
|
|
|
@@ -83,6 +82,10 @@ export class AVLTreeMultiMap<
|
|
|
83
82
|
* @returns the sum of the count property of all nodes in the tree.
|
|
84
83
|
*/
|
|
85
84
|
get count(): number {
|
|
85
|
+
return this._count;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
getMutableCount(): number {
|
|
86
89
|
let sum = 0;
|
|
87
90
|
this.dfs(node => (sum += node.count));
|
|
88
91
|
return sum;
|
|
@@ -245,9 +248,9 @@ export class AVLTreeMultiMap<
|
|
|
245
248
|
if (curr.right !== undefined) this._setRoot(curr.right);
|
|
246
249
|
} else {
|
|
247
250
|
const { familyPosition: fp } = curr;
|
|
248
|
-
if (fp ===
|
|
251
|
+
if (fp === 'LEFT' || fp === 'ROOT_LEFT') {
|
|
249
252
|
parent.left = curr.right;
|
|
250
|
-
} else if (fp ===
|
|
253
|
+
} else if (fp === 'RIGHT' || fp === 'ROOT_RIGHT') {
|
|
251
254
|
parent.right = curr.right;
|
|
252
255
|
}
|
|
253
256
|
needBalanced = parent;
|
|
@@ -320,7 +323,7 @@ export class AVLTreeMultiMap<
|
|
|
320
323
|
|
|
321
324
|
this.clear();
|
|
322
325
|
|
|
323
|
-
if (iterationType ===
|
|
326
|
+
if (iterationType === 'RECURSIVE') {
|
|
324
327
|
const buildBalanceBST = (l: number, r: number) => {
|
|
325
328
|
if (l > r) return;
|
|
326
329
|
const m = l + Math.floor((r - l) / 2);
|
|
@@ -414,7 +417,7 @@ export class AVLTreeMultiMap<
|
|
|
414
417
|
* @returns The method is returning the result of calling the `_replaceNode` method from the
|
|
415
418
|
* superclass, after updating the `count` property of the `newNode` object.
|
|
416
419
|
*/
|
|
417
|
-
protected _replaceNode(oldNode: NODE, newNode: NODE): NODE {
|
|
420
|
+
protected override _replaceNode(oldNode: NODE, newNode: NODE): NODE {
|
|
418
421
|
newNode.count = oldNode.count + newNode.count;
|
|
419
422
|
return super._replaceNode(oldNode, newNode);
|
|
420
423
|
}
|
|
@@ -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);
|
|
@@ -107,16 +107,16 @@ export class BinaryTreeNode<
|
|
|
107
107
|
get familyPosition(): FamilyPosition {
|
|
108
108
|
const that = this as unknown as NODE;
|
|
109
109
|
if (!this.parent) {
|
|
110
|
-
return this.left || this.right ?
|
|
110
|
+
return this.left || this.right ? 'ROOT' : 'ISOLATED';
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
if (this.parent.left === that) {
|
|
114
|
-
return this.left || this.right ?
|
|
114
|
+
return this.left || this.right ? 'ROOT_LEFT' : 'LEFT';
|
|
115
115
|
} else if (this.parent.right === that) {
|
|
116
|
-
return this.left || this.right ?
|
|
116
|
+
return this.left || this.right ? 'ROOT_RIGHT' : 'RIGHT';
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
return
|
|
119
|
+
return 'MAL_NODE';
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
|
|
@@ -136,7 +136,7 @@ export class BinaryTree<
|
|
|
136
136
|
>
|
|
137
137
|
extends IterableEntryBase<K, V | undefined>
|
|
138
138
|
implements IBinaryTree<K, V, NODE, TREE> {
|
|
139
|
-
iterationType =
|
|
139
|
+
iterationType: IterationType = 'ITERATIVE';
|
|
140
140
|
|
|
141
141
|
/**
|
|
142
142
|
* The constructor function initializes a binary tree object with optional keysOrNodesOrEntries and options.
|
|
@@ -160,7 +160,7 @@ export class BinaryTree<
|
|
|
160
160
|
if (keysOrNodesOrEntries) this.addMany(keysOrNodesOrEntries);
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
protected _extractor = (key: K) => Number(key);
|
|
163
|
+
protected _extractor = (key: K) => (typeof key === 'number' ? key : Number(key));
|
|
164
164
|
|
|
165
165
|
/**
|
|
166
166
|
* The function returns the value of the `_extractor` property.
|
|
@@ -260,14 +260,11 @@ export class BinaryTree<
|
|
|
260
260
|
* `null`, or `undefined`. It represents a key used to identify a node in a binary tree.
|
|
261
261
|
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
262
262
|
* type of iteration to be used when searching for a node by key. It has a default value of
|
|
263
|
-
* `
|
|
263
|
+
* `'ITERATIVE'`.
|
|
264
264
|
* @returns either the node corresponding to the given key if it is a valid node key, or the key
|
|
265
265
|
* itself if it is not a valid node key.
|
|
266
266
|
*/
|
|
267
|
-
ensureNode(
|
|
268
|
-
keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>,
|
|
269
|
-
iterationType = IterationType.ITERATIVE
|
|
270
|
-
): NODE | null | undefined {
|
|
267
|
+
ensureNode(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>, iterationType = 'ITERATIVE'): NODE | null | undefined {
|
|
271
268
|
let res: NODE | null | undefined;
|
|
272
269
|
if (this.isRealNode(keyOrNodeOrEntry)) {
|
|
273
270
|
res = keyOrNodeOrEntry;
|
|
@@ -521,9 +518,9 @@ export class BinaryTree<
|
|
|
521
518
|
}
|
|
522
519
|
} else if (parent) {
|
|
523
520
|
const { familyPosition: fp } = curr;
|
|
524
|
-
if (fp ===
|
|
521
|
+
if (fp === 'LEFT' || fp === 'ROOT_LEFT') {
|
|
525
522
|
parent.left = curr.right;
|
|
526
|
-
} else if (fp ===
|
|
523
|
+
} else if (fp === 'RIGHT' || fp === 'ROOT_RIGHT') {
|
|
527
524
|
parent.right = curr.right;
|
|
528
525
|
}
|
|
529
526
|
needBalanced = parent;
|
|
@@ -606,7 +603,7 @@ export class BinaryTree<
|
|
|
606
603
|
|
|
607
604
|
const ans: NODE[] = [];
|
|
608
605
|
|
|
609
|
-
if (iterationType ===
|
|
606
|
+
if (iterationType === 'RECURSIVE') {
|
|
610
607
|
const _traverse = (cur: NODE) => {
|
|
611
608
|
if (callback(cur) === identifier) {
|
|
612
609
|
ans.push(cur);
|
|
@@ -714,9 +711,9 @@ export class BinaryTree<
|
|
|
714
711
|
* @returns The function `getNodeByKey` returns a node (`NODE`) if a node with the specified key is
|
|
715
712
|
* found in the binary tree. If no node is found, it returns `undefined`.
|
|
716
713
|
*/
|
|
717
|
-
getNodeByKey(key: K, iterationType =
|
|
714
|
+
getNodeByKey(key: K, iterationType = 'ITERATIVE'): NODE | undefined {
|
|
718
715
|
if (!this.root) return undefined;
|
|
719
|
-
if (iterationType ===
|
|
716
|
+
if (iterationType === 'RECURSIVE') {
|
|
720
717
|
const _dfs = (cur: NODE): NODE | undefined => {
|
|
721
718
|
if (cur.key === key) return cur;
|
|
722
719
|
|
|
@@ -932,7 +929,7 @@ export class BinaryTree<
|
|
|
932
929
|
beginRoot = this.ensureNode(beginRoot);
|
|
933
930
|
if (!beginRoot) return true;
|
|
934
931
|
|
|
935
|
-
if (iterationType ===
|
|
932
|
+
if (iterationType === 'RECURSIVE') {
|
|
936
933
|
const dfs = (cur: NODE | null | undefined, min: number, max: number): boolean => {
|
|
937
934
|
if (!this.isRealNode(cur)) return true;
|
|
938
935
|
const numKey = this.extractor(cur.key);
|
|
@@ -1021,9 +1018,9 @@ export class BinaryTree<
|
|
|
1021
1018
|
*/
|
|
1022
1019
|
getHeight(beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root, iterationType = this.iterationType): number {
|
|
1023
1020
|
beginRoot = this.ensureNode(beginRoot);
|
|
1024
|
-
if (!beginRoot) return -1;
|
|
1021
|
+
if (!this.isRealNode(beginRoot)) return -1;
|
|
1025
1022
|
|
|
1026
|
-
if (iterationType ===
|
|
1023
|
+
if (iterationType === 'RECURSIVE') {
|
|
1027
1024
|
const _getMaxHeight = (cur: NODE | null | undefined): number => {
|
|
1028
1025
|
if (!this.isRealNode(cur)) return -1;
|
|
1029
1026
|
const leftHeight = _getMaxHeight(cur.left);
|
|
@@ -1071,10 +1068,10 @@ export class BinaryTree<
|
|
|
1071
1068
|
beginRoot = this.ensureNode(beginRoot);
|
|
1072
1069
|
if (!beginRoot) return -1;
|
|
1073
1070
|
|
|
1074
|
-
if (iterationType ===
|
|
1071
|
+
if (iterationType === 'RECURSIVE') {
|
|
1075
1072
|
const _getMinHeight = (cur: NODE | null | undefined): number => {
|
|
1076
|
-
if (!cur) return 0;
|
|
1077
|
-
if (!cur.left && !cur.right) return 0;
|
|
1073
|
+
if (!this.isRealNode(cur)) return 0;
|
|
1074
|
+
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return 0;
|
|
1078
1075
|
const leftMinHeight = _getMinHeight(cur.left);
|
|
1079
1076
|
const rightMinHeight = _getMinHeight(cur.right);
|
|
1080
1077
|
return Math.min(leftMinHeight, rightMinHeight) + 1;
|
|
@@ -1088,16 +1085,16 @@ export class BinaryTree<
|
|
|
1088
1085
|
const depths: Map<NODE, number> = new Map();
|
|
1089
1086
|
|
|
1090
1087
|
while (stack.length > 0 || node) {
|
|
1091
|
-
if (node) {
|
|
1088
|
+
if (this.isRealNode(node)) {
|
|
1092
1089
|
stack.push(node);
|
|
1093
1090
|
node = node.left;
|
|
1094
1091
|
} else {
|
|
1095
1092
|
node = stack[stack.length - 1];
|
|
1096
|
-
if (!node.right || last === node.right) {
|
|
1093
|
+
if (!this.isRealNode(node.right) || last === node.right) {
|
|
1097
1094
|
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;
|
|
1095
|
+
if (this.isRealNode(node)) {
|
|
1096
|
+
const leftMinHeight = this.isRealNode(node.left) ? depths.get(node.left) ?? -1 : -1;
|
|
1097
|
+
const rightMinHeight = this.isRealNode(node.right) ? depths.get(node.right) ?? -1 : -1;
|
|
1101
1098
|
depths.set(node, 1 + Math.min(leftMinHeight, rightMinHeight));
|
|
1102
1099
|
last = node;
|
|
1103
1100
|
node = null;
|
|
@@ -1169,11 +1166,12 @@ export class BinaryTree<
|
|
|
1169
1166
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
1170
1167
|
iterationType = this.iterationType
|
|
1171
1168
|
): NODE | null | undefined {
|
|
1169
|
+
if (this.isNIL(beginRoot)) return beginRoot as NODE;
|
|
1172
1170
|
beginRoot = this.ensureNode(beginRoot);
|
|
1173
1171
|
|
|
1174
|
-
if (!beginRoot) return beginRoot;
|
|
1172
|
+
if (!this.isRealNode(beginRoot)) return beginRoot;
|
|
1175
1173
|
|
|
1176
|
-
if (iterationType ===
|
|
1174
|
+
if (iterationType === 'RECURSIVE') {
|
|
1177
1175
|
const _traverse = (cur: NODE): NODE => {
|
|
1178
1176
|
if (!this.isRealNode(cur.left)) return cur;
|
|
1179
1177
|
return _traverse(cur.left);
|
|
@@ -1215,11 +1213,12 @@ export class BinaryTree<
|
|
|
1215
1213
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
1216
1214
|
iterationType = this.iterationType
|
|
1217
1215
|
): NODE | null | undefined {
|
|
1216
|
+
if (this.isNIL(beginRoot)) return beginRoot as NODE;
|
|
1218
1217
|
// TODO support get right most by passing key in
|
|
1219
1218
|
beginRoot = this.ensureNode(beginRoot);
|
|
1220
1219
|
if (!beginRoot) return beginRoot;
|
|
1221
1220
|
|
|
1222
|
-
if (iterationType ===
|
|
1221
|
+
if (iterationType === 'RECURSIVE') {
|
|
1223
1222
|
const _traverse = (cur: NODE): NODE => {
|
|
1224
1223
|
if (!this.isRealNode(cur.right)) return cur;
|
|
1225
1224
|
return _traverse(cur.right);
|
|
@@ -1343,13 +1342,13 @@ export class BinaryTree<
|
|
|
1343
1342
|
callback: C = this._defaultOneParamCallback as C,
|
|
1344
1343
|
pattern: DFSOrderPattern = 'in',
|
|
1345
1344
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
1346
|
-
iterationType: IterationType =
|
|
1345
|
+
iterationType: IterationType = 'ITERATIVE',
|
|
1347
1346
|
includeNull = false
|
|
1348
1347
|
): ReturnType<C>[] {
|
|
1349
1348
|
beginRoot = this.ensureNode(beginRoot);
|
|
1350
1349
|
if (!beginRoot) return [];
|
|
1351
1350
|
const ans: ReturnType<C>[] = [];
|
|
1352
|
-
if (iterationType ===
|
|
1351
|
+
if (iterationType === 'RECURSIVE') {
|
|
1353
1352
|
const _traverse = (node: NODE | null | undefined) => {
|
|
1354
1353
|
switch (pattern) {
|
|
1355
1354
|
case 'in':
|
|
@@ -1485,7 +1484,7 @@ export class BinaryTree<
|
|
|
1485
1484
|
|
|
1486
1485
|
const ans: ReturnType<BTNCallback<NODE>>[] = [];
|
|
1487
1486
|
|
|
1488
|
-
if (iterationType ===
|
|
1487
|
+
if (iterationType === 'RECURSIVE') {
|
|
1489
1488
|
const queue: Queue<NODE | null | undefined> = new Queue<NODE | null | undefined>([beginRoot]);
|
|
1490
1489
|
|
|
1491
1490
|
const traverse = (level: number) => {
|
|
@@ -1578,7 +1577,7 @@ export class BinaryTree<
|
|
|
1578
1577
|
const levelsNodes: ReturnType<C>[][] = [];
|
|
1579
1578
|
if (!beginRoot) return levelsNodes;
|
|
1580
1579
|
|
|
1581
|
-
if (iterationType ===
|
|
1580
|
+
if (iterationType === 'RECURSIVE') {
|
|
1582
1581
|
const _recursive = (node: NODE | null, level: number) => {
|
|
1583
1582
|
if (!levelsNodes[level]) levelsNodes[level] = [];
|
|
1584
1583
|
levelsNodes[level].push(callback(node));
|
|
@@ -1837,7 +1836,7 @@ export class BinaryTree<
|
|
|
1837
1836
|
* following types:
|
|
1838
1837
|
* @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
1838
|
*/
|
|
1840
|
-
print(beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root, options?: BinaryTreePrintOptions): void {
|
|
1839
|
+
override print(beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root, options?: BinaryTreePrintOptions): void {
|
|
1841
1840
|
const opts = { isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false, ...options };
|
|
1842
1841
|
beginRoot = this.ensureNode(beginRoot);
|
|
1843
1842
|
if (!beginRoot) return;
|
|
@@ -1874,7 +1873,7 @@ export class BinaryTree<
|
|
|
1874
1873
|
protected* _getIterator(node = this.root): IterableIterator<[K, V | undefined]> {
|
|
1875
1874
|
if (!node) return;
|
|
1876
1875
|
|
|
1877
|
-
if (this.iterationType ===
|
|
1876
|
+
if (this.iterationType === 'ITERATIVE') {
|
|
1878
1877
|
const stack: (NODE | null | undefined)[] = [];
|
|
1879
1878
|
let current: NODE | null | undefined = node;
|
|
1880
1879
|
|