data-structure-typed 1.19.3 → 1.19.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data-structures/binary-tree/aa-tree.js +2 -5
- package/dist/data-structures/binary-tree/abstract-binary-tree.js +361 -488
- package/dist/data-structures/binary-tree/avl-tree.js +46 -90
- package/dist/data-structures/binary-tree/b-tree.js +2 -5
- package/dist/data-structures/binary-tree/binary-indexed-tree.js +17 -22
- package/dist/data-structures/binary-tree/binary-tree.js +9 -31
- package/dist/data-structures/binary-tree/bst.js +96 -139
- package/dist/data-structures/binary-tree/rb-tree.js +32 -56
- package/dist/data-structures/binary-tree/segment-tree.js +78 -120
- package/dist/data-structures/binary-tree/splay-tree.js +2 -5
- package/dist/data-structures/binary-tree/tree-multiset.js +176 -253
- package/dist/data-structures/binary-tree/two-three-tree.js +2 -5
- package/dist/data-structures/graph/abstract-graph.js +340 -574
- package/dist/data-structures/graph/directed-graph.js +146 -276
- package/dist/data-structures/graph/undirected-graph.js +87 -176
- package/dist/data-structures/hash/coordinate-map.js +23 -45
- package/dist/data-structures/hash/coordinate-set.js +20 -42
- package/dist/data-structures/hash/hash-table.js +2 -5
- package/dist/data-structures/hash/pair.js +2 -5
- package/dist/data-structures/hash/tree-map.js +2 -5
- package/dist/data-structures/hash/tree-set.js +2 -5
- package/dist/data-structures/heap/heap.js +53 -77
- package/dist/data-structures/heap/max-heap.js +8 -26
- package/dist/data-structures/heap/min-heap.js +8 -26
- package/dist/data-structures/linked-list/doubly-linked-list.js +132 -197
- package/dist/data-structures/linked-list/singly-linked-list.js +112 -173
- package/dist/data-structures/linked-list/skip-linked-list.js +2 -5
- package/dist/data-structures/matrix/matrix.js +7 -8
- package/dist/data-structures/matrix/matrix2d.js +76 -93
- package/dist/data-structures/matrix/navigator.js +18 -37
- package/dist/data-structures/matrix/vector2d.js +80 -101
- package/dist/data-structures/priority-queue/max-priority-queue.js +11 -39
- package/dist/data-structures/priority-queue/min-priority-queue.js +11 -39
- package/dist/data-structures/priority-queue/priority-queue.js +93 -139
- package/dist/data-structures/queue/deque.js +82 -128
- package/dist/data-structures/queue/queue.js +24 -25
- package/dist/data-structures/stack/stack.js +21 -22
- package/dist/data-structures/tree/tree.js +32 -45
- package/dist/data-structures/trie/trie.js +93 -200
- package/dist/utils/utils.js +22 -107
- package/dist/utils/validate-type.js +2 -2
- package/package.json +1 -1
- package/src/assets/complexities-diff.jpg +0 -0
- package/src/assets/data-structure-complexities.jpg +0 -0
- package/src/assets/logo.png +0 -0
- package/src/assets/overview-diagram-of-data-structures.png +0 -0
- package/src/data-structures/binary-tree/aa-tree.ts +3 -0
- package/src/data-structures/binary-tree/abstract-binary-tree.ts +1528 -0
- package/src/data-structures/binary-tree/avl-tree.ts +297 -0
- package/src/data-structures/binary-tree/b-tree.ts +3 -0
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +78 -0
- package/src/data-structures/binary-tree/binary-tree.ts +40 -0
- package/src/data-structures/binary-tree/bst.ts +435 -0
- package/src/data-structures/binary-tree/diagrams/avl-tree-inserting.gif +0 -0
- package/src/data-structures/binary-tree/diagrams/bst-rotation.gif +0 -0
- package/src/data-structures/binary-tree/diagrams/segment-tree.png +0 -0
- package/src/data-structures/binary-tree/index.ts +12 -0
- package/src/data-structures/binary-tree/rb-tree.ts +102 -0
- package/src/data-structures/binary-tree/segment-tree.ts +243 -0
- package/src/data-structures/binary-tree/splay-tree.ts +3 -0
- package/src/data-structures/binary-tree/tree-multiset.ts +694 -0
- package/src/data-structures/binary-tree/two-three-tree.ts +3 -0
- package/src/data-structures/diagrams/README.md +5 -0
- package/src/data-structures/graph/abstract-graph.ts +1032 -0
- package/src/data-structures/graph/diagrams/adjacency-list-pros-cons.jpg +0 -0
- package/src/data-structures/graph/diagrams/adjacency-list.jpg +0 -0
- package/src/data-structures/graph/diagrams/adjacency-matrix-pros-cons.jpg +0 -0
- package/src/data-structures/graph/diagrams/adjacency-matrix.jpg +0 -0
- package/src/data-structures/graph/diagrams/dfs-can-do.jpg +0 -0
- package/src/data-structures/graph/diagrams/edge-list-pros-cons.jpg +0 -0
- package/src/data-structures/graph/diagrams/edge-list.jpg +0 -0
- package/src/data-structures/graph/diagrams/max-flow.jpg +0 -0
- package/src/data-structures/graph/diagrams/mst.jpg +0 -0
- package/src/data-structures/graph/diagrams/tarjan-articulation-point-bridge.png +0 -0
- package/src/data-structures/graph/diagrams/tarjan-complicate-simple.png +0 -0
- package/src/data-structures/graph/diagrams/tarjan-strongly-connected-component.png +0 -0
- package/src/data-structures/graph/diagrams/tarjan.mp4 +0 -0
- package/src/data-structures/graph/diagrams/tarjan.webp +0 -0
- package/src/data-structures/graph/directed-graph.ts +472 -0
- package/src/data-structures/graph/index.ts +3 -0
- package/src/data-structures/graph/undirected-graph.ts +270 -0
- package/src/data-structures/hash/coordinate-map.ts +67 -0
- package/src/data-structures/hash/coordinate-set.ts +56 -0
- package/src/data-structures/hash/hash-table.ts +3 -0
- package/src/data-structures/hash/index.ts +6 -0
- package/src/data-structures/hash/pair.ts +3 -0
- package/src/data-structures/hash/tree-map.ts +3 -0
- package/src/data-structures/hash/tree-set.ts +3 -0
- package/src/data-structures/heap/heap.ts +183 -0
- package/src/data-structures/heap/index.ts +3 -0
- package/src/data-structures/heap/max-heap.ts +31 -0
- package/src/data-structures/heap/min-heap.ts +34 -0
- package/src/data-structures/index.ts +15 -0
- package/src/data-structures/interfaces/abstract-binary-tree.ts +231 -0
- package/src/data-structures/interfaces/abstract-graph.ts +40 -0
- package/src/data-structures/interfaces/avl-tree.ts +28 -0
- package/src/data-structures/interfaces/binary-tree.ts +8 -0
- package/src/data-structures/interfaces/bst.ts +32 -0
- package/src/data-structures/interfaces/directed-graph.ts +20 -0
- package/src/data-structures/interfaces/doubly-linked-list.ts +1 -0
- package/src/data-structures/interfaces/heap.ts +1 -0
- package/src/data-structures/interfaces/index.ts +15 -0
- package/src/data-structures/interfaces/navigator.ts +1 -0
- package/src/data-structures/interfaces/priority-queue.ts +1 -0
- package/src/data-structures/interfaces/rb-tree.ts +11 -0
- package/src/data-structures/interfaces/segment-tree.ts +1 -0
- package/src/data-structures/interfaces/singly-linked-list.ts +1 -0
- package/src/data-structures/interfaces/tree-multiset.ts +12 -0
- package/src/data-structures/interfaces/undirected-graph.ts +6 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +573 -0
- package/src/data-structures/linked-list/index.ts +3 -0
- package/src/data-structures/linked-list/singly-linked-list.ts +490 -0
- package/src/data-structures/linked-list/skip-linked-list.ts +3 -0
- package/src/data-structures/matrix/index.ts +4 -0
- package/src/data-structures/matrix/matrix.ts +27 -0
- package/src/data-structures/matrix/matrix2d.ts +208 -0
- package/src/data-structures/matrix/navigator.ts +122 -0
- package/src/data-structures/matrix/vector2d.ts +316 -0
- package/src/data-structures/priority-queue/index.ts +3 -0
- package/src/data-structures/priority-queue/max-priority-queue.ts +49 -0
- package/src/data-structures/priority-queue/min-priority-queue.ts +50 -0
- package/src/data-structures/priority-queue/priority-queue.ts +354 -0
- package/src/data-structures/queue/deque.ts +251 -0
- package/src/data-structures/queue/index.ts +2 -0
- package/src/data-structures/queue/queue.ts +120 -0
- package/src/data-structures/stack/index.ts +1 -0
- package/src/data-structures/stack/stack.ts +98 -0
- package/src/data-structures/tree/index.ts +1 -0
- package/src/data-structures/tree/tree.ts +69 -0
- package/src/data-structures/trie/index.ts +1 -0
- package/src/data-structures/trie/trie.ts +227 -0
- package/src/data-structures/types/abstract-binary-tree.ts +42 -0
- package/src/data-structures/types/abstract-graph.ts +5 -0
- package/src/data-structures/types/avl-tree.ts +5 -0
- package/src/data-structures/types/binary-tree.ts +9 -0
- package/src/data-structures/types/bst.ts +12 -0
- package/src/data-structures/types/directed-graph.ts +8 -0
- package/src/data-structures/types/doubly-linked-list.ts +1 -0
- package/src/data-structures/types/heap.ts +5 -0
- package/src/data-structures/types/helpers.ts +1 -0
- package/src/data-structures/types/index.ts +15 -0
- package/src/data-structures/types/navigator.ts +13 -0
- package/src/data-structures/types/priority-queue.ts +9 -0
- package/src/data-structures/types/rb-tree.ts +8 -0
- package/src/data-structures/types/segment-tree.ts +1 -0
- package/src/data-structures/types/singly-linked-list.ts +1 -0
- package/src/data-structures/types/tree-multiset.ts +8 -0
- package/src/index.ts +2 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/types/index.ts +2 -0
- package/src/utils/types/utils.ts +6 -0
- package/src/utils/types/validate-type.ts +25 -0
- package/src/utils/utils.ts +78 -0
- package/src/utils/validate-type.ts +69 -0
- package/tsconfig.json +1 -1
|
@@ -6,38 +6,11 @@
|
|
|
6
6
|
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
7
7
|
* @license MIT License
|
|
8
8
|
*/
|
|
9
|
-
var __values = (this && this.__values) || function(o) {
|
|
10
|
-
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
11
|
-
if (m) return m.call(o);
|
|
12
|
-
if (o && typeof o.length === "number") return {
|
|
13
|
-
next: function () {
|
|
14
|
-
if (o && i >= o.length) o = void 0;
|
|
15
|
-
return { value: o && o[i++], done: !o };
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
19
|
-
};
|
|
20
|
-
var __read = (this && this.__read) || function (o, n) {
|
|
21
|
-
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
22
|
-
if (!m) return o;
|
|
23
|
-
var i = m.call(o), r, ar = [], e;
|
|
24
|
-
try {
|
|
25
|
-
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
26
|
-
}
|
|
27
|
-
catch (error) { e = { error: error }; }
|
|
28
|
-
finally {
|
|
29
|
-
try {
|
|
30
|
-
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
31
|
-
}
|
|
32
|
-
finally { if (e) throw e.error; }
|
|
33
|
-
}
|
|
34
|
-
return ar;
|
|
35
|
-
};
|
|
36
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
10
|
exports.AbstractBinaryTree = exports.AbstractBinaryTreeNode = void 0;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
11
|
+
const utils_1 = require("../../utils");
|
|
12
|
+
const types_1 = require("../types");
|
|
13
|
+
class AbstractBinaryTreeNode {
|
|
41
14
|
/**
|
|
42
15
|
* The constructor function initializes a BinaryTreeNode object with an id and an optional value.
|
|
43
16
|
* @param {BinaryTreeNodeId} id - The `id` parameter is of type `BinaryTreeNodeId` and represents the unique identifier
|
|
@@ -45,127 +18,98 @@ var AbstractBinaryTreeNode = /** @class */ (function () {
|
|
|
45
18
|
* @param {T} [val] - The "val" parameter is an optional parameter of type T. It represents the value that will be
|
|
46
19
|
* stored in the binary tree node. If no value is provided, it will be set to undefined.
|
|
47
20
|
*/
|
|
48
|
-
|
|
21
|
+
constructor(id, val) {
|
|
49
22
|
this._height = 0;
|
|
50
23
|
this._id = id;
|
|
51
24
|
this._val = val;
|
|
52
25
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
},
|
|
106
|
-
enumerable: false,
|
|
107
|
-
configurable: true
|
|
108
|
-
});
|
|
109
|
-
Object.defineProperty(AbstractBinaryTreeNode.prototype, "height", {
|
|
110
|
-
get: function () {
|
|
111
|
-
return this._height;
|
|
112
|
-
},
|
|
113
|
-
set: function (v) {
|
|
114
|
-
this._height = v;
|
|
115
|
-
},
|
|
116
|
-
enumerable: false,
|
|
117
|
-
configurable: true
|
|
118
|
-
});
|
|
119
|
-
Object.defineProperty(AbstractBinaryTreeNode.prototype, "familyPosition", {
|
|
120
|
-
/**
|
|
121
|
-
* The function determines the position of a node in a family tree structure.
|
|
122
|
-
* @returns a value of type `FamilyPosition`.
|
|
123
|
-
*/
|
|
124
|
-
get: function () {
|
|
125
|
-
var that = this;
|
|
126
|
-
if (that.parent) {
|
|
127
|
-
if (that.parent.left === that) {
|
|
128
|
-
if (that.left || that.right) {
|
|
129
|
-
return types_1.FamilyPosition.ROOT_LEFT;
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
return types_1.FamilyPosition.LEFT;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
else if (that.parent.right === that) {
|
|
136
|
-
if (that.left || that.right) {
|
|
137
|
-
return types_1.FamilyPosition.ROOT_RIGHT;
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
return types_1.FamilyPosition.RIGHT;
|
|
141
|
-
}
|
|
26
|
+
get id() {
|
|
27
|
+
return this._id;
|
|
28
|
+
}
|
|
29
|
+
set id(v) {
|
|
30
|
+
this._id = v;
|
|
31
|
+
}
|
|
32
|
+
get val() {
|
|
33
|
+
return this._val;
|
|
34
|
+
}
|
|
35
|
+
set val(value) {
|
|
36
|
+
this._val = value;
|
|
37
|
+
}
|
|
38
|
+
get left() {
|
|
39
|
+
return this._left;
|
|
40
|
+
}
|
|
41
|
+
set left(v) {
|
|
42
|
+
if (v) {
|
|
43
|
+
v.parent = this;
|
|
44
|
+
}
|
|
45
|
+
this._left = v;
|
|
46
|
+
}
|
|
47
|
+
get right() {
|
|
48
|
+
return this._right;
|
|
49
|
+
}
|
|
50
|
+
set right(v) {
|
|
51
|
+
if (v) {
|
|
52
|
+
v.parent = this;
|
|
53
|
+
}
|
|
54
|
+
this._right = v;
|
|
55
|
+
}
|
|
56
|
+
get parent() {
|
|
57
|
+
return this._parent;
|
|
58
|
+
}
|
|
59
|
+
set parent(v) {
|
|
60
|
+
this._parent = v;
|
|
61
|
+
}
|
|
62
|
+
get height() {
|
|
63
|
+
return this._height;
|
|
64
|
+
}
|
|
65
|
+
set height(v) {
|
|
66
|
+
this._height = v;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The function determines the position of a node in a family tree structure.
|
|
70
|
+
* @returns a value of type `FamilyPosition`.
|
|
71
|
+
*/
|
|
72
|
+
get familyPosition() {
|
|
73
|
+
const that = this;
|
|
74
|
+
if (that.parent) {
|
|
75
|
+
if (that.parent.left === that) {
|
|
76
|
+
if (that.left || that.right) {
|
|
77
|
+
return types_1.FamilyPosition.ROOT_LEFT;
|
|
142
78
|
}
|
|
143
79
|
else {
|
|
144
|
-
return types_1.FamilyPosition.
|
|
80
|
+
return types_1.FamilyPosition.LEFT;
|
|
145
81
|
}
|
|
146
82
|
}
|
|
147
|
-
else {
|
|
83
|
+
else if (that.parent.right === that) {
|
|
148
84
|
if (that.left || that.right) {
|
|
149
|
-
return types_1.FamilyPosition.
|
|
85
|
+
return types_1.FamilyPosition.ROOT_RIGHT;
|
|
150
86
|
}
|
|
151
87
|
else {
|
|
152
|
-
return types_1.FamilyPosition.
|
|
88
|
+
return types_1.FamilyPosition.RIGHT;
|
|
153
89
|
}
|
|
154
90
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
91
|
+
else {
|
|
92
|
+
return types_1.FamilyPosition.MAL_NODE;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
if (that.left || that.right) {
|
|
97
|
+
return types_1.FamilyPosition.ROOT;
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
return types_1.FamilyPosition.ISOLATED;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
161
105
|
exports.AbstractBinaryTreeNode = AbstractBinaryTreeNode;
|
|
162
|
-
|
|
106
|
+
class AbstractBinaryTree {
|
|
163
107
|
/**
|
|
164
108
|
* The protected constructor initializes the options for an abstract binary tree.
|
|
165
109
|
* @param {AbstractBinaryTreeOptions} [options] - An optional object that contains configuration options for the binary
|
|
166
110
|
* tree.
|
|
167
111
|
*/
|
|
168
|
-
|
|
112
|
+
constructor(options) {
|
|
169
113
|
this._root = null;
|
|
170
114
|
this._size = 0;
|
|
171
115
|
this._loopType = types_1.LoopType.ITERATIVE;
|
|
@@ -179,89 +123,45 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
179
123
|
this._visitedCount = [];
|
|
180
124
|
this._visitedLeftSum = [];
|
|
181
125
|
if (options !== undefined) {
|
|
182
|
-
|
|
126
|
+
const { loopType = types_1.LoopType.ITERATIVE, autoIncrementId = false, isMergeDuplicatedVal = true } = options;
|
|
183
127
|
this._isMergeDuplicatedVal = isMergeDuplicatedVal;
|
|
184
128
|
this._autoIncrementId = autoIncrementId;
|
|
185
129
|
this._loopType = loopType;
|
|
186
130
|
}
|
|
187
131
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
configurable: true
|
|
222
|
-
});
|
|
223
|
-
Object.defineProperty(AbstractBinaryTree.prototype, "isMergeDuplicatedVal", {
|
|
224
|
-
get: function () {
|
|
225
|
-
return this._isMergeDuplicatedVal;
|
|
226
|
-
},
|
|
227
|
-
enumerable: false,
|
|
228
|
-
configurable: true
|
|
229
|
-
});
|
|
230
|
-
Object.defineProperty(AbstractBinaryTree.prototype, "visitedId", {
|
|
231
|
-
get: function () {
|
|
232
|
-
return this._visitedId;
|
|
233
|
-
},
|
|
234
|
-
enumerable: false,
|
|
235
|
-
configurable: true
|
|
236
|
-
});
|
|
237
|
-
Object.defineProperty(AbstractBinaryTree.prototype, "visitedVal", {
|
|
238
|
-
get: function () {
|
|
239
|
-
return this._visitedVal;
|
|
240
|
-
},
|
|
241
|
-
enumerable: false,
|
|
242
|
-
configurable: true
|
|
243
|
-
});
|
|
244
|
-
Object.defineProperty(AbstractBinaryTree.prototype, "visitedNode", {
|
|
245
|
-
get: function () {
|
|
246
|
-
return this._visitedNode;
|
|
247
|
-
},
|
|
248
|
-
enumerable: false,
|
|
249
|
-
configurable: true
|
|
250
|
-
});
|
|
251
|
-
Object.defineProperty(AbstractBinaryTree.prototype, "visitedCount", {
|
|
252
|
-
get: function () {
|
|
253
|
-
return this._visitedCount;
|
|
254
|
-
},
|
|
255
|
-
enumerable: false,
|
|
256
|
-
configurable: true
|
|
257
|
-
});
|
|
258
|
-
Object.defineProperty(AbstractBinaryTree.prototype, "visitedLeftSum", {
|
|
259
|
-
get: function () {
|
|
260
|
-
return this._visitedLeftSum;
|
|
261
|
-
},
|
|
262
|
-
enumerable: false,
|
|
263
|
-
configurable: true
|
|
264
|
-
});
|
|
132
|
+
get root() {
|
|
133
|
+
return this._root;
|
|
134
|
+
}
|
|
135
|
+
get size() {
|
|
136
|
+
return this._size;
|
|
137
|
+
}
|
|
138
|
+
get loopType() {
|
|
139
|
+
return this._loopType;
|
|
140
|
+
}
|
|
141
|
+
get autoIncrementId() {
|
|
142
|
+
return this._autoIncrementId;
|
|
143
|
+
}
|
|
144
|
+
get maxId() {
|
|
145
|
+
return this._maxId;
|
|
146
|
+
}
|
|
147
|
+
get isMergeDuplicatedVal() {
|
|
148
|
+
return this._isMergeDuplicatedVal;
|
|
149
|
+
}
|
|
150
|
+
get visitedId() {
|
|
151
|
+
return this._visitedId;
|
|
152
|
+
}
|
|
153
|
+
get visitedVal() {
|
|
154
|
+
return this._visitedVal;
|
|
155
|
+
}
|
|
156
|
+
get visitedNode() {
|
|
157
|
+
return this._visitedNode;
|
|
158
|
+
}
|
|
159
|
+
get visitedCount() {
|
|
160
|
+
return this._visitedCount;
|
|
161
|
+
}
|
|
162
|
+
get visitedLeftSum() {
|
|
163
|
+
return this._visitedLeftSum;
|
|
164
|
+
}
|
|
265
165
|
/**
|
|
266
166
|
* The `swapLocation` function swaps the location of two nodes in a binary tree.
|
|
267
167
|
* @param {N} srcNode - The source node that you want to swap with the destination node.
|
|
@@ -269,9 +169,9 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
269
169
|
* be swapped to.
|
|
270
170
|
* @returns The `destNode` is being returned.
|
|
271
171
|
*/
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
172
|
+
swapLocation(srcNode, destNode) {
|
|
173
|
+
const { val, height, id } = destNode;
|
|
174
|
+
const tempNode = this.createNode(id, val);
|
|
275
175
|
if (tempNode) {
|
|
276
176
|
tempNode.height = height;
|
|
277
177
|
if (tempNode instanceof AbstractBinaryTreeNode) {
|
|
@@ -285,22 +185,22 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
285
185
|
}
|
|
286
186
|
}
|
|
287
187
|
return destNode;
|
|
288
|
-
}
|
|
188
|
+
}
|
|
289
189
|
/**
|
|
290
190
|
* The clear() function resets the root, size, and maxId properties to their initial values.
|
|
291
191
|
*/
|
|
292
|
-
|
|
192
|
+
clear() {
|
|
293
193
|
this._setRoot(null);
|
|
294
194
|
this._setSize(0);
|
|
295
195
|
this._setMaxId(-1);
|
|
296
|
-
}
|
|
196
|
+
}
|
|
297
197
|
/**
|
|
298
198
|
* The function checks if the size of an object is equal to zero and returns a boolean value.
|
|
299
199
|
* @returns A boolean value indicating whether the size of the object is 0 or not.
|
|
300
200
|
*/
|
|
301
|
-
|
|
201
|
+
isEmpty() {
|
|
302
202
|
return this.size === 0;
|
|
303
|
-
}
|
|
203
|
+
}
|
|
304
204
|
/**
|
|
305
205
|
* The `add` function adds a new node to a binary tree, updating the value of an existing node if it already exists.
|
|
306
206
|
* @param {BinaryTreeNodeId} id - The `id` parameter is the identifier of the binary tree node that you want to add.
|
|
@@ -310,16 +210,15 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
310
210
|
* should be added to the binary tree. If not provided, the default value is `undefined`.
|
|
311
211
|
* @returns The function `add` returns either a `BinaryTreeNode` object (`N`), `null`, or `undefined`.
|
|
312
212
|
*/
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
var queue = [root];
|
|
213
|
+
add(id, val, count) {
|
|
214
|
+
const _bfs = (root, newNode) => {
|
|
215
|
+
const queue = [root];
|
|
317
216
|
while (queue.length > 0) {
|
|
318
|
-
|
|
217
|
+
const cur = queue.shift();
|
|
319
218
|
if (cur) {
|
|
320
|
-
|
|
321
|
-
if (
|
|
322
|
-
return
|
|
219
|
+
const inserted = this.addTo(newNode, cur);
|
|
220
|
+
if (inserted !== undefined)
|
|
221
|
+
return inserted;
|
|
323
222
|
if (cur.left)
|
|
324
223
|
queue.push(cur.left);
|
|
325
224
|
if (cur.right)
|
|
@@ -330,9 +229,9 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
330
229
|
}
|
|
331
230
|
return;
|
|
332
231
|
};
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
232
|
+
let inserted;
|
|
233
|
+
const needInsert = val !== null ? this.createNode(id, val) : null;
|
|
234
|
+
const existNode = val !== null ? this.get(id, 'id') : null;
|
|
336
235
|
if (this.root) {
|
|
337
236
|
if (existNode) {
|
|
338
237
|
existNode.val = val !== null && val !== void 0 ? val : id;
|
|
@@ -352,7 +251,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
352
251
|
inserted = this.root;
|
|
353
252
|
}
|
|
354
253
|
return inserted;
|
|
355
|
-
}
|
|
254
|
+
}
|
|
356
255
|
/**
|
|
357
256
|
* The function adds a new node to the left or right child of a parent node, updating the size of the tree if
|
|
358
257
|
* necessary.
|
|
@@ -362,7 +261,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
362
261
|
* child.
|
|
363
262
|
* @returns either the left child node, the right child node, or undefined.
|
|
364
263
|
*/
|
|
365
|
-
|
|
264
|
+
addTo(newNode, parent) {
|
|
366
265
|
if (parent) {
|
|
367
266
|
if (parent.left === undefined) {
|
|
368
267
|
if (newNode) {
|
|
@@ -391,7 +290,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
391
290
|
else {
|
|
392
291
|
return;
|
|
393
292
|
}
|
|
394
|
-
}
|
|
293
|
+
}
|
|
395
294
|
/**
|
|
396
295
|
* The `addMany` function adds multiple nodes to a binary tree and returns an array of the inserted nodes or
|
|
397
296
|
* null/undefined values.
|
|
@@ -399,83 +298,61 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
399
298
|
* `N['val']` values.
|
|
400
299
|
* @returns The function `addMany` returns an array of values of type `N | null | undefined`.
|
|
401
300
|
*/
|
|
402
|
-
|
|
403
|
-
var
|
|
404
|
-
var _c;
|
|
301
|
+
addMany(data) {
|
|
302
|
+
var _a;
|
|
405
303
|
// TODO not sure addMany not be run multi times
|
|
406
|
-
|
|
407
|
-
|
|
304
|
+
const inserted = [];
|
|
305
|
+
const map = new Map();
|
|
408
306
|
if (this.isMergeDuplicatedVal) {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
307
|
+
for (const nodeOrId of data)
|
|
308
|
+
map.set(nodeOrId, ((_a = map.get(nodeOrId)) !== null && _a !== void 0 ? _a : 0) + 1);
|
|
309
|
+
}
|
|
310
|
+
for (const nodeOrId of data) {
|
|
311
|
+
if (nodeOrId instanceof AbstractBinaryTreeNode) {
|
|
312
|
+
inserted.push(this.add(nodeOrId.id, nodeOrId.val));
|
|
313
|
+
continue;
|
|
414
314
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
if (data_1_1 && !data_1_1.done && (_a = data_1.return)) _a.call(data_1);
|
|
419
|
-
}
|
|
420
|
-
finally { if (e_1) throw e_1.error; }
|
|
315
|
+
if (nodeOrId === null) {
|
|
316
|
+
inserted.push(this.add(NaN, null, 0));
|
|
317
|
+
continue;
|
|
421
318
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
inserted.push(this.add(NaN, null, 0));
|
|
432
|
-
continue;
|
|
433
|
-
}
|
|
434
|
-
// TODO will this cause an issue?
|
|
435
|
-
var count = this.isMergeDuplicatedVal ? map.get(nodeOrId) : 1;
|
|
436
|
-
var newId = void 0;
|
|
437
|
-
if (typeof nodeOrId === 'number') {
|
|
438
|
-
newId = this.autoIncrementId ? this.maxId + 1 : nodeOrId;
|
|
319
|
+
// TODO will this cause an issue?
|
|
320
|
+
const count = this.isMergeDuplicatedVal ? map.get(nodeOrId) : 1;
|
|
321
|
+
let newId;
|
|
322
|
+
if (typeof nodeOrId === 'number') {
|
|
323
|
+
newId = this.autoIncrementId ? this.maxId + 1 : nodeOrId;
|
|
324
|
+
}
|
|
325
|
+
else if (nodeOrId instanceof Object) {
|
|
326
|
+
if (this.autoIncrementId) {
|
|
327
|
+
newId = this.maxId + 1;
|
|
439
328
|
}
|
|
440
|
-
else
|
|
441
|
-
if (
|
|
442
|
-
newId =
|
|
329
|
+
else {
|
|
330
|
+
if (Object.keys(nodeOrId).includes('id')) {
|
|
331
|
+
newId = nodeOrId.id;
|
|
443
332
|
}
|
|
444
333
|
else {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
}
|
|
448
|
-
else {
|
|
449
|
-
console.warn(nodeOrId, 'Object value must has an id property when the autoIncrementId is false');
|
|
450
|
-
continue;
|
|
451
|
-
}
|
|
334
|
+
console.warn(nodeOrId, 'Object value must has an id property when the autoIncrementId is false');
|
|
335
|
+
continue;
|
|
452
336
|
}
|
|
453
337
|
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
}
|
|
464
|
-
else {
|
|
465
|
-
inserted.push(this.add(newId, nodeOrId, 1));
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
console.warn(nodeOrId, ` is not added`);
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
if (this.isMergeDuplicatedVal) {
|
|
344
|
+
if (map.has(nodeOrId)) {
|
|
345
|
+
inserted.push(this.add(newId, nodeOrId, count));
|
|
346
|
+
map.delete(nodeOrId);
|
|
466
347
|
}
|
|
467
|
-
this._setMaxId(newId);
|
|
468
348
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
finally {
|
|
472
|
-
try {
|
|
473
|
-
if (data_2_1 && !data_2_1.done && (_b = data_2.return)) _b.call(data_2);
|
|
349
|
+
else {
|
|
350
|
+
inserted.push(this.add(newId, nodeOrId, 1));
|
|
474
351
|
}
|
|
475
|
-
|
|
352
|
+
this._setMaxId(newId);
|
|
476
353
|
}
|
|
477
354
|
return inserted;
|
|
478
|
-
}
|
|
355
|
+
}
|
|
479
356
|
/**
|
|
480
357
|
* The `fill` function clears the current data and adds new data, returning a boolean indicating if the operation was
|
|
481
358
|
* successful.
|
|
@@ -483,10 +360,10 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
483
360
|
* Each object or array should have a property called `val`.
|
|
484
361
|
* @returns a boolean value.
|
|
485
362
|
*/
|
|
486
|
-
|
|
363
|
+
fill(data) {
|
|
487
364
|
this.clear();
|
|
488
365
|
return data.length === this.addMany(data).length;
|
|
489
|
-
}
|
|
366
|
+
}
|
|
490
367
|
/**
|
|
491
368
|
* The `remove` function removes a node from a binary search tree and returns the deleted node along with the parent
|
|
492
369
|
* node that needs to be balanced.
|
|
@@ -497,22 +374,22 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
497
374
|
* nodes in the binary tree will not be updated after removing a node. If `ignoreCount`
|
|
498
375
|
* @returns The function `remove` returns an array of `BinaryTreeDeletedResult<N>` objects.
|
|
499
376
|
*/
|
|
500
|
-
|
|
501
|
-
|
|
377
|
+
remove(nodeOrId, ignoreCount) {
|
|
378
|
+
const bstDeletedResult = [];
|
|
502
379
|
if (!this.root)
|
|
503
380
|
return bstDeletedResult;
|
|
504
|
-
|
|
381
|
+
const curr = (typeof nodeOrId === 'number') ? this.get(nodeOrId) : nodeOrId;
|
|
505
382
|
if (!curr)
|
|
506
383
|
return bstDeletedResult;
|
|
507
|
-
|
|
508
|
-
|
|
384
|
+
const parent = (curr === null || curr === void 0 ? void 0 : curr.parent) ? curr.parent : null;
|
|
385
|
+
let needBalanced = null, orgCurrent = curr;
|
|
509
386
|
if (!curr.left) {
|
|
510
387
|
if (!parent) {
|
|
511
388
|
if (curr.right !== undefined)
|
|
512
389
|
this._setRoot(curr.right);
|
|
513
390
|
}
|
|
514
391
|
else {
|
|
515
|
-
|
|
392
|
+
const { familyPosition: fp } = curr;
|
|
516
393
|
if (fp === types_1.FamilyPosition.LEFT || fp === types_1.FamilyPosition.ROOT_LEFT) {
|
|
517
394
|
parent.left = curr.right;
|
|
518
395
|
}
|
|
@@ -523,9 +400,9 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
523
400
|
}
|
|
524
401
|
}
|
|
525
402
|
else {
|
|
526
|
-
|
|
403
|
+
const leftSubTreeRightMost = curr.left ? this.getRightMost(curr.left) : null;
|
|
527
404
|
if (leftSubTreeRightMost) {
|
|
528
|
-
|
|
405
|
+
const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
|
|
529
406
|
orgCurrent = this.swapLocation(curr, leftSubTreeRightMost);
|
|
530
407
|
if (parentOfLeftSubTreeMax) {
|
|
531
408
|
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
|
|
@@ -537,24 +414,24 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
537
414
|
}
|
|
538
415
|
}
|
|
539
416
|
this._setSize(this.size - 1);
|
|
540
|
-
bstDeletedResult.push({ deleted: orgCurrent, needBalanced
|
|
417
|
+
bstDeletedResult.push({ deleted: orgCurrent, needBalanced });
|
|
541
418
|
return bstDeletedResult;
|
|
542
|
-
}
|
|
419
|
+
}
|
|
543
420
|
/**
|
|
544
421
|
* The function calculates the depth of a node in a binary tree.
|
|
545
422
|
* @param {N | BinaryTreeNodeId | null} beginRoot - The `beginRoot` parameter can be one of the following:
|
|
546
423
|
* @returns the depth of the given node or binary tree.
|
|
547
424
|
*/
|
|
548
|
-
|
|
425
|
+
getDepth(beginRoot) {
|
|
549
426
|
if (typeof beginRoot === 'number')
|
|
550
427
|
beginRoot = this.get(beginRoot, 'id');
|
|
551
|
-
|
|
428
|
+
let depth = 0;
|
|
552
429
|
while (beginRoot === null || beginRoot === void 0 ? void 0 : beginRoot.parent) {
|
|
553
430
|
depth++;
|
|
554
431
|
beginRoot = beginRoot.parent;
|
|
555
432
|
}
|
|
556
433
|
return depth;
|
|
557
|
-
}
|
|
434
|
+
}
|
|
558
435
|
/**
|
|
559
436
|
* The `getHeight` function calculates the maximum height of a binary tree, either recursively or iteratively.
|
|
560
437
|
* @param {N | BinaryTreeNodeId | null} [beginRoot] - The `beginRoot` parameter is optional and can be of type `N` (a
|
|
@@ -562,30 +439,30 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
562
439
|
* node), or `null`.
|
|
563
440
|
* @returns the height of the binary tree.
|
|
564
441
|
*/
|
|
565
|
-
|
|
442
|
+
getHeight(beginRoot) {
|
|
566
443
|
beginRoot = beginRoot !== null && beginRoot !== void 0 ? beginRoot : this.root;
|
|
567
444
|
if (typeof beginRoot === 'number')
|
|
568
445
|
beginRoot = this.get(beginRoot, 'id');
|
|
569
446
|
if (!beginRoot)
|
|
570
447
|
return -1;
|
|
571
448
|
if (this._loopType === types_1.LoopType.RECURSIVE) {
|
|
572
|
-
|
|
449
|
+
const _getMaxHeight = (cur) => {
|
|
573
450
|
if (!cur)
|
|
574
451
|
return -1;
|
|
575
|
-
|
|
576
|
-
|
|
452
|
+
const leftHeight = _getMaxHeight(cur.left);
|
|
453
|
+
const rightHeight = _getMaxHeight(cur.right);
|
|
577
454
|
return Math.max(leftHeight, rightHeight) + 1;
|
|
578
455
|
};
|
|
579
|
-
return
|
|
456
|
+
return _getMaxHeight(beginRoot);
|
|
580
457
|
}
|
|
581
458
|
else {
|
|
582
459
|
if (!beginRoot) {
|
|
583
460
|
return -1;
|
|
584
461
|
}
|
|
585
|
-
|
|
586
|
-
|
|
462
|
+
const stack = [{ node: beginRoot, depth: 0 }];
|
|
463
|
+
let maxHeight = 0;
|
|
587
464
|
while (stack.length > 0) {
|
|
588
|
-
|
|
465
|
+
const { node, depth } = stack.pop();
|
|
589
466
|
if (node.left) {
|
|
590
467
|
stack.push({ node: node.left, depth: depth + 1 });
|
|
591
468
|
}
|
|
@@ -596,7 +473,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
596
473
|
}
|
|
597
474
|
return maxHeight;
|
|
598
475
|
}
|
|
599
|
-
}
|
|
476
|
+
}
|
|
600
477
|
/**
|
|
601
478
|
* The `getMinHeight` function calculates the minimum height of a binary tree using either a recursive or iterative
|
|
602
479
|
* approach.
|
|
@@ -605,27 +482,27 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
605
482
|
* for `beginRoot`, the `this.root` property is used as the default value.
|
|
606
483
|
* @returns The function `getMinHeight` returns the minimum height of the binary tree.
|
|
607
484
|
*/
|
|
608
|
-
|
|
485
|
+
getMinHeight(beginRoot) {
|
|
609
486
|
var _a, _b, _c;
|
|
610
487
|
beginRoot = beginRoot || this.root;
|
|
611
488
|
if (!beginRoot)
|
|
612
489
|
return -1;
|
|
613
490
|
if (this._loopType === types_1.LoopType.RECURSIVE) {
|
|
614
|
-
|
|
491
|
+
const _getMinHeight = (cur) => {
|
|
615
492
|
if (!cur)
|
|
616
493
|
return 0;
|
|
617
494
|
if (!cur.left && !cur.right)
|
|
618
495
|
return 0;
|
|
619
|
-
|
|
620
|
-
|
|
496
|
+
const leftMinHeight = _getMinHeight(cur.left);
|
|
497
|
+
const rightMinHeight = _getMinHeight(cur.right);
|
|
621
498
|
return Math.min(leftMinHeight, rightMinHeight) + 1;
|
|
622
499
|
};
|
|
623
|
-
return
|
|
500
|
+
return _getMinHeight(beginRoot);
|
|
624
501
|
}
|
|
625
502
|
else {
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
503
|
+
const stack = [];
|
|
504
|
+
let node = beginRoot, last = null;
|
|
505
|
+
const depths = new Map();
|
|
629
506
|
while (stack.length > 0 || node) {
|
|
630
507
|
if (node) {
|
|
631
508
|
stack.push(node);
|
|
@@ -636,8 +513,8 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
636
513
|
if (!node.right || last === node.right) {
|
|
637
514
|
node = stack.pop();
|
|
638
515
|
if (node) {
|
|
639
|
-
|
|
640
|
-
|
|
516
|
+
const leftMinHeight = node.left ? (_a = depths.get(node.left)) !== null && _a !== void 0 ? _a : -1 : -1;
|
|
517
|
+
const rightMinHeight = node.right ? (_b = depths.get(node.right)) !== null && _b !== void 0 ? _b : -1 : -1;
|
|
641
518
|
depths.set(node, 1 + Math.min(leftMinHeight, rightMinHeight));
|
|
642
519
|
last = node;
|
|
643
520
|
node = null;
|
|
@@ -649,7 +526,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
649
526
|
}
|
|
650
527
|
return (_c = depths.get(beginRoot)) !== null && _c !== void 0 ? _c : -1;
|
|
651
528
|
}
|
|
652
|
-
}
|
|
529
|
+
}
|
|
653
530
|
/**
|
|
654
531
|
* The function checks if a binary tree is perfectly balanced by comparing the minimum height and the height of the
|
|
655
532
|
* tree.
|
|
@@ -657,9 +534,9 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
657
534
|
* tree or null if the tree is empty.
|
|
658
535
|
* @returns The method is returning a boolean value.
|
|
659
536
|
*/
|
|
660
|
-
|
|
537
|
+
isPerfectlyBalanced(beginRoot) {
|
|
661
538
|
return (this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot));
|
|
662
|
-
}
|
|
539
|
+
}
|
|
663
540
|
/**
|
|
664
541
|
* The function `getNodes` returns an array of nodes that match a given property name and value in a binary tree.
|
|
665
542
|
* @param {BinaryTreeNodeId | N} nodeProperty - The `nodeProperty` parameter can be either a `BinaryTreeNodeId` or a
|
|
@@ -671,27 +548,26 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
671
548
|
* function will stop traversing the tree and return the first matching node. If `only
|
|
672
549
|
* @returns an array of nodes (type N).
|
|
673
550
|
*/
|
|
674
|
-
|
|
675
|
-
var _this = this;
|
|
551
|
+
getNodes(nodeProperty, propertyName, onlyOne) {
|
|
676
552
|
if (!this.root)
|
|
677
553
|
return [];
|
|
678
554
|
propertyName = propertyName !== null && propertyName !== void 0 ? propertyName : 'id';
|
|
679
|
-
|
|
555
|
+
const result = [];
|
|
680
556
|
if (this.loopType === types_1.LoopType.RECURSIVE) {
|
|
681
|
-
|
|
682
|
-
if (
|
|
557
|
+
const _traverse = (cur) => {
|
|
558
|
+
if (this._pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne))
|
|
683
559
|
return;
|
|
684
560
|
if (!cur.left && !cur.right)
|
|
685
561
|
return;
|
|
686
|
-
cur.left &&
|
|
687
|
-
cur.right &&
|
|
562
|
+
cur.left && _traverse(cur.left);
|
|
563
|
+
cur.right && _traverse(cur.right);
|
|
688
564
|
};
|
|
689
|
-
|
|
565
|
+
_traverse(this.root);
|
|
690
566
|
}
|
|
691
567
|
else {
|
|
692
|
-
|
|
568
|
+
const queue = [this.root];
|
|
693
569
|
while (queue.length > 0) {
|
|
694
|
-
|
|
570
|
+
const cur = queue.shift();
|
|
695
571
|
if (cur) {
|
|
696
572
|
if (this._pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne))
|
|
697
573
|
return result;
|
|
@@ -701,7 +577,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
701
577
|
}
|
|
702
578
|
}
|
|
703
579
|
return result;
|
|
704
|
-
}
|
|
580
|
+
}
|
|
705
581
|
/**
|
|
706
582
|
* The function checks if a binary tree node has a specific property.
|
|
707
583
|
* @param {BinaryTreeNodeId | N} nodeProperty - The `nodeProperty` parameter can be either a `BinaryTreeNodeId` or `N`.
|
|
@@ -710,10 +586,10 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
710
586
|
* specifies the name of the property to be checked in the nodes. If not provided, it defaults to 'id'.
|
|
711
587
|
* @returns a boolean value.
|
|
712
588
|
*/
|
|
713
|
-
|
|
589
|
+
has(nodeProperty, propertyName) {
|
|
714
590
|
propertyName = propertyName !== null && propertyName !== void 0 ? propertyName : 'id';
|
|
715
591
|
return this.getNodes(nodeProperty, propertyName).length > 0;
|
|
716
|
-
}
|
|
592
|
+
}
|
|
717
593
|
/**
|
|
718
594
|
* The function returns the first node that matches the given property name and value, or null if no matching node is
|
|
719
595
|
* found.
|
|
@@ -725,26 +601,26 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
725
601
|
* @returns either the value of the specified property of the node, or the node itself if no property name is provided.
|
|
726
602
|
* If no matching node is found, it returns null.
|
|
727
603
|
*/
|
|
728
|
-
|
|
604
|
+
get(nodeProperty, propertyName) {
|
|
729
605
|
var _a;
|
|
730
606
|
propertyName = propertyName !== null && propertyName !== void 0 ? propertyName : 'id';
|
|
731
607
|
return (_a = this.getNodes(nodeProperty, propertyName, true)[0]) !== null && _a !== void 0 ? _a : null;
|
|
732
|
-
}
|
|
608
|
+
}
|
|
733
609
|
/**
|
|
734
610
|
* The function getPathToRoot takes a node and returns an array of nodes representing the path from the given node to
|
|
735
611
|
* the root node.
|
|
736
612
|
* @param {N} node - The parameter `node` represents a node in a tree data structure.
|
|
737
613
|
* @returns The function `getPathToRoot` returns an array of nodes (`N[]`).
|
|
738
614
|
*/
|
|
739
|
-
|
|
740
|
-
|
|
615
|
+
getPathToRoot(node) {
|
|
616
|
+
const result = [];
|
|
741
617
|
while (node.parent) {
|
|
742
618
|
result.unshift(node);
|
|
743
619
|
node = node.parent;
|
|
744
620
|
}
|
|
745
621
|
result.unshift(node);
|
|
746
622
|
return result;
|
|
747
|
-
}
|
|
623
|
+
}
|
|
748
624
|
/**
|
|
749
625
|
* The `getLeftMost` function returns the leftmost node in a binary tree, starting from a specified node or the root if
|
|
750
626
|
* no node is specified.
|
|
@@ -755,30 +631,30 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
755
631
|
* provided, it starts the traversal from that node. If `beginRoot` is not provided or is `null`, it starts the
|
|
756
632
|
* traversal from the root of the binary tree. If there are no nodes in the binary tree, it returns `null`.
|
|
757
633
|
*/
|
|
758
|
-
|
|
634
|
+
getLeftMost(beginRoot) {
|
|
759
635
|
if (typeof beginRoot === 'number')
|
|
760
636
|
beginRoot = this.get(beginRoot, 'id');
|
|
761
637
|
beginRoot = beginRoot !== null && beginRoot !== void 0 ? beginRoot : this.root;
|
|
762
638
|
if (!beginRoot)
|
|
763
639
|
return beginRoot;
|
|
764
640
|
if (this._loopType === types_1.LoopType.RECURSIVE) {
|
|
765
|
-
|
|
641
|
+
const _traverse = (cur) => {
|
|
766
642
|
if (!cur.left)
|
|
767
643
|
return cur;
|
|
768
|
-
return
|
|
644
|
+
return _traverse(cur.left);
|
|
769
645
|
};
|
|
770
|
-
return
|
|
646
|
+
return _traverse(beginRoot);
|
|
771
647
|
}
|
|
772
648
|
else {
|
|
773
649
|
// Indirect implementation of iteration using tail recursion optimization
|
|
774
|
-
|
|
650
|
+
const _traverse = (0, utils_1.trampoline)((cur) => {
|
|
775
651
|
if (!cur.left)
|
|
776
652
|
return cur;
|
|
777
|
-
return
|
|
653
|
+
return _traverse.cont(cur.left);
|
|
778
654
|
});
|
|
779
|
-
return
|
|
655
|
+
return _traverse(beginRoot);
|
|
780
656
|
}
|
|
781
|
-
}
|
|
657
|
+
}
|
|
782
658
|
/**
|
|
783
659
|
* The `getRightMost` function returns the rightmost node in a binary tree, either recursively or iteratively using
|
|
784
660
|
* tail recursion optimization.
|
|
@@ -789,50 +665,50 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
789
665
|
* not provided, it defaults to the root node of the tree. If the tree is empty or the `node` parameter is `null`, the
|
|
790
666
|
* function returns `null`.
|
|
791
667
|
*/
|
|
792
|
-
|
|
668
|
+
getRightMost(node) {
|
|
793
669
|
node = node !== null && node !== void 0 ? node : this.root;
|
|
794
670
|
if (!node)
|
|
795
671
|
return node;
|
|
796
672
|
if (this._loopType === types_1.LoopType.RECURSIVE) {
|
|
797
|
-
|
|
673
|
+
const _traverse = (cur) => {
|
|
798
674
|
if (!cur.right)
|
|
799
675
|
return cur;
|
|
800
|
-
return
|
|
676
|
+
return _traverse(cur.right);
|
|
801
677
|
};
|
|
802
|
-
return
|
|
678
|
+
return _traverse(node);
|
|
803
679
|
}
|
|
804
680
|
else {
|
|
805
681
|
// Indirect implementation of iteration using tail recursion optimization
|
|
806
|
-
|
|
682
|
+
const _traverse = (0, utils_1.trampoline)((cur) => {
|
|
807
683
|
if (!cur.right)
|
|
808
684
|
return cur;
|
|
809
|
-
return
|
|
685
|
+
return _traverse.cont(cur.right);
|
|
810
686
|
});
|
|
811
|
-
return
|
|
687
|
+
return _traverse(node);
|
|
812
688
|
}
|
|
813
|
-
}
|
|
689
|
+
}
|
|
814
690
|
/**
|
|
815
691
|
* The function checks if a binary search tree is valid by traversing it either recursively or iteratively.
|
|
816
692
|
* @param {N | null} node - The `node` parameter represents the root node of a binary search tree (BST).
|
|
817
693
|
* @returns a boolean value.
|
|
818
694
|
*/
|
|
819
|
-
|
|
695
|
+
isBSTByRooted(node) {
|
|
820
696
|
// TODO there is a bug
|
|
821
697
|
if (!node)
|
|
822
698
|
return true;
|
|
823
699
|
if (this._loopType === types_1.LoopType.RECURSIVE) {
|
|
824
|
-
|
|
700
|
+
const dfs = (cur, min, max) => {
|
|
825
701
|
if (!cur)
|
|
826
702
|
return true;
|
|
827
703
|
if (cur.id <= min || cur.id >= max)
|
|
828
704
|
return false;
|
|
829
|
-
return
|
|
705
|
+
return dfs(cur.left, min, cur.id) && dfs(cur.right, cur.id, max);
|
|
830
706
|
};
|
|
831
|
-
return
|
|
707
|
+
return dfs(node, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
|
|
832
708
|
}
|
|
833
709
|
else {
|
|
834
|
-
|
|
835
|
-
|
|
710
|
+
const stack = [];
|
|
711
|
+
let prev = Number.MIN_SAFE_INTEGER, curr = node;
|
|
836
712
|
while (curr || stack.length > 0) {
|
|
837
713
|
while (curr) {
|
|
838
714
|
stack.push(curr);
|
|
@@ -846,46 +722,46 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
846
722
|
}
|
|
847
723
|
return true;
|
|
848
724
|
}
|
|
849
|
-
}
|
|
725
|
+
}
|
|
850
726
|
/**
|
|
851
727
|
* The function checks if a binary tree is a binary search tree.
|
|
852
728
|
* @param {N | null} [node] - The `node` parameter is of type `N` or `null`. It represents the root node of a binary
|
|
853
729
|
* search tree (BST).
|
|
854
730
|
* @returns a boolean value.
|
|
855
731
|
*/
|
|
856
|
-
|
|
732
|
+
isBST(node) {
|
|
857
733
|
return this.isBSTByRooted(this.root);
|
|
858
|
-
}
|
|
734
|
+
}
|
|
859
735
|
/**
|
|
860
736
|
* The function calculates the size of a subtree by traversing it either recursively or iteratively.
|
|
861
737
|
* @param {N | null | undefined} subTreeRoot - The `subTreeRoot` parameter represents the root node of a subtree in a
|
|
862
738
|
* binary tree.
|
|
863
739
|
* @returns the size of the subtree rooted at `subTreeRoot`.
|
|
864
740
|
*/
|
|
865
|
-
|
|
866
|
-
|
|
741
|
+
getSubTreeSize(subTreeRoot) {
|
|
742
|
+
let size = 0;
|
|
867
743
|
if (!subTreeRoot)
|
|
868
744
|
return size;
|
|
869
745
|
if (this._loopType === types_1.LoopType.RECURSIVE) {
|
|
870
|
-
|
|
746
|
+
const _traverse = (cur) => {
|
|
871
747
|
size++;
|
|
872
|
-
cur.left &&
|
|
873
|
-
cur.right &&
|
|
748
|
+
cur.left && _traverse(cur.left);
|
|
749
|
+
cur.right && _traverse(cur.right);
|
|
874
750
|
};
|
|
875
|
-
|
|
751
|
+
_traverse(subTreeRoot);
|
|
876
752
|
return size;
|
|
877
753
|
}
|
|
878
754
|
else {
|
|
879
|
-
|
|
755
|
+
const stack = [subTreeRoot];
|
|
880
756
|
while (stack.length > 0) {
|
|
881
|
-
|
|
757
|
+
const cur = stack.pop();
|
|
882
758
|
size++;
|
|
883
759
|
cur.right && stack.push(cur.right);
|
|
884
760
|
cur.left && stack.push(cur.left);
|
|
885
761
|
}
|
|
886
762
|
return size;
|
|
887
763
|
}
|
|
888
|
-
}
|
|
764
|
+
}
|
|
889
765
|
/**
|
|
890
766
|
* The function `subTreeSum` calculates the sum of a specified property in a binary tree or subtree.
|
|
891
767
|
* @param {N | BinaryTreeNodeId | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a binary
|
|
@@ -895,15 +771,15 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
895
771
|
* not provided, it defaults to 'id'.
|
|
896
772
|
* @returns a number, which is the sum of the values of the specified property in the subtree rooted at `subTreeRoot`.
|
|
897
773
|
*/
|
|
898
|
-
|
|
774
|
+
subTreeSum(subTreeRoot, propertyName) {
|
|
899
775
|
propertyName = propertyName !== null && propertyName !== void 0 ? propertyName : 'id';
|
|
900
776
|
if (typeof subTreeRoot === 'number')
|
|
901
777
|
subTreeRoot = this.get(subTreeRoot, 'id');
|
|
902
778
|
if (!subTreeRoot)
|
|
903
779
|
return 0;
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
780
|
+
let sum = 0;
|
|
781
|
+
const _sumByProperty = (cur) => {
|
|
782
|
+
let needSum;
|
|
907
783
|
switch (propertyName) {
|
|
908
784
|
case 'id':
|
|
909
785
|
needSum = cur.id;
|
|
@@ -918,24 +794,24 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
918
794
|
return needSum;
|
|
919
795
|
};
|
|
920
796
|
if (this._loopType === types_1.LoopType.RECURSIVE) {
|
|
921
|
-
|
|
797
|
+
const _traverse = (cur) => {
|
|
922
798
|
sum += _sumByProperty(cur);
|
|
923
|
-
cur.left &&
|
|
924
|
-
cur.right &&
|
|
799
|
+
cur.left && _traverse(cur.left);
|
|
800
|
+
cur.right && _traverse(cur.right);
|
|
925
801
|
};
|
|
926
|
-
|
|
802
|
+
_traverse(subTreeRoot);
|
|
927
803
|
}
|
|
928
804
|
else {
|
|
929
|
-
|
|
805
|
+
const stack = [subTreeRoot];
|
|
930
806
|
while (stack.length > 0) {
|
|
931
|
-
|
|
807
|
+
const cur = stack.pop();
|
|
932
808
|
sum += _sumByProperty(cur);
|
|
933
809
|
cur.right && stack.push(cur.right);
|
|
934
810
|
cur.left && stack.push(cur.left);
|
|
935
811
|
}
|
|
936
812
|
}
|
|
937
813
|
return sum;
|
|
938
|
-
}
|
|
814
|
+
}
|
|
939
815
|
/**
|
|
940
816
|
* The function `subTreeAdd` adds a delta value to a specified property of each node in a subtree.
|
|
941
817
|
* @param {N | BinaryTreeNodeId | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a binary
|
|
@@ -946,13 +822,13 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
946
822
|
* specifies the property of the binary tree node that should be modified. If not provided, it defaults to 'id'.
|
|
947
823
|
* @returns a boolean value.
|
|
948
824
|
*/
|
|
949
|
-
|
|
825
|
+
subTreeAdd(subTreeRoot, delta, propertyName) {
|
|
950
826
|
propertyName = propertyName !== null && propertyName !== void 0 ? propertyName : 'id';
|
|
951
827
|
if (typeof subTreeRoot === 'number')
|
|
952
828
|
subTreeRoot = this.get(subTreeRoot, 'id');
|
|
953
829
|
if (!subTreeRoot)
|
|
954
830
|
return false;
|
|
955
|
-
|
|
831
|
+
const _addByProperty = (cur) => {
|
|
956
832
|
switch (propertyName) {
|
|
957
833
|
case 'id':
|
|
958
834
|
cur.id += delta;
|
|
@@ -963,24 +839,24 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
963
839
|
}
|
|
964
840
|
};
|
|
965
841
|
if (this._loopType === types_1.LoopType.RECURSIVE) {
|
|
966
|
-
|
|
842
|
+
const _traverse = (cur) => {
|
|
967
843
|
_addByProperty(cur);
|
|
968
|
-
cur.left &&
|
|
969
|
-
cur.right &&
|
|
844
|
+
cur.left && _traverse(cur.left);
|
|
845
|
+
cur.right && _traverse(cur.right);
|
|
970
846
|
};
|
|
971
|
-
|
|
847
|
+
_traverse(subTreeRoot);
|
|
972
848
|
}
|
|
973
849
|
else {
|
|
974
|
-
|
|
850
|
+
const stack = [subTreeRoot];
|
|
975
851
|
while (stack.length > 0) {
|
|
976
|
-
|
|
852
|
+
const cur = stack.pop();
|
|
977
853
|
_addByProperty(cur);
|
|
978
854
|
cur.right && stack.push(cur.right);
|
|
979
855
|
cur.left && stack.push(cur.left);
|
|
980
856
|
}
|
|
981
857
|
}
|
|
982
858
|
return true;
|
|
983
|
-
}
|
|
859
|
+
}
|
|
984
860
|
/**
|
|
985
861
|
* The BFS function performs a breadth-first search on a binary tree, accumulating properties of each node based on a
|
|
986
862
|
* specified property name.
|
|
@@ -990,12 +866,12 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
990
866
|
* the
|
|
991
867
|
* @returns an instance of the `AbstractBinaryTreeNodeProperties` class with generic type `N`.
|
|
992
868
|
*/
|
|
993
|
-
|
|
869
|
+
BFS(nodeOrPropertyName) {
|
|
994
870
|
nodeOrPropertyName = nodeOrPropertyName !== null && nodeOrPropertyName !== void 0 ? nodeOrPropertyName : 'id';
|
|
995
871
|
this._resetResults();
|
|
996
|
-
|
|
872
|
+
const queue = [this.root];
|
|
997
873
|
while (queue.length !== 0) {
|
|
998
|
-
|
|
874
|
+
const cur = queue.shift();
|
|
999
875
|
if (cur) {
|
|
1000
876
|
this._accumulatedByPropertyName(cur, nodeOrPropertyName);
|
|
1001
877
|
if ((cur === null || cur === void 0 ? void 0 : cur.left) !== null)
|
|
@@ -1005,7 +881,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1005
881
|
}
|
|
1006
882
|
}
|
|
1007
883
|
return this._getResultByPropertyName(nodeOrPropertyName);
|
|
1008
|
-
}
|
|
884
|
+
}
|
|
1009
885
|
/**
|
|
1010
886
|
* The DFS function performs a depth-first search traversal on a binary tree and returns the accumulated properties of
|
|
1011
887
|
* each node based on the specified pattern and property name.
|
|
@@ -1017,22 +893,21 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1017
893
|
* @returns an instance of the AbstractBinaryTreeNodeProperties class, which contains the accumulated properties of the
|
|
1018
894
|
* binary tree nodes based on the specified pattern and node or property name.
|
|
1019
895
|
*/
|
|
1020
|
-
|
|
1021
|
-
var _this = this;
|
|
896
|
+
DFS(pattern, nodeOrPropertyName) {
|
|
1022
897
|
pattern = pattern !== null && pattern !== void 0 ? pattern : 'in';
|
|
1023
898
|
nodeOrPropertyName = nodeOrPropertyName !== null && nodeOrPropertyName !== void 0 ? nodeOrPropertyName : 'id';
|
|
1024
899
|
this._resetResults();
|
|
1025
|
-
|
|
900
|
+
const _traverse = (node) => {
|
|
1026
901
|
switch (pattern) {
|
|
1027
902
|
case 'in':
|
|
1028
903
|
if (node.left)
|
|
1029
904
|
_traverse(node.left);
|
|
1030
|
-
|
|
905
|
+
this._accumulatedByPropertyName(node, nodeOrPropertyName);
|
|
1031
906
|
if (node.right)
|
|
1032
907
|
_traverse(node.right);
|
|
1033
908
|
break;
|
|
1034
909
|
case 'pre':
|
|
1035
|
-
|
|
910
|
+
this._accumulatedByPropertyName(node, nodeOrPropertyName);
|
|
1036
911
|
if (node.left)
|
|
1037
912
|
_traverse(node.left);
|
|
1038
913
|
if (node.right)
|
|
@@ -1043,13 +918,13 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1043
918
|
_traverse(node.left);
|
|
1044
919
|
if (node.right)
|
|
1045
920
|
_traverse(node.right);
|
|
1046
|
-
|
|
921
|
+
this._accumulatedByPropertyName(node, nodeOrPropertyName);
|
|
1047
922
|
break;
|
|
1048
923
|
}
|
|
1049
924
|
};
|
|
1050
925
|
this.root && _traverse(this.root);
|
|
1051
926
|
return this._getResultByPropertyName(nodeOrPropertyName);
|
|
1052
|
-
}
|
|
927
|
+
}
|
|
1053
928
|
/**
|
|
1054
929
|
* The DFSIterative function performs an iterative depth-first search traversal on a binary tree, with the option to
|
|
1055
930
|
* specify the traversal pattern and the property name to accumulate results by.
|
|
@@ -1061,16 +936,16 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1061
936
|
* the
|
|
1062
937
|
* @returns an object of type AbstractBinaryTreeNodeProperties<N>.
|
|
1063
938
|
*/
|
|
1064
|
-
|
|
939
|
+
DFSIterative(pattern, nodeOrPropertyName) {
|
|
1065
940
|
pattern = pattern || 'in';
|
|
1066
941
|
nodeOrPropertyName = nodeOrPropertyName || 'id';
|
|
1067
942
|
this._resetResults();
|
|
1068
943
|
if (!this.root)
|
|
1069
944
|
return this._getResultByPropertyName(nodeOrPropertyName);
|
|
1070
945
|
// 0: visit, 1: print
|
|
1071
|
-
|
|
946
|
+
const stack = [{ opt: 0, node: this.root }];
|
|
1072
947
|
while (stack.length > 0) {
|
|
1073
|
-
|
|
948
|
+
const cur = stack.pop();
|
|
1074
949
|
if (!cur || !cur.node)
|
|
1075
950
|
continue;
|
|
1076
951
|
if (cur.opt === 1) {
|
|
@@ -1102,7 +977,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1102
977
|
}
|
|
1103
978
|
}
|
|
1104
979
|
return this._getResultByPropertyName(nodeOrPropertyName);
|
|
1105
|
-
}
|
|
980
|
+
}
|
|
1106
981
|
/**
|
|
1107
982
|
* The `levelIterative` function performs a level-order traversal on a binary tree and returns the values of the nodes
|
|
1108
983
|
* in an array, based on a specified property name.
|
|
@@ -1115,15 +990,15 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1115
990
|
* accumulating results
|
|
1116
991
|
* @returns The function `levelIterative` returns an object of type `AbstractBinaryTreeNodeProperties<N>`.
|
|
1117
992
|
*/
|
|
1118
|
-
|
|
993
|
+
levelIterative(node, nodeOrPropertyName) {
|
|
1119
994
|
nodeOrPropertyName = nodeOrPropertyName || 'id';
|
|
1120
995
|
node = node || this.root;
|
|
1121
996
|
if (!node)
|
|
1122
997
|
return [];
|
|
1123
998
|
this._resetResults();
|
|
1124
|
-
|
|
999
|
+
const queue = [node];
|
|
1125
1000
|
while (queue.length > 0) {
|
|
1126
|
-
|
|
1001
|
+
const cur = queue.shift();
|
|
1127
1002
|
if (cur) {
|
|
1128
1003
|
this._accumulatedByPropertyName(cur, nodeOrPropertyName);
|
|
1129
1004
|
if (cur.left) {
|
|
@@ -1135,7 +1010,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1135
1010
|
}
|
|
1136
1011
|
}
|
|
1137
1012
|
return this._getResultByPropertyName(nodeOrPropertyName);
|
|
1138
|
-
}
|
|
1013
|
+
}
|
|
1139
1014
|
/**
|
|
1140
1015
|
* The `listLevels` function collects nodes from a binary tree by a specified property and organizes them into levels.
|
|
1141
1016
|
* @param {N | null} node - The `node` parameter is a BinaryTreeNode object or null. It represents the
|
|
@@ -1145,13 +1020,13 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1145
1020
|
* values:
|
|
1146
1021
|
* @returns The function `listLevels` returns a 2D array of `AbstractBinaryTreeNodeProperty<N>` objects.
|
|
1147
1022
|
*/
|
|
1148
|
-
|
|
1023
|
+
listLevels(node, nodeOrPropertyName) {
|
|
1149
1024
|
nodeOrPropertyName = nodeOrPropertyName || 'id';
|
|
1150
1025
|
node = node || this.root;
|
|
1151
1026
|
if (!node)
|
|
1152
1027
|
return [];
|
|
1153
|
-
|
|
1154
|
-
|
|
1028
|
+
const levelsNodes = [];
|
|
1029
|
+
const collectByProperty = (node, level) => {
|
|
1155
1030
|
switch (nodeOrPropertyName) {
|
|
1156
1031
|
case 'id':
|
|
1157
1032
|
levelsNodes[level].push(node.id);
|
|
@@ -1168,41 +1043,41 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1168
1043
|
}
|
|
1169
1044
|
};
|
|
1170
1045
|
if (this.loopType === types_1.LoopType.RECURSIVE) {
|
|
1171
|
-
|
|
1046
|
+
const _recursive = (node, level) => {
|
|
1172
1047
|
if (!levelsNodes[level])
|
|
1173
1048
|
levelsNodes[level] = [];
|
|
1174
1049
|
collectByProperty(node, level);
|
|
1175
1050
|
if (node.left)
|
|
1176
|
-
|
|
1051
|
+
_recursive(node.left, level + 1);
|
|
1177
1052
|
if (node.right)
|
|
1178
|
-
|
|
1053
|
+
_recursive(node.right, level + 1);
|
|
1179
1054
|
};
|
|
1180
|
-
|
|
1055
|
+
_recursive(node, 0);
|
|
1181
1056
|
}
|
|
1182
1057
|
else {
|
|
1183
|
-
|
|
1058
|
+
const stack = [[node, 0]];
|
|
1184
1059
|
while (stack.length > 0) {
|
|
1185
|
-
|
|
1186
|
-
|
|
1060
|
+
const head = stack.pop();
|
|
1061
|
+
const [node, level] = head;
|
|
1187
1062
|
if (!levelsNodes[level])
|
|
1188
1063
|
levelsNodes[level] = [];
|
|
1189
|
-
collectByProperty(
|
|
1190
|
-
if (
|
|
1191
|
-
stack.push([
|
|
1192
|
-
if (
|
|
1193
|
-
stack.push([
|
|
1064
|
+
collectByProperty(node, level);
|
|
1065
|
+
if (node.right)
|
|
1066
|
+
stack.push([node.right, level + 1]);
|
|
1067
|
+
if (node.left)
|
|
1068
|
+
stack.push([node.left, level + 1]);
|
|
1194
1069
|
}
|
|
1195
1070
|
}
|
|
1196
1071
|
return levelsNodes;
|
|
1197
|
-
}
|
|
1072
|
+
}
|
|
1198
1073
|
/**
|
|
1199
1074
|
* The function returns the predecessor of a given node in a binary tree.
|
|
1200
1075
|
* @param node - The parameter `node` is a BinaryTreeNode object, representing a node in a binary tree.
|
|
1201
1076
|
* @returns the predecessor of the given node in a binary tree.
|
|
1202
1077
|
*/
|
|
1203
|
-
|
|
1078
|
+
getPredecessor(node) {
|
|
1204
1079
|
if (node.left) {
|
|
1205
|
-
|
|
1080
|
+
let predecessor = node.left;
|
|
1206
1081
|
while (!(predecessor) || predecessor.right && predecessor.right !== node) {
|
|
1207
1082
|
if (predecessor) {
|
|
1208
1083
|
predecessor = predecessor.right;
|
|
@@ -1213,7 +1088,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1213
1088
|
else {
|
|
1214
1089
|
return node;
|
|
1215
1090
|
}
|
|
1216
|
-
}
|
|
1091
|
+
}
|
|
1217
1092
|
/**
|
|
1218
1093
|
* The `morris` function performs an in-order, pre-order, or post-order traversal on a binary tree using the Morris
|
|
1219
1094
|
* traversal algorithm.
|
|
@@ -1224,17 +1099,16 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1224
1099
|
* tree.
|
|
1225
1100
|
* @returns an array of AbstractBinaryTreeNodeProperties<N> objects.
|
|
1226
1101
|
*/
|
|
1227
|
-
|
|
1228
|
-
var _this = this;
|
|
1102
|
+
morris(pattern, nodeOrPropertyName) {
|
|
1229
1103
|
if (this.root === null)
|
|
1230
1104
|
return [];
|
|
1231
1105
|
pattern = pattern || 'in';
|
|
1232
1106
|
nodeOrPropertyName = nodeOrPropertyName || 'id';
|
|
1233
1107
|
this._resetResults();
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1108
|
+
let cur = this.root;
|
|
1109
|
+
const _reverseEdge = (node) => {
|
|
1110
|
+
let pre = null;
|
|
1111
|
+
let next = null;
|
|
1238
1112
|
while (node) {
|
|
1239
1113
|
next = node.right;
|
|
1240
1114
|
node.right = pre;
|
|
@@ -1243,11 +1117,11 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1243
1117
|
}
|
|
1244
1118
|
return pre;
|
|
1245
1119
|
};
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1120
|
+
const _printEdge = (node) => {
|
|
1121
|
+
const tail = _reverseEdge(node);
|
|
1122
|
+
let cur = tail;
|
|
1249
1123
|
while (cur) {
|
|
1250
|
-
|
|
1124
|
+
this._accumulatedByPropertyName(cur, nodeOrPropertyName);
|
|
1251
1125
|
cur = cur.right;
|
|
1252
1126
|
}
|
|
1253
1127
|
_reverseEdge(tail);
|
|
@@ -1256,7 +1130,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1256
1130
|
case 'in':
|
|
1257
1131
|
while (cur) {
|
|
1258
1132
|
if (cur.left) {
|
|
1259
|
-
|
|
1133
|
+
const predecessor = this.getPredecessor(cur);
|
|
1260
1134
|
if (!predecessor.right) {
|
|
1261
1135
|
predecessor.right = cur;
|
|
1262
1136
|
cur = cur.left;
|
|
@@ -1273,7 +1147,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1273
1147
|
case 'pre':
|
|
1274
1148
|
while (cur) {
|
|
1275
1149
|
if (cur.left) {
|
|
1276
|
-
|
|
1150
|
+
const predecessor = this.getPredecessor(cur);
|
|
1277
1151
|
if (!predecessor.right) {
|
|
1278
1152
|
predecessor.right = cur;
|
|
1279
1153
|
this._accumulatedByPropertyName(cur, nodeOrPropertyName);
|
|
@@ -1293,7 +1167,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1293
1167
|
case 'post':
|
|
1294
1168
|
while (cur) {
|
|
1295
1169
|
if (cur.left) {
|
|
1296
|
-
|
|
1170
|
+
const predecessor = this.getPredecessor(cur);
|
|
1297
1171
|
if (predecessor.right === null) {
|
|
1298
1172
|
predecessor.right = cur;
|
|
1299
1173
|
cur = cur.left;
|
|
@@ -1310,101 +1184,101 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1310
1184
|
break;
|
|
1311
1185
|
}
|
|
1312
1186
|
return this._getResultByPropertyName(nodeOrPropertyName);
|
|
1313
|
-
}
|
|
1187
|
+
}
|
|
1314
1188
|
/**
|
|
1315
1189
|
* The function sets the loop type for a protected variable.
|
|
1316
1190
|
* @param {LoopType} value - The value parameter is of type LoopType.
|
|
1317
1191
|
*/
|
|
1318
|
-
|
|
1192
|
+
_setLoopType(value) {
|
|
1319
1193
|
this._loopType = value;
|
|
1320
|
-
}
|
|
1194
|
+
}
|
|
1321
1195
|
/**
|
|
1322
1196
|
* The function sets the value of the `_visitedId` property in a protected manner.
|
|
1323
1197
|
* @param {BinaryTreeNodeId[]} value - value is an array of BinaryTreeNodeId values.
|
|
1324
1198
|
*/
|
|
1325
|
-
|
|
1199
|
+
_setVisitedId(value) {
|
|
1326
1200
|
this._visitedId = value;
|
|
1327
|
-
}
|
|
1201
|
+
}
|
|
1328
1202
|
/**
|
|
1329
1203
|
* The function sets the value of the "_visitedVal" property to the given array.
|
|
1330
1204
|
* @param value - An array of type N.
|
|
1331
1205
|
*/
|
|
1332
|
-
|
|
1206
|
+
_setVisitedVal(value) {
|
|
1333
1207
|
this._visitedVal = value;
|
|
1334
|
-
}
|
|
1208
|
+
}
|
|
1335
1209
|
/**
|
|
1336
1210
|
* The function sets the value of the _visitedNode property.
|
|
1337
1211
|
* @param {N[]} value - N[] is an array of elements of type N.
|
|
1338
1212
|
*/
|
|
1339
|
-
|
|
1213
|
+
_setVisitedNode(value) {
|
|
1340
1214
|
this._visitedNode = value;
|
|
1341
|
-
}
|
|
1215
|
+
}
|
|
1342
1216
|
/**
|
|
1343
1217
|
* The function sets the value of the visitedCount property.
|
|
1344
1218
|
* @param {number[]} value - The value parameter is an array of numbers.
|
|
1345
1219
|
*/
|
|
1346
|
-
|
|
1220
|
+
setVisitedCount(value) {
|
|
1347
1221
|
this._visitedCount = value;
|
|
1348
|
-
}
|
|
1222
|
+
}
|
|
1349
1223
|
/**
|
|
1350
1224
|
* The function sets the value of the `_visitedLeftSum` property to the provided array.
|
|
1351
1225
|
* @param {number[]} value - An array of numbers that represents the visited left sum.
|
|
1352
1226
|
*/
|
|
1353
|
-
|
|
1227
|
+
_setVisitedLeftSum(value) {
|
|
1354
1228
|
this._visitedLeftSum = value;
|
|
1355
|
-
}
|
|
1229
|
+
}
|
|
1356
1230
|
/**
|
|
1357
1231
|
* The function sets the value of the _autoIncrementId property.
|
|
1358
1232
|
* @param {boolean} value - The value parameter is a boolean that determines whether the id should be automatically
|
|
1359
1233
|
* incremented or not. If value is true, the id will be automatically incremented. If value is false, the id will not
|
|
1360
1234
|
* be automatically incremented.
|
|
1361
1235
|
*/
|
|
1362
|
-
|
|
1236
|
+
_setAutoIncrementId(value) {
|
|
1363
1237
|
this._autoIncrementId = value;
|
|
1364
|
-
}
|
|
1238
|
+
}
|
|
1365
1239
|
/**
|
|
1366
1240
|
* The function sets the maximum ID value.
|
|
1367
1241
|
* @param {number} value - The value parameter is a number that represents the new maximum ID value.
|
|
1368
1242
|
*/
|
|
1369
|
-
|
|
1243
|
+
_setMaxId(value) {
|
|
1370
1244
|
this._maxId = value;
|
|
1371
|
-
}
|
|
1245
|
+
}
|
|
1372
1246
|
/**
|
|
1373
1247
|
* The function sets the value of a protected property called "_isMergeDuplicatedVal".
|
|
1374
1248
|
* @param {boolean} value - The value parameter is a boolean value that determines whether the isMergeDuplicatedVal
|
|
1375
1249
|
* property should be set to true or false.
|
|
1376
1250
|
*/
|
|
1377
|
-
|
|
1251
|
+
_setIsDuplicatedVal(value) {
|
|
1378
1252
|
this._isMergeDuplicatedVal = value;
|
|
1379
|
-
}
|
|
1253
|
+
}
|
|
1380
1254
|
/**
|
|
1381
1255
|
* The function sets the root property of an object to a given value, and if the value is not null, it also sets the
|
|
1382
1256
|
* parent property of the value to undefined.
|
|
1383
1257
|
* @param {N | null} v - The parameter `v` is of type `N | null`, which means it can either be of type `N` or `null`.
|
|
1384
1258
|
*/
|
|
1385
|
-
|
|
1259
|
+
_setRoot(v) {
|
|
1386
1260
|
if (v) {
|
|
1387
1261
|
v.parent = undefined;
|
|
1388
1262
|
}
|
|
1389
1263
|
this._root = v;
|
|
1390
|
-
}
|
|
1264
|
+
}
|
|
1391
1265
|
/**
|
|
1392
1266
|
* The function sets the size of a protected variable.
|
|
1393
1267
|
* @param {number} v - number
|
|
1394
1268
|
*/
|
|
1395
|
-
|
|
1269
|
+
_setSize(v) {
|
|
1396
1270
|
this._size = v;
|
|
1397
|
-
}
|
|
1271
|
+
}
|
|
1398
1272
|
/**
|
|
1399
1273
|
* The function `_resetResults` resets the values of several arrays used for tracking visited nodes and their
|
|
1400
1274
|
* properties.
|
|
1401
1275
|
*/
|
|
1402
|
-
|
|
1276
|
+
_resetResults() {
|
|
1403
1277
|
this._visitedId = [];
|
|
1404
1278
|
this._visitedVal = [];
|
|
1405
1279
|
this._visitedNode = [];
|
|
1406
1280
|
this._visitedLeftSum = [];
|
|
1407
|
-
}
|
|
1281
|
+
}
|
|
1408
1282
|
/**
|
|
1409
1283
|
* The function checks if a given property of a binary tree node matches a specified value, and if so, adds the node to
|
|
1410
1284
|
* a result array.
|
|
@@ -1420,7 +1294,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1420
1294
|
* `true`, the function will stop after finding the first matching node and return `true`. If `onlyOne
|
|
1421
1295
|
* @returns a boolean value indicating whether only one matching node should be pushed into the result array.
|
|
1422
1296
|
*/
|
|
1423
|
-
|
|
1297
|
+
_pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne) {
|
|
1424
1298
|
switch (propertyName) {
|
|
1425
1299
|
case 'id':
|
|
1426
1300
|
if (cur.id === nodeProperty) {
|
|
@@ -1441,7 +1315,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1441
1315
|
}
|
|
1442
1316
|
break;
|
|
1443
1317
|
}
|
|
1444
|
-
}
|
|
1318
|
+
}
|
|
1445
1319
|
/**
|
|
1446
1320
|
* The function `_accumulatedByPropertyName` accumulates values from a given node based on the specified property name.
|
|
1447
1321
|
* @param {N} node - The `node` parameter is of type `N`, which represents a node in a data structure.
|
|
@@ -1449,7 +1323,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1449
1323
|
* can be either a string representing a property name or a reference to a `Node` object. If it is a string, it
|
|
1450
1324
|
* specifies the property name to be used for accumulating values. If it is a `Node` object, it specifies
|
|
1451
1325
|
*/
|
|
1452
|
-
|
|
1326
|
+
_accumulatedByPropertyName(node, nodeOrPropertyName) {
|
|
1453
1327
|
nodeOrPropertyName = nodeOrPropertyName !== null && nodeOrPropertyName !== void 0 ? nodeOrPropertyName : 'id';
|
|
1454
1328
|
switch (nodeOrPropertyName) {
|
|
1455
1329
|
case 'id':
|
|
@@ -1465,7 +1339,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1465
1339
|
this._visitedId.push(node.id);
|
|
1466
1340
|
break;
|
|
1467
1341
|
}
|
|
1468
|
-
}
|
|
1342
|
+
}
|
|
1469
1343
|
/**
|
|
1470
1344
|
* The time complexity of Morris traversal is O(n), it's may slower than others
|
|
1471
1345
|
* The space complexity Morris traversal is O(1) because no using stack
|
|
@@ -1477,7 +1351,7 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1477
1351
|
* can accept either a `NodeOrPropertyName` type or be undefined.
|
|
1478
1352
|
* @returns The method `_getResultByPropertyName` returns an instance of `AbstractBinaryTreeNodeProperties<N>`.
|
|
1479
1353
|
*/
|
|
1480
|
-
|
|
1354
|
+
_getResultByPropertyName(nodeOrPropertyName) {
|
|
1481
1355
|
nodeOrPropertyName = nodeOrPropertyName !== null && nodeOrPropertyName !== void 0 ? nodeOrPropertyName : 'id';
|
|
1482
1356
|
switch (nodeOrPropertyName) {
|
|
1483
1357
|
case 'id':
|
|
@@ -1489,7 +1363,6 @@ var AbstractBinaryTree = /** @class */ (function () {
|
|
|
1489
1363
|
default:
|
|
1490
1364
|
return this._visitedId;
|
|
1491
1365
|
}
|
|
1492
|
-
}
|
|
1493
|
-
|
|
1494
|
-
}());
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1495
1368
|
exports.AbstractBinaryTree = AbstractBinaryTree;
|