undirected-graph-typed 1.51.7 → 1.51.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 +3 -12
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +1 -10
- package/dist/data-structures/binary-tree/avl-tree.d.ts +3 -3
- package/dist/data-structures/binary-tree/avl-tree.js +12 -12
- package/dist/data-structures/binary-tree/binary-tree.d.ts +5 -12
- package/dist/data-structures/binary-tree/binary-tree.js +22 -32
- package/dist/data-structures/binary-tree/bst.d.ts +32 -77
- package/dist/data-structures/binary-tree/bst.js +68 -136
- package/dist/data-structures/binary-tree/rb-tree.d.ts +3 -13
- package/dist/data-structures/binary-tree/rb-tree.js +3 -20
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +3 -4
- package/dist/data-structures/heap/heap.d.ts +1 -3
- package/dist/interfaces/binary-tree.d.ts +3 -3
- package/dist/types/common.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +3 -2
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +3 -2
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +4 -4
- package/dist/types/data-structures/binary-tree/bst.d.ts +6 -5
- package/dist/types/data-structures/binary-tree/rb-tree.d.ts +4 -3
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +3 -2
- package/dist/types/utils/utils.d.ts +10 -1
- package/dist/utils/utils.d.ts +2 -1
- package/dist/utils/utils.js +29 -1
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +4 -12
- package/src/data-structures/binary-tree/avl-tree.ts +15 -14
- package/src/data-structures/binary-tree/binary-tree.ts +29 -38
- package/src/data-structures/binary-tree/bst.ts +78 -148
- package/src/data-structures/binary-tree/rb-tree.ts +8 -22
- package/src/data-structures/binary-tree/tree-multi-map.ts +4 -3
- package/src/data-structures/heap/heap.ts +1 -1
- package/src/interfaces/binary-tree.ts +4 -3
- package/src/types/common.ts +1 -1
- package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +3 -2
- package/src/types/data-structures/binary-tree/avl-tree.ts +3 -2
- package/src/types/data-structures/binary-tree/binary-tree.ts +5 -5
- package/src/types/data-structures/binary-tree/bst.ts +6 -5
- package/src/types/data-structures/binary-tree/rb-tree.ts +4 -3
- package/src/types/data-structures/binary-tree/tree-multi-map.ts +3 -2
- package/src/types/utils/utils.ts +14 -1
- package/src/utils/utils.ts +20 -1
|
@@ -5,4 +5,13 @@ export type Thunk = () => ReturnType<ToThunkFn> & {
|
|
|
5
5
|
export type TrlFn = (...args: any[]) => any;
|
|
6
6
|
export type TrlAsyncFn = (...args: any[]) => any;
|
|
7
7
|
export type SpecifyOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
8
|
-
export type Any = string | number |
|
|
8
|
+
export type Any = string | number | bigint | boolean | symbol | undefined | object;
|
|
9
|
+
export type Comparable = number | string | bigint | boolean | ({
|
|
10
|
+
[key in string]: any;
|
|
11
|
+
} & {
|
|
12
|
+
valueOf(): Comparable;
|
|
13
|
+
}) | ({
|
|
14
|
+
[key in string]: any;
|
|
15
|
+
} & {
|
|
16
|
+
toString(): Comparable;
|
|
17
|
+
}) | (() => Comparable);
|
package/dist/utils/utils.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
-
import type { Thunk, ToThunkFn, TrlAsyncFn, TrlFn } from '../types';
|
|
8
|
+
import type { Comparable, Thunk, ToThunkFn, TrlAsyncFn, TrlFn } from '../types';
|
|
9
9
|
export declare const uuidV4: () => string;
|
|
10
10
|
export declare const arrayRemove: <T>(array: T[], predicate: (item: T, index: number, array: T[]) => boolean) => T[];
|
|
11
11
|
export declare const THUNK_SYMBOL: unique symbol;
|
|
@@ -23,3 +23,4 @@ export declare const throwRangeError: (message?: string) => void;
|
|
|
23
23
|
export declare const isWeakKey: (input: unknown) => input is object;
|
|
24
24
|
export declare const calcMinUnitsRequired: (totalQuantity: number, unitSize: number) => number;
|
|
25
25
|
export declare const roundFixed: (num: number, digit?: number) => number;
|
|
26
|
+
export declare function isComparable(key: any): key is Comparable;
|
package/dist/utils/utils.js
CHANGED
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.roundFixed = exports.calcMinUnitsRequired = exports.isWeakKey = exports.throwRangeError = exports.rangeCheck = exports.getMSB = exports.trampolineAsync = exports.trampoline = exports.toThunk = exports.isThunk = exports.THUNK_SYMBOL = exports.arrayRemove = exports.uuidV4 = void 0;
|
|
12
|
+
exports.isComparable = exports.roundFixed = exports.calcMinUnitsRequired = exports.isWeakKey = exports.throwRangeError = exports.rangeCheck = exports.getMSB = exports.trampolineAsync = exports.trampoline = exports.toThunk = exports.isThunk = exports.THUNK_SYMBOL = exports.arrayRemove = exports.uuidV4 = void 0;
|
|
13
13
|
const uuidV4 = function () {
|
|
14
14
|
return 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'.replace(/[x]/g, function (c) {
|
|
15
15
|
const r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8;
|
|
@@ -92,3 +92,31 @@ const roundFixed = (num, digit = 10) => {
|
|
|
92
92
|
return Math.round(num * multiplier) / multiplier;
|
|
93
93
|
};
|
|
94
94
|
exports.roundFixed = roundFixed;
|
|
95
|
+
function isComparable(key) {
|
|
96
|
+
const keyType = typeof key;
|
|
97
|
+
if (keyType === 'number')
|
|
98
|
+
return isNaN(key);
|
|
99
|
+
if (keyType === 'string')
|
|
100
|
+
return true;
|
|
101
|
+
if (keyType === 'bigint')
|
|
102
|
+
return true;
|
|
103
|
+
if (keyType === 'boolean')
|
|
104
|
+
return true;
|
|
105
|
+
if (keyType === 'symbol')
|
|
106
|
+
return false;
|
|
107
|
+
if (keyType === 'undefined')
|
|
108
|
+
return false;
|
|
109
|
+
if (keyType === 'function')
|
|
110
|
+
return isComparable(key());
|
|
111
|
+
if (keyType === 'object') {
|
|
112
|
+
if (key === null)
|
|
113
|
+
return true;
|
|
114
|
+
if (typeof key.valueOf === 'function')
|
|
115
|
+
return isComparable(key.valueOf());
|
|
116
|
+
if (typeof key.toString === 'function')
|
|
117
|
+
return isComparable(key.toString());
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
exports.isComparable = isComparable;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "undirected-graph-typed",
|
|
3
|
-
"version": "1.51.
|
|
3
|
+
"version": "1.51.8",
|
|
4
4
|
"description": "Undirected Graph. Javascript & Typescript Data Structure.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -145,6 +145,6 @@
|
|
|
145
145
|
"typescript": "^4.9.5"
|
|
146
146
|
},
|
|
147
147
|
"dependencies": {
|
|
148
|
-
"data-structure-typed": "^1.51.
|
|
148
|
+
"data-structure-typed": "^1.51.8"
|
|
149
149
|
}
|
|
150
150
|
}
|
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
BinaryTreeDeleteResult,
|
|
13
13
|
BSTNKeyOrNode,
|
|
14
14
|
BTNCallback,
|
|
15
|
+
Comparable,
|
|
15
16
|
IterationType,
|
|
16
17
|
KeyOrNodeOrEntry
|
|
17
18
|
} from '../../types';
|
|
@@ -19,7 +20,7 @@ import { IBinaryTree } from '../../interfaces';
|
|
|
19
20
|
import { AVLTree, AVLTreeNode } from './avl-tree';
|
|
20
21
|
|
|
21
22
|
export class AVLTreeMultiMapNode<
|
|
22
|
-
K
|
|
23
|
+
K extends Comparable,
|
|
23
24
|
V = any,
|
|
24
25
|
NODE extends AVLTreeMultiMapNode<K, V, NODE> = AVLTreeMultiMapNodeNested<K, V>
|
|
25
26
|
> extends AVLTreeNode<K, V, NODE> {
|
|
@@ -62,7 +63,7 @@ export class AVLTreeMultiMapNode<
|
|
|
62
63
|
* The only distinction between a AVLTreeMultiMap and a AVLTree lies in the ability of the former to store duplicate nodes through the utilization of counters.
|
|
63
64
|
*/
|
|
64
65
|
export class AVLTreeMultiMap<
|
|
65
|
-
K
|
|
66
|
+
K extends Comparable,
|
|
66
67
|
V = any,
|
|
67
68
|
NODE extends AVLTreeMultiMapNode<K, V, NODE> = AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNodeNested<K, V>>,
|
|
68
69
|
TREE extends AVLTreeMultiMap<K, V, NODE, TREE> = AVLTreeMultiMap<K, V, NODE, AVLTreeMultiMapNested<K, V, NODE>>
|
|
@@ -118,19 +119,10 @@ export class AVLTreeMultiMap<
|
|
|
118
119
|
return new AVLTreeMultiMapNode(key, value, count) as NODE;
|
|
119
120
|
}
|
|
120
121
|
|
|
121
|
-
/**
|
|
122
|
-
* The function creates a new AVLTreeMultiMap object with the specified options and returns it.
|
|
123
|
-
* @param [options] - The `options` parameter is an optional object that contains additional
|
|
124
|
-
* configuration options for creating the `AVLTreeMultiMap` object. It can include properties such as
|
|
125
|
-
* `iterationType` and `variant`, which are used to specify the type of iteration and the variant of
|
|
126
|
-
* the tree, respectively. These properties can be
|
|
127
|
-
* @returns a new instance of the `AVLTreeMultiMap` class, with the provided options merged with the
|
|
128
|
-
* default options. The returned value is casted as `TREE`.
|
|
129
|
-
*/
|
|
130
122
|
override createTree(options?: AVLTreeMultiMapOptions<K>): TREE {
|
|
131
123
|
return new AVLTreeMultiMap<K, V, NODE, TREE>([], {
|
|
132
124
|
iterationType: this.iterationType,
|
|
133
|
-
|
|
125
|
+
comparator: this.comparator,
|
|
134
126
|
...options
|
|
135
127
|
}) as TREE;
|
|
136
128
|
}
|
|
@@ -13,12 +13,13 @@ import type {
|
|
|
13
13
|
BinaryTreeDeleteResult,
|
|
14
14
|
BSTNKeyOrNode,
|
|
15
15
|
BTNCallback,
|
|
16
|
+
Comparable,
|
|
16
17
|
KeyOrNodeOrEntry
|
|
17
18
|
} from '../../types';
|
|
18
19
|
import { IBinaryTree } from '../../interfaces';
|
|
19
20
|
|
|
20
21
|
export class AVLTreeNode<
|
|
21
|
-
K
|
|
22
|
+
K extends Comparable,
|
|
22
23
|
V = any,
|
|
23
24
|
NODE extends AVLTreeNode<K, V, NODE> = AVLTreeNodeNested<K, V>
|
|
24
25
|
> extends BSTNode<K, V, NODE> {
|
|
@@ -65,7 +66,7 @@ export class AVLTreeNode<
|
|
|
65
66
|
* 7. Path Length: The path length from the root to any leaf is longer compared to an unbalanced BST, but shorter than a linear chain of nodes.
|
|
66
67
|
*/
|
|
67
68
|
export class AVLTree<
|
|
68
|
-
K
|
|
69
|
+
K extends Comparable,
|
|
69
70
|
V = any,
|
|
70
71
|
NODE extends AVLTreeNode<K, V, NODE> = AVLTreeNode<K, V, AVLTreeNodeNested<K, V>>,
|
|
71
72
|
TREE extends AVLTree<K, V, NODE, TREE> = AVLTree<K, V, NODE, AVLTreeNested<K, V, NODE>>
|
|
@@ -109,7 +110,7 @@ export class AVLTree<
|
|
|
109
110
|
override createTree(options?: AVLTreeOptions<K>): TREE {
|
|
110
111
|
return new AVLTree<K, V, NODE, TREE>([], {
|
|
111
112
|
iterationType: this.iterationType,
|
|
112
|
-
|
|
113
|
+
comparator: this.comparator,
|
|
113
114
|
...options
|
|
114
115
|
}) as TREE;
|
|
115
116
|
}
|
|
@@ -195,26 +196,26 @@ export class AVLTree<
|
|
|
195
196
|
srcNode: BSTNKeyOrNode<K, NODE>,
|
|
196
197
|
destNode: BSTNKeyOrNode<K, NODE>
|
|
197
198
|
): NODE | undefined {
|
|
198
|
-
|
|
199
|
-
|
|
199
|
+
const srcNodeEnsured = this.ensureNode(srcNode);
|
|
200
|
+
const destNodeEnsured = this.ensureNode(destNode);
|
|
200
201
|
|
|
201
|
-
if (
|
|
202
|
-
const { key, value, height } =
|
|
202
|
+
if (srcNodeEnsured && destNodeEnsured) {
|
|
203
|
+
const { key, value, height } = destNodeEnsured;
|
|
203
204
|
const tempNode = this.createNode(key, value);
|
|
204
205
|
|
|
205
206
|
if (tempNode) {
|
|
206
207
|
tempNode.height = height;
|
|
207
208
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
209
|
+
destNodeEnsured.key = srcNodeEnsured.key;
|
|
210
|
+
destNodeEnsured.value = srcNodeEnsured.value;
|
|
211
|
+
destNodeEnsured.height = srcNodeEnsured.height;
|
|
211
212
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
srcNodeEnsured.key = tempNode.key;
|
|
214
|
+
srcNodeEnsured.value = tempNode.value;
|
|
215
|
+
srcNodeEnsured.height = tempNode.height;
|
|
215
216
|
}
|
|
216
217
|
|
|
217
|
-
return
|
|
218
|
+
return destNodeEnsured;
|
|
218
219
|
}
|
|
219
220
|
return undefined;
|
|
220
221
|
}
|
|
@@ -14,12 +14,14 @@ import type {
|
|
|
14
14
|
BinaryTreePrintOptions,
|
|
15
15
|
BTNCallback,
|
|
16
16
|
BTNEntry,
|
|
17
|
+
Comparable,
|
|
17
18
|
DFSOrderPattern,
|
|
18
19
|
EntryCallback,
|
|
20
|
+
FamilyPosition,
|
|
21
|
+
IterationType,
|
|
19
22
|
KeyOrNodeOrEntry,
|
|
20
23
|
NodeDisplayLayout
|
|
21
24
|
} from '../../types';
|
|
22
|
-
import { FamilyPosition, IterationType } from '../../types';
|
|
23
25
|
import { IBinaryTree } from '../../interfaces';
|
|
24
26
|
import { trampoline } from '../../utils';
|
|
25
27
|
import { Queue } from '../queue';
|
|
@@ -31,7 +33,7 @@ import { IterableEntryBase } from '../base';
|
|
|
31
33
|
* @template NODE - The type of the family relationship in the binary tree.
|
|
32
34
|
*/
|
|
33
35
|
export class BinaryTreeNode<
|
|
34
|
-
K
|
|
36
|
+
K extends Comparable,
|
|
35
37
|
V = any,
|
|
36
38
|
NODE extends BinaryTreeNode<K, V, NODE> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>
|
|
37
39
|
> {
|
|
@@ -129,7 +131,7 @@ export class BinaryTreeNode<
|
|
|
129
131
|
*/
|
|
130
132
|
|
|
131
133
|
export class BinaryTree<
|
|
132
|
-
K
|
|
134
|
+
K extends Comparable,
|
|
133
135
|
V = any,
|
|
134
136
|
NODE extends BinaryTreeNode<K, V, NODE> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>,
|
|
135
137
|
TREE extends BinaryTree<K, V, NODE, TREE> = BinaryTree<K, V, NODE, BinaryTreeNested<K, V, NODE>>
|
|
@@ -147,12 +149,11 @@ export class BinaryTree<
|
|
|
147
149
|
* `Partial<BinaryTreeOptions>`, which means that not all properties of `BinaryTreeOptions` are
|
|
148
150
|
* required.
|
|
149
151
|
*/
|
|
150
|
-
constructor(keysOrNodesOrEntries: Iterable<KeyOrNodeOrEntry<K, V, NODE>> = [], options?: BinaryTreeOptions
|
|
152
|
+
constructor(keysOrNodesOrEntries: Iterable<KeyOrNodeOrEntry<K, V, NODE>> = [], options?: BinaryTreeOptions) {
|
|
151
153
|
super();
|
|
152
154
|
if (options) {
|
|
153
|
-
const { iterationType
|
|
155
|
+
const { iterationType } = options;
|
|
154
156
|
if (iterationType) this.iterationType = iterationType;
|
|
155
|
-
if (extractor) this._extractor = extractor;
|
|
156
157
|
}
|
|
157
158
|
|
|
158
159
|
this._size = 0;
|
|
@@ -160,16 +161,6 @@ export class BinaryTree<
|
|
|
160
161
|
if (keysOrNodesOrEntries) this.addMany(keysOrNodesOrEntries);
|
|
161
162
|
}
|
|
162
163
|
|
|
163
|
-
protected _extractor = (key: K) => (typeof key === 'number' ? key : Number(key));
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* The function returns the value of the `_extractor` property.
|
|
167
|
-
* @returns The `_extractor` property is being returned.
|
|
168
|
-
*/
|
|
169
|
-
get extractor() {
|
|
170
|
-
return this._extractor;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
164
|
protected _root?: NODE | null;
|
|
174
165
|
|
|
175
166
|
/**
|
|
@@ -218,7 +209,7 @@ export class BinaryTree<
|
|
|
218
209
|
* you can provide only a subset of the properties defined in the `BinaryTreeOptions` interface.
|
|
219
210
|
* @returns a new instance of a binary tree.
|
|
220
211
|
*/
|
|
221
|
-
createTree(options?: Partial<BinaryTreeOptions
|
|
212
|
+
createTree(options?: Partial<BinaryTreeOptions>): TREE {
|
|
222
213
|
return new BinaryTree<K, V, NODE, TREE>([], { iterationType: this.iterationType, ...options }) as TREE;
|
|
223
214
|
}
|
|
224
215
|
|
|
@@ -921,7 +912,7 @@ export class BinaryTree<
|
|
|
921
912
|
if (iterationType === 'RECURSIVE') {
|
|
922
913
|
const dfs = (cur: NODE | null | undefined, min: number, max: number): boolean => {
|
|
923
914
|
if (!this.isRealNode(cur)) return true;
|
|
924
|
-
const numKey =
|
|
915
|
+
const numKey = Number(cur.key);
|
|
925
916
|
if (numKey <= min || numKey >= max) return false;
|
|
926
917
|
return dfs(cur.left, min, numKey) && dfs(cur.right, numKey, max);
|
|
927
918
|
};
|
|
@@ -941,7 +932,7 @@ export class BinaryTree<
|
|
|
941
932
|
curr = curr.left;
|
|
942
933
|
}
|
|
943
934
|
curr = stack.pop()!;
|
|
944
|
-
const numKey =
|
|
935
|
+
const numKey = Number(curr.key);
|
|
945
936
|
if (!this.isRealNode(curr) || (!checkMax && prev >= numKey) || (checkMax && prev <= numKey)) return false;
|
|
946
937
|
prev = numKey;
|
|
947
938
|
curr = curr.right;
|
|
@@ -973,15 +964,15 @@ export class BinaryTree<
|
|
|
973
964
|
* @returns the depth of the `dist` relative to the `beginRoot`.
|
|
974
965
|
*/
|
|
975
966
|
getDepth(dist: KeyOrNodeOrEntry<K, V, NODE>, beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root): number {
|
|
976
|
-
|
|
977
|
-
|
|
967
|
+
let distEnsured = this.ensureNode(dist);
|
|
968
|
+
const beginRootEnsured = this.ensureNode(beginRoot);
|
|
978
969
|
let depth = 0;
|
|
979
|
-
while (
|
|
980
|
-
if (
|
|
970
|
+
while (distEnsured?.parent) {
|
|
971
|
+
if (distEnsured === beginRootEnsured) {
|
|
981
972
|
return depth;
|
|
982
973
|
}
|
|
983
974
|
depth++;
|
|
984
|
-
|
|
975
|
+
distEnsured = distEnsured.parent;
|
|
985
976
|
}
|
|
986
977
|
return depth;
|
|
987
978
|
}
|
|
@@ -1124,17 +1115,17 @@ export class BinaryTree<
|
|
|
1124
1115
|
getPathToRoot(beginNode: KeyOrNodeOrEntry<K, V, NODE>, isReverse = true): NODE[] {
|
|
1125
1116
|
// TODO to support get path through passing key
|
|
1126
1117
|
const result: NODE[] = [];
|
|
1127
|
-
|
|
1118
|
+
let beginNodeEnsured = this.ensureNode(beginNode);
|
|
1128
1119
|
|
|
1129
|
-
if (!
|
|
1120
|
+
if (!beginNodeEnsured) return result;
|
|
1130
1121
|
|
|
1131
|
-
while (
|
|
1122
|
+
while (beginNodeEnsured.parent) {
|
|
1132
1123
|
// Array.push + Array.reverse is more efficient than Array.unshift
|
|
1133
1124
|
// TODO may consider using Deque, so far this is not the performance bottleneck
|
|
1134
|
-
result.push(
|
|
1135
|
-
|
|
1125
|
+
result.push(beginNodeEnsured);
|
|
1126
|
+
beginNodeEnsured = beginNodeEnsured.parent;
|
|
1136
1127
|
}
|
|
1137
|
-
result.push(
|
|
1128
|
+
result.push(beginNodeEnsured);
|
|
1138
1129
|
return isReverse ? result.reverse() : result;
|
|
1139
1130
|
}
|
|
1140
1131
|
|
|
@@ -1840,10 +1831,10 @@ export class BinaryTree<
|
|
|
1840
1831
|
console.log(`U for undefined
|
|
1841
1832
|
`);
|
|
1842
1833
|
if (opts.isShowNull)
|
|
1843
|
-
console.log(`
|
|
1834
|
+
console.log(`N for null
|
|
1844
1835
|
`);
|
|
1845
1836
|
if (opts.isShowRedBlackNIL)
|
|
1846
|
-
console.log(`S for Sentinel Node
|
|
1837
|
+
console.log(`S for Sentinel Node(NIL)
|
|
1847
1838
|
`);
|
|
1848
1839
|
|
|
1849
1840
|
const display = (root: NODE | null | undefined): void => {
|
|
@@ -1873,24 +1864,24 @@ export class BinaryTree<
|
|
|
1873
1864
|
let current: NODE | null | undefined = node;
|
|
1874
1865
|
|
|
1875
1866
|
while (current || stack.length > 0) {
|
|
1876
|
-
while (
|
|
1867
|
+
while (this.isRealNode(current)) {
|
|
1877
1868
|
stack.push(current);
|
|
1878
1869
|
current = current.left;
|
|
1879
1870
|
}
|
|
1880
1871
|
|
|
1881
1872
|
current = stack.pop();
|
|
1882
1873
|
|
|
1883
|
-
if (
|
|
1874
|
+
if (this.isRealNode(current)) {
|
|
1884
1875
|
yield [current.key, current.value];
|
|
1885
1876
|
current = current.right;
|
|
1886
1877
|
}
|
|
1887
1878
|
}
|
|
1888
1879
|
} else {
|
|
1889
|
-
if (node.left &&
|
|
1880
|
+
if (node.left && this.isRealNode(node)) {
|
|
1890
1881
|
yield* this[Symbol.iterator](node.left);
|
|
1891
1882
|
}
|
|
1892
1883
|
yield [node.key, node.value];
|
|
1893
|
-
if (node.right &&
|
|
1884
|
+
if (node.right && this.isRealNode(node)) {
|
|
1894
1885
|
yield* this[Symbol.iterator](node.right);
|
|
1895
1886
|
}
|
|
1896
1887
|
}
|
|
@@ -1919,13 +1910,13 @@ export class BinaryTree<
|
|
|
1919
1910
|
return emptyDisplayLayout;
|
|
1920
1911
|
} else if (node === undefined && !isShowUndefined) {
|
|
1921
1912
|
return emptyDisplayLayout;
|
|
1922
|
-
} else if (
|
|
1913
|
+
} else if (this.isNIL(node) && !isShowRedBlackNIL) {
|
|
1923
1914
|
return emptyDisplayLayout;
|
|
1924
1915
|
} else if (node !== null && node !== undefined) {
|
|
1925
1916
|
// Display logic of normal nodes
|
|
1926
1917
|
|
|
1927
1918
|
const key = node.key,
|
|
1928
|
-
line =
|
|
1919
|
+
line = this.isNIL(node) ? 'S' : key.toString(),
|
|
1929
1920
|
width = line.length;
|
|
1930
1921
|
|
|
1931
1922
|
return _buildNodeDisplay(
|