bst-typed 1.47.5 → 1.47.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data-structures/binary-tree/avl-tree.d.ts +36 -18
- package/dist/data-structures/binary-tree/avl-tree.js +46 -29
- package/dist/data-structures/binary-tree/binary-tree.d.ts +158 -129
- package/dist/data-structures/binary-tree/binary-tree.js +182 -184
- package/dist/data-structures/binary-tree/bst.d.ts +73 -63
- package/dist/data-structures/binary-tree/bst.js +168 -169
- package/dist/data-structures/binary-tree/rb-tree.d.ts +54 -17
- package/dist/data-structures/binary-tree/rb-tree.js +77 -31
- package/dist/data-structures/binary-tree/tree-multimap.d.ts +29 -40
- package/dist/data-structures/binary-tree/tree-multimap.js +66 -136
- package/dist/data-structures/graph/abstract-graph.js +1 -1
- package/dist/data-structures/hash/hash-map.d.ts +2 -6
- package/dist/data-structures/hash/hash-map.js +5 -8
- package/dist/data-structures/heap/heap.d.ts +19 -21
- package/dist/data-structures/heap/heap.js +52 -34
- package/dist/data-structures/heap/max-heap.d.ts +2 -5
- package/dist/data-structures/heap/max-heap.js +2 -2
- package/dist/data-structures/heap/min-heap.d.ts +2 -5
- package/dist/data-structures/heap/min-heap.js +2 -2
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +2 -1
- package/dist/data-structures/linked-list/doubly-linked-list.js +9 -1
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +2 -1
- package/dist/data-structures/linked-list/singly-linked-list.js +8 -1
- package/dist/data-structures/priority-queue/max-priority-queue.d.ts +2 -5
- package/dist/data-structures/priority-queue/max-priority-queue.js +2 -2
- package/dist/data-structures/priority-queue/min-priority-queue.d.ts +2 -5
- package/dist/data-structures/priority-queue/min-priority-queue.js +2 -2
- package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -5
- package/dist/data-structures/priority-queue/priority-queue.js +2 -2
- package/dist/data-structures/queue/deque.d.ts +1 -0
- package/dist/data-structures/queue/deque.js +3 -0
- package/dist/data-structures/queue/queue.d.ts +1 -0
- package/dist/data-structures/queue/queue.js +3 -0
- package/dist/data-structures/stack/stack.d.ts +2 -1
- package/dist/data-structures/stack/stack.js +10 -2
- package/dist/data-structures/trie/trie.d.ts +3 -0
- package/dist/data-structures/trie/trie.js +19 -4
- package/dist/interfaces/binary-tree.d.ts +4 -2
- package/dist/types/common.d.ts +7 -0
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/bst.d.ts +2 -2
- package/dist/types/data-structures/hash/hash-map.d.ts +1 -2
- package/dist/types/data-structures/heap/heap.d.ts +4 -1
- package/dist/types/data-structures/priority-queue/priority-queue.d.ts +2 -1
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree.ts +61 -31
- package/src/data-structures/binary-tree/binary-tree.ts +283 -254
- package/src/data-structures/binary-tree/bst.ts +193 -170
- package/src/data-structures/binary-tree/rb-tree.ts +87 -32
- package/src/data-structures/binary-tree/tree-multimap.ts +76 -136
- package/src/data-structures/graph/abstract-graph.ts +1 -1
- package/src/data-structures/hash/hash-map.ts +8 -8
- package/src/data-structures/heap/heap.ts +57 -39
- package/src/data-structures/heap/max-heap.ts +5 -5
- package/src/data-structures/heap/min-heap.ts +5 -5
- package/src/data-structures/linked-list/doubly-linked-list.ts +10 -1
- package/src/data-structures/linked-list/singly-linked-list.ts +9 -1
- package/src/data-structures/priority-queue/max-priority-queue.ts +4 -3
- package/src/data-structures/priority-queue/min-priority-queue.ts +12 -12
- package/src/data-structures/priority-queue/priority-queue.ts +3 -3
- package/src/data-structures/queue/deque.ts +4 -0
- package/src/data-structures/queue/queue.ts +4 -0
- package/src/data-structures/stack/stack.ts +12 -3
- package/src/data-structures/trie/trie.ts +23 -4
- package/src/interfaces/binary-tree.ts +14 -2
- package/src/types/common.ts +15 -1
- package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
- package/src/types/data-structures/binary-tree/bst.ts +2 -3
- package/src/types/data-structures/hash/hash-map.ts +1 -2
- package/src/types/data-structures/heap/heap.ts +3 -1
- package/src/types/data-structures/priority-queue/priority-queue.ts +3 -1
|
@@ -17,41 +17,22 @@ const queue_1 = require("../queue");
|
|
|
17
17
|
* @template N - The type of the family relationship in the binary tree.
|
|
18
18
|
*/
|
|
19
19
|
class BinaryTreeNode {
|
|
20
|
-
/**
|
|
21
|
-
* Creates a new instance of BinaryTreeNode.
|
|
22
|
-
* @param {BTNKey} key - The key associated with the node.
|
|
23
|
-
* @param {V} value - The value stored in the node.
|
|
24
|
-
*/
|
|
25
20
|
constructor(key, value) {
|
|
26
21
|
this.key = key;
|
|
27
22
|
this.value = value;
|
|
28
23
|
}
|
|
29
|
-
/**
|
|
30
|
-
* Get the left child node.
|
|
31
|
-
*/
|
|
32
24
|
get left() {
|
|
33
25
|
return this._left;
|
|
34
26
|
}
|
|
35
|
-
/**
|
|
36
|
-
* Set the left child node.
|
|
37
|
-
* @param {N | null | undefined} v - The left child node.
|
|
38
|
-
*/
|
|
39
27
|
set left(v) {
|
|
40
28
|
if (v) {
|
|
41
29
|
v.parent = this;
|
|
42
30
|
}
|
|
43
31
|
this._left = v;
|
|
44
32
|
}
|
|
45
|
-
/**
|
|
46
|
-
* Get the right child node.
|
|
47
|
-
*/
|
|
48
33
|
get right() {
|
|
49
34
|
return this._right;
|
|
50
35
|
}
|
|
51
|
-
/**
|
|
52
|
-
* Set the right child node.
|
|
53
|
-
* @param {N | null | undefined} v - The right child node.
|
|
54
|
-
*/
|
|
55
36
|
set right(v) {
|
|
56
37
|
if (v) {
|
|
57
38
|
v.parent = this;
|
|
@@ -78,33 +59,42 @@ class BinaryTreeNode {
|
|
|
78
59
|
}
|
|
79
60
|
exports.BinaryTreeNode = BinaryTreeNode;
|
|
80
61
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
62
|
+
* 1. Two Children Maximum: Each node has at most two children.
|
|
63
|
+
* 2. Left and Right Children: Nodes have distinct left and right children.
|
|
64
|
+
* 3. Depth and Height: Depth is the number of edges from the root to a node; height is the maximum depth in the tree.
|
|
65
|
+
* 4. Subtrees: Each child of a node forms the root of a subtree.
|
|
66
|
+
* 5. Leaf Nodes: Nodes without children are leaves.
|
|
67
|
+
* 6. Internal Nodes: Nodes with at least one child are internal.
|
|
68
|
+
* 7. Balanced Trees: The heights of the left and right subtrees of any node differ by no more than one.
|
|
69
|
+
* 8. Full Trees: Every node has either 0 or 2 children.
|
|
70
|
+
* 9. Complete Trees: All levels are fully filled except possibly the last, filled from left to right.
|
|
83
71
|
*/
|
|
84
72
|
class BinaryTree {
|
|
85
73
|
/**
|
|
86
|
-
*
|
|
87
|
-
* @param
|
|
74
|
+
* The constructor function initializes a binary tree object with optional elements and options.
|
|
75
|
+
* @param [elements] - An optional iterable of BTNodeExemplar objects. These objects represent the
|
|
76
|
+
* elements to be added to the binary tree.
|
|
77
|
+
* @param [options] - The `options` parameter is an optional object that can contain additional
|
|
78
|
+
* configuration options for the binary tree. In this case, it is of type
|
|
79
|
+
* `Partial<BinaryTreeOptions>`, which means that not all properties of `BinaryTreeOptions` are
|
|
80
|
+
* required.
|
|
88
81
|
*/
|
|
89
|
-
constructor(options) {
|
|
82
|
+
constructor(elements, options) {
|
|
83
|
+
this.iterationType = types_1.IterationType.ITERATIVE;
|
|
90
84
|
this._defaultOneParamCallback = (node) => node.key;
|
|
91
85
|
if (options) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
86
|
+
const { iterationType } = options;
|
|
87
|
+
if (iterationType) {
|
|
88
|
+
this.iterationType = iterationType;
|
|
89
|
+
}
|
|
96
90
|
}
|
|
97
91
|
this._size = 0;
|
|
92
|
+
if (elements)
|
|
93
|
+
this.addMany(elements);
|
|
98
94
|
}
|
|
99
|
-
/**
|
|
100
|
-
* Get the root node of the binary tree.
|
|
101
|
-
*/
|
|
102
95
|
get root() {
|
|
103
96
|
return this._root;
|
|
104
97
|
}
|
|
105
|
-
/**
|
|
106
|
-
* Get the number of nodes in the binary tree.
|
|
107
|
-
*/
|
|
108
98
|
get size() {
|
|
109
99
|
return this._size;
|
|
110
100
|
}
|
|
@@ -117,35 +107,46 @@ class BinaryTree {
|
|
|
117
107
|
createNode(key, value) {
|
|
118
108
|
return new BinaryTreeNode(key, value);
|
|
119
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* The function creates a binary tree with the given options.
|
|
112
|
+
* @param [options] - The `options` parameter is an optional object that allows you to customize the
|
|
113
|
+
* behavior of the `BinaryTree` class. It is of type `Partial<BinaryTreeOptions>`, which means that
|
|
114
|
+
* you can provide only a subset of the properties defined in the `BinaryTreeOptions` interface.
|
|
115
|
+
* @returns a new instance of a binary tree.
|
|
116
|
+
*/
|
|
120
117
|
createTree(options) {
|
|
121
|
-
return new BinaryTree(Object.assign(
|
|
118
|
+
return new BinaryTree([], Object.assign({ iterationType: this.iterationType }, options));
|
|
122
119
|
}
|
|
123
120
|
/**
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
121
|
+
* The function checks if a given value is an entry in a binary tree node.
|
|
122
|
+
* @param kne - BTNodeExemplar<V, N> - A generic type representing a node in a binary tree. It has
|
|
123
|
+
* two type parameters V and N, representing the value and node type respectively.
|
|
124
|
+
* @returns a boolean value.
|
|
127
125
|
*/
|
|
126
|
+
isEntry(kne) {
|
|
127
|
+
return Array.isArray(kne) && kne.length === 2;
|
|
128
|
+
}
|
|
128
129
|
/**
|
|
129
|
-
* Time Complexity
|
|
130
|
-
* Space Complexity
|
|
130
|
+
* Time Complexity O(log n) - O(n)
|
|
131
|
+
* Space Complexity O(1)
|
|
132
|
+
*/
|
|
133
|
+
/**
|
|
134
|
+
* Time Complexity O(log n) - O(n)
|
|
135
|
+
* Space Complexity O(1)
|
|
131
136
|
*
|
|
132
|
-
* The `add` function adds a new node
|
|
133
|
-
*
|
|
134
|
-
* @
|
|
135
|
-
* following types:
|
|
136
|
-
* @param {V} [value] - The value to be associated with the key or node being added to the binary
|
|
137
|
-
* tree.
|
|
138
|
-
* @returns The function `add` returns a node (`N`) if it was successfully inserted into the binary
|
|
139
|
-
* tree, or `null` or `undefined` if the insertion was not successful.
|
|
137
|
+
* The `add` function adds a new node to a binary tree, either by key or by providing a node object.
|
|
138
|
+
* @param keyOrNodeOrEntry - The parameter `keyOrNodeOrEntry` can be one of the following:
|
|
139
|
+
* @returns The function `add` returns the inserted node (`N`), `null`, or `undefined`.
|
|
140
140
|
*/
|
|
141
|
-
add(
|
|
141
|
+
add(keyOrNodeOrEntry) {
|
|
142
|
+
let inserted, needInsert;
|
|
142
143
|
const _bfs = (root, newNode) => {
|
|
143
144
|
const queue = new queue_1.Queue([root]);
|
|
144
145
|
while (queue.size > 0) {
|
|
145
146
|
const cur = queue.shift();
|
|
146
147
|
if (newNode && cur.key === newNode.key) {
|
|
147
|
-
cur
|
|
148
|
-
return;
|
|
148
|
+
this._replaceNode(cur, newNode);
|
|
149
|
+
return newNode;
|
|
149
150
|
}
|
|
150
151
|
const inserted = this._addTo(newNode, cur);
|
|
151
152
|
if (inserted !== undefined)
|
|
@@ -156,15 +157,26 @@ class BinaryTree {
|
|
|
156
157
|
queue.push(cur.right);
|
|
157
158
|
}
|
|
158
159
|
};
|
|
159
|
-
|
|
160
|
-
if (keyOrNode === null) {
|
|
160
|
+
if (keyOrNodeOrEntry === null) {
|
|
161
161
|
needInsert = null;
|
|
162
162
|
}
|
|
163
|
-
else if (this.isNodeKey(
|
|
164
|
-
needInsert = this.createNode(
|
|
163
|
+
else if (this.isNodeKey(keyOrNodeOrEntry)) {
|
|
164
|
+
needInsert = this.createNode(keyOrNodeOrEntry);
|
|
165
165
|
}
|
|
166
|
-
else if (
|
|
167
|
-
needInsert =
|
|
166
|
+
else if (keyOrNodeOrEntry instanceof BinaryTreeNode) {
|
|
167
|
+
needInsert = keyOrNodeOrEntry;
|
|
168
|
+
}
|
|
169
|
+
else if (this.isEntry(keyOrNodeOrEntry)) {
|
|
170
|
+
const [key, value] = keyOrNodeOrEntry;
|
|
171
|
+
if (key === undefined) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
else if (key === null) {
|
|
175
|
+
needInsert = null;
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
needInsert = this.createNode(key, value);
|
|
179
|
+
}
|
|
168
180
|
}
|
|
169
181
|
else {
|
|
170
182
|
return;
|
|
@@ -185,35 +197,28 @@ class BinaryTree {
|
|
|
185
197
|
return inserted;
|
|
186
198
|
}
|
|
187
199
|
/**
|
|
188
|
-
* Time Complexity: O(k
|
|
200
|
+
* Time Complexity: O(k log n) - O(k * n)
|
|
189
201
|
* Space Complexity: O(1)
|
|
202
|
+
* Comments: The time complexity for adding a node depends on the depth of the tree. In the best case (when the tree is empty), it's O(1). In the worst case (when the tree is a degenerate tree), it's O(n). The space complexity is constant.
|
|
190
203
|
*/
|
|
191
204
|
/**
|
|
192
|
-
* Time Complexity: O(k
|
|
205
|
+
* Time Complexity: O(k log n) - O(k * n)
|
|
193
206
|
* Space Complexity: O(1)
|
|
194
207
|
*
|
|
195
|
-
* The `addMany`
|
|
196
|
-
*
|
|
197
|
-
* @param
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
|
|
204
|
-
*/
|
|
205
|
-
addMany(keysOrNodes, values) {
|
|
208
|
+
* The function `addMany` takes in an iterable of `BTNodeExemplar` objects, adds each object to the
|
|
209
|
+
* current instance, and returns an array of the inserted nodes.
|
|
210
|
+
* @param nodes - The `nodes` parameter is an iterable (such as an array or a set) of
|
|
211
|
+
* `BTNodeExemplar<V, N>` objects.
|
|
212
|
+
* @returns The function `addMany` returns an array of values, where each value is either of type
|
|
213
|
+
* `N`, `null`, or `undefined`.
|
|
214
|
+
*/
|
|
215
|
+
addMany(nodes) {
|
|
206
216
|
// TODO not sure addMany not be run multi times
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
return this.add(null);
|
|
213
|
-
}
|
|
214
|
-
const value = values === null || values === void 0 ? void 0 : values[i];
|
|
215
|
-
return this.add(keyOrNode, value);
|
|
216
|
-
});
|
|
217
|
+
const inserted = [];
|
|
218
|
+
for (const kne of nodes) {
|
|
219
|
+
inserted.push(this.add(kne));
|
|
220
|
+
}
|
|
221
|
+
return inserted;
|
|
217
222
|
}
|
|
218
223
|
/**
|
|
219
224
|
* Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
|
|
@@ -223,22 +228,14 @@ class BinaryTree {
|
|
|
223
228
|
* Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
|
|
224
229
|
* Space Complexity: O(1)
|
|
225
230
|
*
|
|
226
|
-
* The `refill` function clears the
|
|
227
|
-
* @param
|
|
228
|
-
* `
|
|
229
|
-
* @param {N[] | Array<V>} [values] - The `data` parameter is an optional array of values that will be assigned to
|
|
230
|
-
* the nodes being added. If provided, the length of the `data` array should be equal to the length of the `keysOrNodes`
|
|
231
|
-
* array. Each value in the `data` array will be assigned to the
|
|
232
|
-
* @returns The method is returning a boolean value.
|
|
231
|
+
* The `refill` function clears the current collection and adds new nodes, keys, or entries to it.
|
|
232
|
+
* @param nodesOrKeysOrEntries - The parameter `nodesOrKeysOrEntries` is an iterable object that can
|
|
233
|
+
* contain either `BTNodeExemplar` objects, keys, or entries.
|
|
233
234
|
*/
|
|
234
|
-
refill(
|
|
235
|
+
refill(nodesOrKeysOrEntries) {
|
|
235
236
|
this.clear();
|
|
236
|
-
|
|
237
|
+
this.addMany(nodesOrKeysOrEntries);
|
|
237
238
|
}
|
|
238
|
-
/**
|
|
239
|
-
* Time Complexity: O(n)
|
|
240
|
-
* Space Complexity: O(1)
|
|
241
|
-
*/
|
|
242
239
|
/**
|
|
243
240
|
* Time Complexity: O(n)
|
|
244
241
|
* Space Complexity: O(1)
|
|
@@ -287,7 +284,7 @@ class BinaryTree {
|
|
|
287
284
|
const leftSubTreeRightMost = this.getRightMost(curr.left);
|
|
288
285
|
if (leftSubTreeRightMost) {
|
|
289
286
|
const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
|
|
290
|
-
orgCurrent = this.
|
|
287
|
+
orgCurrent = this._swapProperties(curr, leftSubTreeRightMost);
|
|
291
288
|
if (parentOfLeftSubTreeMax) {
|
|
292
289
|
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
|
|
293
290
|
parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
|
|
@@ -320,8 +317,8 @@ class BinaryTree {
|
|
|
320
317
|
* @returns the depth of the `distNode` relative to the `beginRoot`.
|
|
321
318
|
*/
|
|
322
319
|
getDepth(distNode, beginRoot = this.root) {
|
|
323
|
-
distNode = this.
|
|
324
|
-
beginRoot = this.
|
|
320
|
+
distNode = this.ensureNode(distNode);
|
|
321
|
+
beginRoot = this.ensureNode(beginRoot);
|
|
325
322
|
let depth = 0;
|
|
326
323
|
while (distNode === null || distNode === void 0 ? void 0 : distNode.parent) {
|
|
327
324
|
if (distNode === beginRoot) {
|
|
@@ -334,8 +331,7 @@ class BinaryTree {
|
|
|
334
331
|
}
|
|
335
332
|
/**
|
|
336
333
|
* Time Complexity: O(n)
|
|
337
|
-
* Space Complexity: O(
|
|
338
|
-
* Best Case - O(log n) (when using recursive iterationType), Worst Case - O(n) (when using iterative iterationType)
|
|
334
|
+
* Space Complexity: O(1)
|
|
339
335
|
*/
|
|
340
336
|
/**
|
|
341
337
|
* Time Complexity: O(n)
|
|
@@ -351,8 +347,8 @@ class BinaryTree {
|
|
|
351
347
|
* values:
|
|
352
348
|
* @returns the height of the binary tree.
|
|
353
349
|
*/
|
|
354
|
-
getHeight(beginRoot = this.root, iterationType = this.
|
|
355
|
-
beginRoot = this.
|
|
350
|
+
getHeight(beginRoot = this.root, iterationType = this.iterationType) {
|
|
351
|
+
beginRoot = this.ensureNode(beginRoot);
|
|
356
352
|
if (!beginRoot)
|
|
357
353
|
return -1;
|
|
358
354
|
if (iterationType === types_1.IterationType.RECURSIVE) {
|
|
@@ -397,9 +393,9 @@ class BinaryTree {
|
|
|
397
393
|
* to calculate the minimum height of a binary tree. It can have two possible values:
|
|
398
394
|
* @returns The function `getMinHeight` returns the minimum height of a binary tree.
|
|
399
395
|
*/
|
|
400
|
-
getMinHeight(beginRoot = this.root, iterationType = this.
|
|
396
|
+
getMinHeight(beginRoot = this.root, iterationType = this.iterationType) {
|
|
401
397
|
var _a, _b, _c;
|
|
402
|
-
beginRoot = this.
|
|
398
|
+
beginRoot = this.ensureNode(beginRoot);
|
|
403
399
|
if (!beginRoot)
|
|
404
400
|
return -1;
|
|
405
401
|
if (iterationType === types_1.IterationType.RECURSIVE) {
|
|
@@ -445,6 +441,7 @@ class BinaryTree {
|
|
|
445
441
|
/**
|
|
446
442
|
* Time Complexity: O(n)
|
|
447
443
|
* Space Complexity: O(log n)
|
|
444
|
+
* Best Case - O(log n) (when using recursive iterationType), Worst Case - O(n) (when using iterative iterationType)
|
|
448
445
|
*/
|
|
449
446
|
/**
|
|
450
447
|
* Time Complexity: O(n)
|
|
@@ -460,10 +457,6 @@ class BinaryTree {
|
|
|
460
457
|
isPerfectlyBalanced(beginRoot = this.root) {
|
|
461
458
|
return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
|
|
462
459
|
}
|
|
463
|
-
/**
|
|
464
|
-
* Time Complexity: O(n)
|
|
465
|
-
* Space Complexity: O(log n).
|
|
466
|
-
*/
|
|
467
460
|
/**
|
|
468
461
|
* Time Complexity: O(n)
|
|
469
462
|
* Space Complexity: O(log n).
|
|
@@ -489,10 +482,10 @@ class BinaryTree {
|
|
|
489
482
|
* traverse the binary tree. It can have two possible values:
|
|
490
483
|
* @returns an array of nodes of type `N`.
|
|
491
484
|
*/
|
|
492
|
-
getNodes(identifier, callback = this._defaultOneParamCallback, onlyOne = false, beginRoot = this.root, iterationType = this.
|
|
485
|
+
getNodes(identifier, callback = this._defaultOneParamCallback, onlyOne = false, beginRoot = this.root, iterationType = this.iterationType) {
|
|
493
486
|
if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
|
|
494
487
|
callback = (node => node);
|
|
495
|
-
beginRoot = this.
|
|
488
|
+
beginRoot = this.ensureNode(beginRoot);
|
|
496
489
|
if (!beginRoot)
|
|
497
490
|
return [];
|
|
498
491
|
const ans = [];
|
|
@@ -527,10 +520,6 @@ class BinaryTree {
|
|
|
527
520
|
}
|
|
528
521
|
return ans;
|
|
529
522
|
}
|
|
530
|
-
/**
|
|
531
|
-
* Time Complexity: O(n)
|
|
532
|
-
* Space Complexity: O(log n).
|
|
533
|
-
*/
|
|
534
523
|
/**
|
|
535
524
|
* Time Complexity: O(n)
|
|
536
525
|
*
|
|
@@ -551,15 +540,11 @@ class BinaryTree {
|
|
|
551
540
|
* be performed in a pre-order, in-order, or post-order manner.
|
|
552
541
|
* @returns a boolean value.
|
|
553
542
|
*/
|
|
554
|
-
has(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.
|
|
543
|
+
has(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
|
|
555
544
|
if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
|
|
556
545
|
callback = (node => node);
|
|
557
546
|
return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
|
|
558
547
|
}
|
|
559
|
-
/**
|
|
560
|
-
* Time Complexity: O(n)
|
|
561
|
-
* Space Complexity: O(log n)
|
|
562
|
-
*/
|
|
563
548
|
/**
|
|
564
549
|
* Time Complexity: O(n)
|
|
565
550
|
* Space Complexity: O(log n)
|
|
@@ -581,7 +566,7 @@ class BinaryTree {
|
|
|
581
566
|
* nodes are visited during the search.
|
|
582
567
|
* @returns a value of type `N | null | undefined`.
|
|
583
568
|
*/
|
|
584
|
-
getNode(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.
|
|
569
|
+
getNode(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
|
|
585
570
|
var _a;
|
|
586
571
|
if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
|
|
587
572
|
callback = (node => node);
|
|
@@ -635,7 +620,11 @@ class BinaryTree {
|
|
|
635
620
|
}
|
|
636
621
|
}
|
|
637
622
|
/**
|
|
638
|
-
*
|
|
623
|
+
* Time Complexity: O(n)
|
|
624
|
+
* Space Complexity: O(log n)
|
|
625
|
+
*/
|
|
626
|
+
/**
|
|
627
|
+
* The function `ensureNode` returns the node corresponding to the given key if it is a valid node
|
|
639
628
|
* key, otherwise it returns the key itself.
|
|
640
629
|
* @param {BTNKey | N | null | undefined} key - The `key` parameter can be of type `BTNKey`, `N`,
|
|
641
630
|
* `null`, or `undefined`. It represents a key used to identify a node in a binary tree.
|
|
@@ -645,13 +634,9 @@ class BinaryTree {
|
|
|
645
634
|
* @returns either the node corresponding to the given key if it is a valid node key, or the key
|
|
646
635
|
* itself if it is not a valid node key.
|
|
647
636
|
*/
|
|
648
|
-
|
|
637
|
+
ensureNode(key, iterationType = types_1.IterationType.ITERATIVE) {
|
|
649
638
|
return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key;
|
|
650
639
|
}
|
|
651
|
-
/**
|
|
652
|
-
* Time Complexity: O(n)
|
|
653
|
-
* Space Complexity: O(log n)
|
|
654
|
-
*/
|
|
655
640
|
/**
|
|
656
641
|
* Time Complexity: O(n)
|
|
657
642
|
* Space Complexity: O(log n)
|
|
@@ -674,12 +659,16 @@ class BinaryTree {
|
|
|
674
659
|
* @returns The value of the node with the given identifier is being returned. If the node is not
|
|
675
660
|
* found, `undefined` is returned.
|
|
676
661
|
*/
|
|
677
|
-
get(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.
|
|
662
|
+
get(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
|
|
678
663
|
var _a, _b;
|
|
679
664
|
if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
|
|
680
665
|
callback = (node => node);
|
|
681
666
|
return (_b = (_a = this.getNode(identifier, callback, beginRoot, iterationType)) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : undefined;
|
|
682
667
|
}
|
|
668
|
+
/**
|
|
669
|
+
* Time Complexity: O(n)
|
|
670
|
+
* Space Complexity: O(log n)
|
|
671
|
+
*/
|
|
683
672
|
/**
|
|
684
673
|
* Clear the binary tree, removing all nodes.
|
|
685
674
|
*/
|
|
@@ -694,10 +683,6 @@ class BinaryTree {
|
|
|
694
683
|
isEmpty() {
|
|
695
684
|
return this.size === 0;
|
|
696
685
|
}
|
|
697
|
-
/**
|
|
698
|
-
* Time Complexity: O(log n)
|
|
699
|
-
* Space Complexity: O(log n)
|
|
700
|
-
*/
|
|
701
686
|
/**
|
|
702
687
|
* Time Complexity: O(log n)
|
|
703
688
|
* Space Complexity: O(log n)
|
|
@@ -715,7 +700,7 @@ class BinaryTree {
|
|
|
715
700
|
getPathToRoot(beginRoot, isReverse = true) {
|
|
716
701
|
// TODO to support get path through passing key
|
|
717
702
|
const result = [];
|
|
718
|
-
beginRoot = this.
|
|
703
|
+
beginRoot = this.ensureNode(beginRoot);
|
|
719
704
|
if (!beginRoot)
|
|
720
705
|
return result;
|
|
721
706
|
while (beginRoot.parent) {
|
|
@@ -729,7 +714,7 @@ class BinaryTree {
|
|
|
729
714
|
}
|
|
730
715
|
/**
|
|
731
716
|
* Time Complexity: O(log n)
|
|
732
|
-
* Space Complexity: O(
|
|
717
|
+
* Space Complexity: O(log n)
|
|
733
718
|
*/
|
|
734
719
|
/**
|
|
735
720
|
* Time Complexity: O(log n)
|
|
@@ -745,8 +730,8 @@ class BinaryTree {
|
|
|
745
730
|
* @returns The function `getLeftMost` returns the leftmost node (`N`) in the binary tree. If there
|
|
746
731
|
* is no leftmost node, it returns `null` or `undefined` depending on the input.
|
|
747
732
|
*/
|
|
748
|
-
getLeftMost(beginRoot = this.root, iterationType = this.
|
|
749
|
-
beginRoot = this.
|
|
733
|
+
getLeftMost(beginRoot = this.root, iterationType = this.iterationType) {
|
|
734
|
+
beginRoot = this.ensureNode(beginRoot);
|
|
750
735
|
if (!beginRoot)
|
|
751
736
|
return beginRoot;
|
|
752
737
|
if (iterationType === types_1.IterationType.RECURSIVE) {
|
|
@@ -786,9 +771,9 @@ class BinaryTree {
|
|
|
786
771
|
* @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If there
|
|
787
772
|
* is no rightmost node, it returns `null` or `undefined`, depending on the input.
|
|
788
773
|
*/
|
|
789
|
-
getRightMost(beginRoot = this.root, iterationType = this.
|
|
774
|
+
getRightMost(beginRoot = this.root, iterationType = this.iterationType) {
|
|
790
775
|
// TODO support get right most by passing key in
|
|
791
|
-
beginRoot = this.
|
|
776
|
+
beginRoot = this.ensureNode(beginRoot);
|
|
792
777
|
if (!beginRoot)
|
|
793
778
|
return beginRoot;
|
|
794
779
|
if (iterationType === types_1.IterationType.RECURSIVE) {
|
|
@@ -810,7 +795,7 @@ class BinaryTree {
|
|
|
810
795
|
}
|
|
811
796
|
}
|
|
812
797
|
/**
|
|
813
|
-
* Time Complexity: O(n)
|
|
798
|
+
* Time Complexity: O(log n)
|
|
814
799
|
* Space Complexity: O(1)
|
|
815
800
|
*/
|
|
816
801
|
/**
|
|
@@ -825,9 +810,9 @@ class BinaryTree {
|
|
|
825
810
|
* possible values:
|
|
826
811
|
* @returns a boolean value.
|
|
827
812
|
*/
|
|
828
|
-
isSubtreeBST(beginRoot, iterationType = this.
|
|
813
|
+
isSubtreeBST(beginRoot, iterationType = this.iterationType) {
|
|
829
814
|
// TODO there is a bug
|
|
830
|
-
beginRoot = this.
|
|
815
|
+
beginRoot = this.ensureNode(beginRoot);
|
|
831
816
|
if (!beginRoot)
|
|
832
817
|
return true;
|
|
833
818
|
if (iterationType === types_1.IterationType.RECURSIVE) {
|
|
@@ -872,15 +857,11 @@ class BinaryTree {
|
|
|
872
857
|
* expected to be
|
|
873
858
|
* @returns a boolean value.
|
|
874
859
|
*/
|
|
875
|
-
isBST(iterationType = this.
|
|
860
|
+
isBST(iterationType = this.iterationType) {
|
|
876
861
|
if (this.root === null)
|
|
877
862
|
return true;
|
|
878
863
|
return this.isSubtreeBST(this.root, iterationType);
|
|
879
864
|
}
|
|
880
|
-
/**
|
|
881
|
-
* Time complexity: O(n)
|
|
882
|
-
* Space complexity: O(log n)
|
|
883
|
-
*/
|
|
884
865
|
/**
|
|
885
866
|
* Time complexity: O(n)
|
|
886
867
|
* Space complexity: O(log n)
|
|
@@ -903,8 +884,8 @@ class BinaryTree {
|
|
|
903
884
|
* the `callback` function on each node in the subtree. The type of the array elements is determined
|
|
904
885
|
* by the return type of the `callback` function.
|
|
905
886
|
*/
|
|
906
|
-
subTreeTraverse(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.
|
|
907
|
-
beginRoot = this.
|
|
887
|
+
subTreeTraverse(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
|
|
888
|
+
beginRoot = this.ensureNode(beginRoot);
|
|
908
889
|
const ans = [];
|
|
909
890
|
if (!beginRoot)
|
|
910
891
|
return ans;
|
|
@@ -943,6 +924,10 @@ class BinaryTree {
|
|
|
943
924
|
}
|
|
944
925
|
return ans;
|
|
945
926
|
}
|
|
927
|
+
/**
|
|
928
|
+
* Time complexity: O(n)
|
|
929
|
+
* Space complexity: O(log n)
|
|
930
|
+
*/
|
|
946
931
|
/**
|
|
947
932
|
* The function checks if a given node is a real node by verifying if it is an instance of
|
|
948
933
|
* BinaryTreeNode and its key is not NaN.
|
|
@@ -977,10 +962,6 @@ class BinaryTree {
|
|
|
977
962
|
isNodeKey(potentialKey) {
|
|
978
963
|
return typeof potentialKey === 'number';
|
|
979
964
|
}
|
|
980
|
-
/**
|
|
981
|
-
* Time complexity: O(n)
|
|
982
|
-
* Space complexity: O(n)
|
|
983
|
-
*/
|
|
984
965
|
/**
|
|
985
966
|
* Time complexity: O(n)
|
|
986
967
|
* Space complexity: O(n)
|
|
@@ -1005,7 +986,7 @@ class BinaryTree {
|
|
|
1005
986
|
* @returns an array of values that are the return values of the callback function.
|
|
1006
987
|
*/
|
|
1007
988
|
dfs(callback = this._defaultOneParamCallback, pattern = 'in', beginRoot = this.root, iterationType = types_1.IterationType.ITERATIVE, includeNull = false) {
|
|
1008
|
-
beginRoot = this.
|
|
989
|
+
beginRoot = this.ensureNode(beginRoot);
|
|
1009
990
|
if (!beginRoot)
|
|
1010
991
|
return [];
|
|
1011
992
|
const ans = [];
|
|
@@ -1110,10 +1091,6 @@ class BinaryTree {
|
|
|
1110
1091
|
}
|
|
1111
1092
|
return ans;
|
|
1112
1093
|
}
|
|
1113
|
-
/**
|
|
1114
|
-
* Time complexity: O(n)
|
|
1115
|
-
* Space complexity: O(n)
|
|
1116
|
-
*/
|
|
1117
1094
|
/**
|
|
1118
1095
|
* Time complexity: O(n)
|
|
1119
1096
|
* Space complexity: O(n)
|
|
@@ -1135,8 +1112,8 @@ class BinaryTree {
|
|
|
1135
1112
|
* @returns an array of values that are the result of invoking the callback function on each node in
|
|
1136
1113
|
* the breadth-first traversal of a binary tree.
|
|
1137
1114
|
*/
|
|
1138
|
-
bfs(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.
|
|
1139
|
-
beginRoot = this.
|
|
1115
|
+
bfs(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
|
|
1116
|
+
beginRoot = this.ensureNode(beginRoot);
|
|
1140
1117
|
if (!beginRoot)
|
|
1141
1118
|
return [];
|
|
1142
1119
|
const ans = [];
|
|
@@ -1187,10 +1164,6 @@ class BinaryTree {
|
|
|
1187
1164
|
}
|
|
1188
1165
|
return ans;
|
|
1189
1166
|
}
|
|
1190
|
-
/**
|
|
1191
|
-
* Time complexity: O(n)
|
|
1192
|
-
* Space complexity: O(n)
|
|
1193
|
-
*/
|
|
1194
1167
|
/**
|
|
1195
1168
|
* Time complexity: O(n)
|
|
1196
1169
|
* Space complexity: O(n)
|
|
@@ -1212,8 +1185,8 @@ class BinaryTree {
|
|
|
1212
1185
|
* be excluded
|
|
1213
1186
|
* @returns The function `listLevels` returns a two-dimensional array of type `ReturnType<C>[][]`.
|
|
1214
1187
|
*/
|
|
1215
|
-
listLevels(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.
|
|
1216
|
-
beginRoot = this.
|
|
1188
|
+
listLevels(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
|
|
1189
|
+
beginRoot = this.ensureNode(beginRoot);
|
|
1217
1190
|
const levelsNodes = [];
|
|
1218
1191
|
if (!beginRoot)
|
|
1219
1192
|
return levelsNodes;
|
|
@@ -1268,7 +1241,7 @@ class BinaryTree {
|
|
|
1268
1241
|
* @returns The function `getPredecessor` returns a value of type `N | undefined`.
|
|
1269
1242
|
*/
|
|
1270
1243
|
getPredecessor(node) {
|
|
1271
|
-
node = this.
|
|
1244
|
+
node = this.ensureNode(node);
|
|
1272
1245
|
if (!this.isRealNode(node))
|
|
1273
1246
|
return undefined;
|
|
1274
1247
|
if (node.left) {
|
|
@@ -1291,7 +1264,7 @@ class BinaryTree {
|
|
|
1291
1264
|
* after the given node in the inorder traversal of the binary tree.
|
|
1292
1265
|
*/
|
|
1293
1266
|
getSuccessor(x) {
|
|
1294
|
-
x = this.
|
|
1267
|
+
x = this.ensureNode(x);
|
|
1295
1268
|
if (!x)
|
|
1296
1269
|
return undefined;
|
|
1297
1270
|
if (x.right) {
|
|
@@ -1304,10 +1277,6 @@ class BinaryTree {
|
|
|
1304
1277
|
}
|
|
1305
1278
|
return y;
|
|
1306
1279
|
}
|
|
1307
|
-
/**
|
|
1308
|
-
* Time complexity: O(n)
|
|
1309
|
-
* Space complexity: O(1)
|
|
1310
|
-
*/
|
|
1311
1280
|
/**
|
|
1312
1281
|
* Time complexity: O(n)
|
|
1313
1282
|
* Space complexity: O(1)
|
|
@@ -1327,7 +1296,7 @@ class BinaryTree {
|
|
|
1327
1296
|
* by the return type of the `callback` function.
|
|
1328
1297
|
*/
|
|
1329
1298
|
morris(callback = this._defaultOneParamCallback, pattern = 'in', beginRoot = this.root) {
|
|
1330
|
-
beginRoot = this.
|
|
1299
|
+
beginRoot = this.ensureNode(beginRoot);
|
|
1331
1300
|
if (beginRoot === null)
|
|
1332
1301
|
return [];
|
|
1333
1302
|
const ans = [];
|
|
@@ -1411,6 +1380,10 @@ class BinaryTree {
|
|
|
1411
1380
|
}
|
|
1412
1381
|
return ans;
|
|
1413
1382
|
}
|
|
1383
|
+
/**
|
|
1384
|
+
* Time complexity: O(n)
|
|
1385
|
+
* Space complexity: O(1)
|
|
1386
|
+
*/
|
|
1414
1387
|
/**
|
|
1415
1388
|
* The `forEach` function iterates over each entry in a tree and calls a callback function with the
|
|
1416
1389
|
* entry and the tree as arguments.
|
|
@@ -1434,19 +1407,11 @@ class BinaryTree {
|
|
|
1434
1407
|
const newTree = this.createTree();
|
|
1435
1408
|
for (const [key, value] of this) {
|
|
1436
1409
|
if (predicate([key, value], this)) {
|
|
1437
|
-
newTree.add(key, value);
|
|
1410
|
+
newTree.add([key, value]);
|
|
1438
1411
|
}
|
|
1439
1412
|
}
|
|
1440
1413
|
return newTree;
|
|
1441
1414
|
}
|
|
1442
|
-
// TODO Type error, need to return a TREE<NV> that is a value type only for callback function.
|
|
1443
|
-
// map<NV>(callback: (entry: [BTNKey, V | undefined], tree: this) => NV) {
|
|
1444
|
-
// const newTree = this.createTree();
|
|
1445
|
-
// for (const [key, value] of this) {
|
|
1446
|
-
// newTree.add(key, callback([key, value], this));
|
|
1447
|
-
// }
|
|
1448
|
-
// return newTree;
|
|
1449
|
-
// }
|
|
1450
1415
|
/**
|
|
1451
1416
|
* The `map` function creates a new tree by applying a callback function to each entry in the current
|
|
1452
1417
|
* tree.
|
|
@@ -1456,10 +1421,18 @@ class BinaryTree {
|
|
|
1456
1421
|
map(callback) {
|
|
1457
1422
|
const newTree = this.createTree();
|
|
1458
1423
|
for (const [key, value] of this) {
|
|
1459
|
-
newTree.add(key, callback([key, value], this));
|
|
1424
|
+
newTree.add([key, callback([key, value], this)]);
|
|
1460
1425
|
}
|
|
1461
1426
|
return newTree;
|
|
1462
1427
|
}
|
|
1428
|
+
// TODO Type error, need to return a TREE<NV> that is a value type only for callback function.
|
|
1429
|
+
// map<NV>(callback: (entry: [BTNKey, V | undefined], tree: this) => NV) {
|
|
1430
|
+
// const newTree = this.createTree();
|
|
1431
|
+
// for (const [key, value] of this) {
|
|
1432
|
+
// newTree.add(key, callback([key, value], this));
|
|
1433
|
+
// }
|
|
1434
|
+
// return newTree;
|
|
1435
|
+
// }
|
|
1463
1436
|
/**
|
|
1464
1437
|
* The `reduce` function iterates over the entries of a tree and applies a callback function to each
|
|
1465
1438
|
* entry, accumulating a single value.
|
|
@@ -1491,7 +1464,7 @@ class BinaryTree {
|
|
|
1491
1464
|
*[Symbol.iterator](node = this.root) {
|
|
1492
1465
|
if (!node)
|
|
1493
1466
|
return;
|
|
1494
|
-
if (this.
|
|
1467
|
+
if (this.iterationType === types_1.IterationType.ITERATIVE) {
|
|
1495
1468
|
const stack = [];
|
|
1496
1469
|
let current = node;
|
|
1497
1470
|
while (current || stack.length > 0) {
|
|
@@ -1525,7 +1498,7 @@ class BinaryTree {
|
|
|
1525
1498
|
*/
|
|
1526
1499
|
print(beginRoot = this.root, options) {
|
|
1527
1500
|
const opts = Object.assign({ isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false }, options);
|
|
1528
|
-
beginRoot = this.
|
|
1501
|
+
beginRoot = this.ensureNode(beginRoot);
|
|
1529
1502
|
if (!beginRoot)
|
|
1530
1503
|
return;
|
|
1531
1504
|
if (opts.isShowUndefined)
|
|
@@ -1594,9 +1567,9 @@ class BinaryTree {
|
|
|
1594
1567
|
* @param {N} destNode - The destination node to swap.
|
|
1595
1568
|
* @returns {N} - The destination node after the swap.
|
|
1596
1569
|
*/
|
|
1597
|
-
|
|
1598
|
-
srcNode = this.
|
|
1599
|
-
destNode = this.
|
|
1570
|
+
_swapProperties(srcNode, destNode) {
|
|
1571
|
+
srcNode = this.ensureNode(srcNode);
|
|
1572
|
+
destNode = this.ensureNode(destNode);
|
|
1600
1573
|
if (srcNode && destNode) {
|
|
1601
1574
|
const { key, value } = destNode;
|
|
1602
1575
|
const tempNode = this.createNode(key, value);
|
|
@@ -1610,6 +1583,31 @@ class BinaryTree {
|
|
|
1610
1583
|
}
|
|
1611
1584
|
return undefined;
|
|
1612
1585
|
}
|
|
1586
|
+
/**
|
|
1587
|
+
* The function replaces an old node with a new node in a binary tree.
|
|
1588
|
+
* @param {N} oldNode - The oldNode parameter represents the node that needs to be replaced in the
|
|
1589
|
+
* tree.
|
|
1590
|
+
* @param {N} newNode - The `newNode` parameter is the node that will replace the `oldNode` in the
|
|
1591
|
+
* tree.
|
|
1592
|
+
* @returns The method is returning the newNode.
|
|
1593
|
+
*/
|
|
1594
|
+
_replaceNode(oldNode, newNode) {
|
|
1595
|
+
if (oldNode.parent) {
|
|
1596
|
+
if (oldNode.parent.left === oldNode) {
|
|
1597
|
+
oldNode.parent.left = newNode;
|
|
1598
|
+
}
|
|
1599
|
+
else if (oldNode.parent.right === oldNode) {
|
|
1600
|
+
oldNode.parent.right = newNode;
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
newNode.left = oldNode.left;
|
|
1604
|
+
newNode.right = oldNode.right;
|
|
1605
|
+
newNode.parent = oldNode.parent;
|
|
1606
|
+
if (this.root === oldNode) {
|
|
1607
|
+
this._root = newNode;
|
|
1608
|
+
}
|
|
1609
|
+
return newNode;
|
|
1610
|
+
}
|
|
1613
1611
|
/**
|
|
1614
1612
|
* The function `_addTo` adds a new node to a binary tree if there is an available position.
|
|
1615
1613
|
* @param {N | null | undefined} newNode - The `newNode` parameter represents the node that you want to add to
|