data-structure-typed 1.19.6 → 1.19.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data-structures/binary-tree/abstract-binary-tree.d.ts +41 -58
- package/dist/data-structures/binary-tree/abstract-binary-tree.js +107 -145
- package/dist/data-structures/binary-tree/avl-tree.d.ts +1 -0
- package/dist/data-structures/binary-tree/avl-tree.js +4 -0
- package/dist/data-structures/binary-tree/binary-tree.d.ts +2 -1
- package/dist/data-structures/binary-tree/binary-tree.js +3 -0
- package/dist/data-structures/binary-tree/bst.d.ts +1 -0
- package/dist/data-structures/binary-tree/bst.js +4 -0
- package/dist/data-structures/binary-tree/rb-tree.d.ts +1 -1
- package/dist/data-structures/binary-tree/rb-tree.js +2 -3
- package/dist/data-structures/binary-tree/tree-multiset.d.ts +22 -16
- package/dist/data-structures/binary-tree/tree-multiset.js +138 -122
- package/dist/data-structures/interfaces/abstract-binary-tree.d.ts +6 -9
- package/dist/data-structures/types/abstract-binary-tree.d.ts +1 -2
- package/dist/data-structures/types/tree-multiset.d.ts +2 -2
- package/package.json +22 -5
- package/src/data-structures/binary-tree/abstract-binary-tree.ts +112 -161
- package/src/data-structures/binary-tree/avl-tree.ts +4 -0
- package/src/data-structures/binary-tree/binary-tree.ts +4 -2
- package/src/data-structures/binary-tree/bst.ts +4 -1
- package/src/data-structures/binary-tree/rb-tree.ts +3 -3
- package/src/data-structures/binary-tree/tree-multiset.ts +136 -118
- package/src/data-structures/interfaces/abstract-binary-tree.ts +6 -43
- package/src/data-structures/types/abstract-binary-tree.ts +1 -2
- package/src/data-structures/types/tree-multiset.ts +2 -2
- package/tsconfig.json +1 -2
- 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/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
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import {trampoline} from '../../utils';
|
|
10
10
|
import type {
|
|
11
11
|
AbstractBinaryTreeNodeNested,
|
|
12
12
|
AbstractBinaryTreeNodeProperties,
|
|
@@ -22,7 +22,6 @@ import {IAbstractBinaryTree, IAbstractBinaryTreeNode} from '../interfaces';
|
|
|
22
22
|
|
|
23
23
|
export abstract class AbstractBinaryTreeNode<T = any, NEIGHBOR extends AbstractBinaryTreeNode<T, NEIGHBOR> = AbstractBinaryTreeNodeNested<T>> implements IAbstractBinaryTreeNode<T, NEIGHBOR> {
|
|
24
24
|
|
|
25
|
-
|
|
26
25
|
/**
|
|
27
26
|
* The constructor function initializes a BinaryTreeNode object with an id and an optional value.
|
|
28
27
|
* @param {BinaryTreeNodeId} id - The `id` parameter is of type `BinaryTreeNodeId` and represents the unique identifier
|
|
@@ -30,7 +29,7 @@ export abstract class AbstractBinaryTreeNode<T = any, NEIGHBOR extends AbstractB
|
|
|
30
29
|
* @param {T} [val] - The "val" parameter is an optional parameter of type T. It represents the value that will be
|
|
31
30
|
* stored in the binary tree node. If no value is provided, it will be set to undefined.
|
|
32
31
|
*/
|
|
33
|
-
constructor(id: BinaryTreeNodeId, val?: T) {
|
|
32
|
+
protected constructor(id: BinaryTreeNodeId, val?: T) {
|
|
34
33
|
this._id = id;
|
|
35
34
|
this._val = val;
|
|
36
35
|
}
|
|
@@ -144,13 +143,15 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
144
143
|
if (options !== undefined) {
|
|
145
144
|
const {
|
|
146
145
|
loopType = LoopType.ITERATIVE,
|
|
147
|
-
|
|
148
|
-
isMergeDuplicatedVal = true
|
|
146
|
+
isMergeDuplicatedNodeById = true
|
|
149
147
|
} = options;
|
|
150
|
-
this.
|
|
151
|
-
this._autoIncrementId = autoIncrementId;
|
|
148
|
+
this._isMergeDuplicatedNodeById = isMergeDuplicatedNodeById;
|
|
152
149
|
this._loopType = loopType;
|
|
150
|
+
} else {
|
|
151
|
+
this._isMergeDuplicatedNodeById = true;
|
|
152
|
+
this._loopType = LoopType.ITERATIVE;
|
|
153
153
|
}
|
|
154
|
+
this.clear();
|
|
154
155
|
}
|
|
155
156
|
|
|
156
157
|
private _root: N | null = null;
|
|
@@ -159,7 +160,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
159
160
|
return this._root;
|
|
160
161
|
}
|
|
161
162
|
|
|
162
|
-
private _size = 0;
|
|
163
|
+
private _size: number = 0;
|
|
163
164
|
|
|
164
165
|
get size(): number {
|
|
165
166
|
return this._size;
|
|
@@ -171,23 +172,11 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
171
172
|
return this._loopType;
|
|
172
173
|
}
|
|
173
174
|
|
|
174
|
-
private _autoIncrementId: boolean = false;
|
|
175
|
-
|
|
176
|
-
get autoIncrementId(): boolean {
|
|
177
|
-
return this._autoIncrementId;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
private _maxId: number = -1;
|
|
181
|
-
|
|
182
|
-
get maxId(): number {
|
|
183
|
-
return this._maxId;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
175
|
// TODO this variable may be moved to TreeMultiset
|
|
187
|
-
private
|
|
176
|
+
private _isMergeDuplicatedNodeById: boolean = true;
|
|
188
177
|
|
|
189
|
-
get
|
|
190
|
-
return this.
|
|
178
|
+
get isMergeDuplicatedNodeById(): boolean {
|
|
179
|
+
return this._isMergeDuplicatedNodeById;
|
|
191
180
|
}
|
|
192
181
|
|
|
193
182
|
private _visitedId: BinaryTreeNodeId[] = [];
|
|
@@ -196,9 +185,9 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
196
185
|
return this._visitedId;
|
|
197
186
|
}
|
|
198
187
|
|
|
199
|
-
private _visitedVal:
|
|
188
|
+
private _visitedVal: N['val'][] = [];
|
|
200
189
|
|
|
201
|
-
get visitedVal():
|
|
190
|
+
get visitedVal(): N['val'][] {
|
|
202
191
|
return this._visitedVal;
|
|
203
192
|
}
|
|
204
193
|
|
|
@@ -208,12 +197,6 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
208
197
|
return this._visitedNode;
|
|
209
198
|
}
|
|
210
199
|
|
|
211
|
-
private _visitedCount: number[] = [];
|
|
212
|
-
|
|
213
|
-
get visitedCount(): number[] {
|
|
214
|
-
return this._visitedCount;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
200
|
private _visitedLeftSum: number[] = [];
|
|
218
201
|
|
|
219
202
|
get visitedLeftSum(): number[] {
|
|
@@ -230,21 +213,19 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
230
213
|
* @returns The `destNode` is being returned.
|
|
231
214
|
*/
|
|
232
215
|
swapLocation(srcNode: N, destNode: N): N {
|
|
233
|
-
const {val, height
|
|
216
|
+
const {id, val, height} = destNode;
|
|
234
217
|
const tempNode = this.createNode(id, val);
|
|
218
|
+
|
|
235
219
|
if (tempNode) {
|
|
236
220
|
tempNode.height = height;
|
|
237
221
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
destNode.val = srcNode.val;
|
|
242
|
-
destNode.height = srcNode.height;
|
|
222
|
+
destNode.id = srcNode.id;
|
|
223
|
+
destNode.val = srcNode.val;
|
|
224
|
+
destNode.height = srcNode.height;
|
|
243
225
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
226
|
+
srcNode.id = tempNode.id;
|
|
227
|
+
srcNode.val = tempNode.val;
|
|
228
|
+
srcNode.height = tempNode.height;
|
|
248
229
|
}
|
|
249
230
|
|
|
250
231
|
return destNode;
|
|
@@ -254,9 +235,9 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
254
235
|
* The clear() function resets the root, size, and maxId properties to their initial values.
|
|
255
236
|
*/
|
|
256
237
|
clear() {
|
|
257
|
-
this.
|
|
258
|
-
this.
|
|
259
|
-
this.
|
|
238
|
+
this._root = null;
|
|
239
|
+
this._size = 0;
|
|
240
|
+
this._clearResults();
|
|
260
241
|
}
|
|
261
242
|
|
|
262
243
|
/**
|
|
@@ -268,15 +249,20 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
268
249
|
}
|
|
269
250
|
|
|
270
251
|
/**
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
* @param [val] - The `val` parameter is an optional value that can be assigned to the node being added. If no value is
|
|
274
|
-
* provided, the default value will be the same as the `id` parameter.
|
|
275
|
-
* @param {number} [count] - The `count` parameter is an optional number that represents the number of times the value
|
|
276
|
-
* should be added to the binary tree. If not provided, the default value is `undefined`.
|
|
277
|
-
* @returns The function `add` returns either a `BinaryTreeNode` object (`N`), `null`, or `undefined`.
|
|
252
|
+
* When all leaf nodes are null, it will no longer be possible to add new entity nodes to this binary tree.
|
|
253
|
+
* In this scenario, null nodes serve as "sentinel nodes," "virtual nodes," or "placeholder nodes."
|
|
278
254
|
*/
|
|
279
|
-
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* The `add` function adds a new node to a binary tree, either by ID or by creating a new node with a given value.
|
|
258
|
+
* @param {BinaryTreeNodeId | N | null} idOrNode - The `idOrNode` parameter can be either a `BinaryTreeNodeId`, which
|
|
259
|
+
* is a number representing the ID of a binary tree node, or it can be a `N` object, which represents a binary tree
|
|
260
|
+
* node itself. It can also be `null` if no node is specified.
|
|
261
|
+
* @param [val] - The `val` parameter is an optional value that can be assigned to the `val` property of the new node
|
|
262
|
+
* being added to the binary tree.
|
|
263
|
+
* @returns The function `add` returns either the inserted node (`N`), `null`, or `undefined`.
|
|
264
|
+
*/
|
|
265
|
+
add(idOrNode: BinaryTreeNodeId | N | null, val?: N['val']): N | null | undefined {
|
|
280
266
|
const _bfs = (root: N, newNode: N | null): N | undefined | null => {
|
|
281
267
|
const queue: Array<N | null> = [root];
|
|
282
268
|
while (queue.length > 0) {
|
|
@@ -291,22 +277,33 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
291
277
|
return;
|
|
292
278
|
};
|
|
293
279
|
|
|
294
|
-
let inserted: N | null | undefined;
|
|
295
|
-
|
|
296
|
-
|
|
280
|
+
let inserted: N | null | undefined, needInsert: N | null;
|
|
281
|
+
|
|
282
|
+
if (idOrNode === null) {
|
|
283
|
+
needInsert = null;
|
|
284
|
+
} else if (typeof idOrNode === 'number') {
|
|
285
|
+
needInsert = this.createNode(idOrNode, val);
|
|
286
|
+
} else if (idOrNode instanceof AbstractBinaryTreeNode) {
|
|
287
|
+
needInsert = idOrNode;
|
|
288
|
+
} else {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const existNode = idOrNode ? this.get(idOrNode, 'id') : undefined;
|
|
293
|
+
|
|
297
294
|
if (this.root) {
|
|
298
295
|
if (existNode) {
|
|
299
|
-
existNode.val = val
|
|
300
|
-
|
|
301
|
-
inserted = existNode;
|
|
302
|
-
}
|
|
296
|
+
existNode.val = val;
|
|
297
|
+
inserted = existNode;
|
|
303
298
|
} else {
|
|
304
299
|
inserted = _bfs(this.root, needInsert);
|
|
305
300
|
}
|
|
306
301
|
} else {
|
|
307
|
-
this._setRoot(
|
|
302
|
+
this._setRoot(needInsert);
|
|
308
303
|
if (needInsert !== null) {
|
|
309
304
|
this._setSize(1);
|
|
305
|
+
} else {
|
|
306
|
+
this._setSize(0);
|
|
310
307
|
}
|
|
311
308
|
inserted = this.root;
|
|
312
309
|
}
|
|
@@ -324,22 +321,17 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
324
321
|
*/
|
|
325
322
|
addTo(newNode: N | null, parent: N): N | null | undefined {
|
|
326
323
|
if (parent) {
|
|
324
|
+
// When all leaf nodes are null, it will no longer be possible to add new entity nodes to this binary tree.
|
|
325
|
+
// In this scenario, null nodes serve as "sentinel nodes," "virtual nodes," or "placeholder nodes."
|
|
327
326
|
if (parent.left === undefined) {
|
|
328
|
-
if (newNode) {
|
|
329
|
-
newNode.parent = parent;
|
|
330
|
-
}
|
|
331
327
|
parent.left = newNode;
|
|
332
|
-
if (newNode
|
|
328
|
+
if (newNode) {
|
|
333
329
|
this._setSize(this.size + 1);
|
|
334
330
|
}
|
|
335
|
-
|
|
336
331
|
return parent.left;
|
|
337
332
|
} else if (parent.right === undefined) {
|
|
338
|
-
if (newNode) {
|
|
339
|
-
newNode.parent = parent;
|
|
340
|
-
}
|
|
341
333
|
parent.right = newNode;
|
|
342
|
-
if (newNode
|
|
334
|
+
if (newNode) {
|
|
343
335
|
this._setSize(this.size + 1);
|
|
344
336
|
}
|
|
345
337
|
return parent.right;
|
|
@@ -352,78 +344,60 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
352
344
|
}
|
|
353
345
|
|
|
354
346
|
/**
|
|
355
|
-
* The `addMany` function adds multiple nodes to a
|
|
347
|
+
* The `addMany` function adds multiple nodes to a tree data structure and returns an array of the inserted nodes or
|
|
356
348
|
* null/undefined values.
|
|
357
|
-
* @param {
|
|
358
|
-
*
|
|
359
|
-
* @
|
|
349
|
+
* @param {(BinaryTreeNodeId|N)[]} idsOrNodes - An array of BinaryTreeNodeId or N objects. These can be either the ID
|
|
350
|
+
* of a binary tree node or the actual node object itself.
|
|
351
|
+
* @param {N['val'][]} [data] - Optional array of values to be added to the nodes. If provided, the length of this
|
|
352
|
+
* array should be the same as the length of the `idsOrNodes` array.
|
|
353
|
+
* @returns The function `addMany` returns an array of values `(N | null | undefined)[]`.
|
|
360
354
|
*/
|
|
361
|
-
addMany(
|
|
355
|
+
addMany(idsOrNodes: (BinaryTreeNodeId | N | null)[], data?: N['val'][]): (N | null | undefined)[] {
|
|
362
356
|
// TODO not sure addMany not be run multi times
|
|
363
357
|
const inserted: (N | null | undefined)[] = [];
|
|
364
|
-
const map: Map<N |
|
|
358
|
+
const map: Map<N | BinaryTreeNodeId | null, number> = new Map();
|
|
365
359
|
|
|
366
|
-
if (this.
|
|
367
|
-
for (const
|
|
360
|
+
if (this.isMergeDuplicatedNodeById) {
|
|
361
|
+
for (const idOrNode of idsOrNodes) map.set(idOrNode, (map.get(idOrNode) ?? 0) + 1);
|
|
368
362
|
}
|
|
369
363
|
|
|
370
|
-
for (
|
|
371
|
-
|
|
372
|
-
if (
|
|
373
|
-
inserted.push(this.add(
|
|
374
|
-
continue;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
if (nodeOrId === null) {
|
|
378
|
-
inserted.push(this.add(NaN, null, 0));
|
|
364
|
+
for (let i = 0; i < idsOrNodes.length; i++) {
|
|
365
|
+
const idOrNode = idsOrNodes[i];
|
|
366
|
+
if (idOrNode instanceof AbstractBinaryTreeNode) {
|
|
367
|
+
inserted.push(this.add(idOrNode.id, idOrNode.val));
|
|
379
368
|
continue;
|
|
380
369
|
}
|
|
381
370
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
let newId: BinaryTreeNodeId;
|
|
385
|
-
if (typeof nodeOrId === 'number') {
|
|
386
|
-
newId = this.autoIncrementId ? this.maxId + 1 : nodeOrId;
|
|
387
|
-
} else if (nodeOrId instanceof Object) {
|
|
388
|
-
if (this.autoIncrementId) {
|
|
389
|
-
newId = this.maxId + 1;
|
|
390
|
-
} else {
|
|
391
|
-
if (Object.keys(nodeOrId).includes('id')) {
|
|
392
|
-
newId = (nodeOrId as ObjectWithNumberId).id;
|
|
393
|
-
} else {
|
|
394
|
-
console.warn(nodeOrId, 'Object value must has an id property when the autoIncrementId is false');
|
|
395
|
-
continue;
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
} else {
|
|
399
|
-
console.warn(nodeOrId, ` is not added`);
|
|
371
|
+
if (idOrNode === null) {
|
|
372
|
+
inserted.push(this.add(null));
|
|
400
373
|
continue;
|
|
401
374
|
}
|
|
402
375
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
376
|
+
const val = data?.[i];
|
|
377
|
+
if (this.isMergeDuplicatedNodeById) {
|
|
378
|
+
if (map.has(idOrNode)) {
|
|
379
|
+
inserted.push(this.add(idOrNode, val));
|
|
380
|
+
map.delete(idOrNode);
|
|
407
381
|
}
|
|
408
382
|
} else {
|
|
409
|
-
inserted.push(this.add(
|
|
383
|
+
inserted.push(this.add(idOrNode, val));
|
|
410
384
|
}
|
|
411
|
-
|
|
412
|
-
this._setMaxId(newId);
|
|
413
385
|
}
|
|
414
386
|
return inserted;
|
|
415
387
|
}
|
|
416
388
|
|
|
417
389
|
/**
|
|
418
|
-
* The `fill` function clears the
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
*
|
|
422
|
-
*
|
|
390
|
+
* The `fill` function clears the binary tree and adds multiple nodes with the given IDs or nodes and optional data.
|
|
391
|
+
* @param {(BinaryTreeNodeId | N)[]} idsOrNodes - The `idsOrNodes` parameter is an array that can contain either
|
|
392
|
+
* `BinaryTreeNodeId` or `N` values.
|
|
393
|
+
* @param {N[] | Array<N['val']>} [data] - The `data` parameter is an optional array of values that will be assigned to
|
|
394
|
+
* the nodes being added. If provided, the length of the `data` array should be equal to the length of the `idsOrNodes`
|
|
395
|
+
* array. Each value in the `data` array will be assigned to the
|
|
396
|
+
* @returns The method is returning a boolean value.
|
|
423
397
|
*/
|
|
424
|
-
fill(
|
|
398
|
+
fill(idsOrNodes: (BinaryTreeNodeId | N | null)[], data?: N[] | Array<N['val']>): boolean {
|
|
425
399
|
this.clear();
|
|
426
|
-
return
|
|
400
|
+
return idsOrNodes.length === this.addMany(idsOrNodes, data).length;
|
|
427
401
|
}
|
|
428
402
|
|
|
429
403
|
/**
|
|
@@ -652,6 +626,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
652
626
|
*/
|
|
653
627
|
has(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName): boolean {
|
|
654
628
|
propertyName = propertyName ?? 'id';
|
|
629
|
+
// TODO may support finding node by value equal
|
|
655
630
|
return this.getNodes(nodeProperty, propertyName).length > 0;
|
|
656
631
|
}
|
|
657
632
|
|
|
@@ -668,6 +643,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
668
643
|
*/
|
|
669
644
|
get(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName): N | null {
|
|
670
645
|
propertyName = propertyName ?? 'id';
|
|
646
|
+
// TODO may support finding node by value equal
|
|
671
647
|
return this.getNodes(nodeProperty, propertyName, true)[0] ?? null;
|
|
672
648
|
}
|
|
673
649
|
|
|
@@ -678,6 +654,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
678
654
|
* @returns The function `getPathToRoot` returns an array of nodes (`N[]`).
|
|
679
655
|
*/
|
|
680
656
|
getPathToRoot(node: N): N[] {
|
|
657
|
+
// TODO to support get path through passing id
|
|
681
658
|
const result: N[] = [];
|
|
682
659
|
while (node.parent) {
|
|
683
660
|
result.unshift(node);
|
|
@@ -741,6 +718,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
741
718
|
* function returns `null`.
|
|
742
719
|
*/
|
|
743
720
|
getRightMost(node?: N | null): N | null {
|
|
721
|
+
// TODO support get right most by passing id in
|
|
744
722
|
node = node ?? this.root;
|
|
745
723
|
if (!node) return node;
|
|
746
724
|
|
|
@@ -767,7 +745,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
767
745
|
* @param {N | null} node - The `node` parameter represents the root node of a binary search tree (BST).
|
|
768
746
|
* @returns a boolean value.
|
|
769
747
|
*/
|
|
770
|
-
|
|
748
|
+
isSubtreeBST(node: N | null): boolean {
|
|
771
749
|
// TODO there is a bug
|
|
772
750
|
if (!node) return true;
|
|
773
751
|
|
|
@@ -797,13 +775,11 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
797
775
|
}
|
|
798
776
|
|
|
799
777
|
/**
|
|
800
|
-
* The function checks if
|
|
801
|
-
* @
|
|
802
|
-
* search tree (BST).
|
|
803
|
-
* @returns a boolean value.
|
|
778
|
+
* The function isBST checks if the binary search tree is valid.
|
|
779
|
+
* @returns The `isBST()` function is returning a boolean value.
|
|
804
780
|
*/
|
|
805
|
-
isBST(
|
|
806
|
-
return this.
|
|
781
|
+
isBST(): boolean {
|
|
782
|
+
return this.isSubtreeBST(this.root);
|
|
807
783
|
}
|
|
808
784
|
|
|
809
785
|
/**
|
|
@@ -813,6 +789,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
813
789
|
* @returns the size of the subtree rooted at `subTreeRoot`.
|
|
814
790
|
*/
|
|
815
791
|
getSubTreeSize(subTreeRoot: N | null | undefined) {
|
|
792
|
+
// TODO support id passed in
|
|
816
793
|
let size = 0;
|
|
817
794
|
if (!subTreeRoot) return size;
|
|
818
795
|
|
|
@@ -962,7 +939,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
962
939
|
*/
|
|
963
940
|
BFS(nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
|
|
964
941
|
nodeOrPropertyName = nodeOrPropertyName ?? 'id';
|
|
965
|
-
this.
|
|
942
|
+
this._clearResults();
|
|
966
943
|
const queue: Array<N | null | undefined> = [this.root];
|
|
967
944
|
|
|
968
945
|
while (queue.length !== 0) {
|
|
@@ -999,7 +976,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
999
976
|
DFS(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
|
|
1000
977
|
pattern = pattern ?? 'in';
|
|
1001
978
|
nodeOrPropertyName = nodeOrPropertyName ?? 'id';
|
|
1002
|
-
this.
|
|
979
|
+
this._clearResults();
|
|
1003
980
|
const _traverse = (node: N) => {
|
|
1004
981
|
switch (pattern) {
|
|
1005
982
|
case 'in':
|
|
@@ -1049,7 +1026,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
1049
1026
|
DFSIterative(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
|
|
1050
1027
|
pattern = pattern || 'in';
|
|
1051
1028
|
nodeOrPropertyName = nodeOrPropertyName || 'id';
|
|
1052
|
-
this.
|
|
1029
|
+
this._clearResults();
|
|
1053
1030
|
if (!this.root) return this._getResultByPropertyName(nodeOrPropertyName);
|
|
1054
1031
|
// 0: visit, 1: print
|
|
1055
1032
|
const stack: { opt: 0 | 1, node: N | null | undefined }[] = [{opt: 0, node: this.root}];
|
|
@@ -1113,7 +1090,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
1113
1090
|
node = node || this.root;
|
|
1114
1091
|
if (!node) return [];
|
|
1115
1092
|
|
|
1116
|
-
this.
|
|
1093
|
+
this._clearResults();
|
|
1117
1094
|
const queue: N[] = [node];
|
|
1118
1095
|
|
|
1119
1096
|
while (queue.length > 0) {
|
|
@@ -1247,7 +1224,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
1247
1224
|
pattern = pattern || 'in';
|
|
1248
1225
|
nodeOrPropertyName = nodeOrPropertyName || 'id';
|
|
1249
1226
|
|
|
1250
|
-
this.
|
|
1227
|
+
this._clearResults();
|
|
1251
1228
|
|
|
1252
1229
|
let cur: N | null | undefined = this.root;
|
|
1253
1230
|
const _reverseEdge = (node: N | null | undefined) => {
|
|
@@ -1359,14 +1336,6 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
1359
1336
|
this._visitedNode = value;
|
|
1360
1337
|
}
|
|
1361
1338
|
|
|
1362
|
-
/**
|
|
1363
|
-
* The function sets the value of the visitedCount property.
|
|
1364
|
-
* @param {number[]} value - The value parameter is an array of numbers.
|
|
1365
|
-
*/
|
|
1366
|
-
protected setVisitedCount(value: number[]) {
|
|
1367
|
-
this._visitedCount = value;
|
|
1368
|
-
}
|
|
1369
|
-
|
|
1370
1339
|
/**
|
|
1371
1340
|
* The function sets the value of the `_visitedLeftSum` property to the provided array.
|
|
1372
1341
|
* @param {number[]} value - An array of numbers that represents the visited left sum.
|
|
@@ -1376,30 +1345,12 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
1376
1345
|
}
|
|
1377
1346
|
|
|
1378
1347
|
/**
|
|
1379
|
-
* The function sets the value of
|
|
1380
|
-
* @param {boolean} value - The value parameter is a boolean that determines whether the
|
|
1381
|
-
* incremented or not. If value is true, the id will be automatically incremented. If value is false, the id will not
|
|
1382
|
-
* be automatically incremented.
|
|
1383
|
-
*/
|
|
1384
|
-
protected _setAutoIncrementId(value: boolean) {
|
|
1385
|
-
this._autoIncrementId = value;
|
|
1386
|
-
}
|
|
1387
|
-
|
|
1388
|
-
/**
|
|
1389
|
-
* The function sets the maximum ID value.
|
|
1390
|
-
* @param {number} value - The value parameter is a number that represents the new maximum ID value.
|
|
1391
|
-
*/
|
|
1392
|
-
protected _setMaxId(value: number) {
|
|
1393
|
-
this._maxId = value;
|
|
1394
|
-
}
|
|
1395
|
-
|
|
1396
|
-
/**
|
|
1397
|
-
* The function sets the value of a protected property called "_isMergeDuplicatedVal".
|
|
1398
|
-
* @param {boolean} value - The value parameter is a boolean value that determines whether the isMergeDuplicatedVal
|
|
1348
|
+
* The function sets the value of a protected property called "_isMergeDuplicatedNodeById".
|
|
1349
|
+
* @param {boolean} value - The value parameter is a boolean value that determines whether the isMergeDuplicatedNodeById
|
|
1399
1350
|
* property should be set to true or false.
|
|
1400
1351
|
*/
|
|
1401
1352
|
protected _setIsDuplicatedVal(value: boolean) {
|
|
1402
|
-
this.
|
|
1353
|
+
this._isMergeDuplicatedNodeById = value;
|
|
1403
1354
|
}
|
|
1404
1355
|
|
|
1405
1356
|
/**
|
|
@@ -1423,10 +1374,10 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|
|
1423
1374
|
}
|
|
1424
1375
|
|
|
1425
1376
|
/**
|
|
1426
|
-
* The function `
|
|
1377
|
+
* The function `_clearResults` resets the values of several arrays used for tracking visited nodes and their
|
|
1427
1378
|
* properties.
|
|
1428
1379
|
*/
|
|
1429
|
-
protected
|
|
1380
|
+
protected _clearResults() {
|
|
1430
1381
|
this._visitedId = [];
|
|
1431
1382
|
this._visitedVal = [];
|
|
1432
1383
|
this._visitedNode = [];
|
|
@@ -10,6 +10,9 @@ import type {AVLTreeNodeNested, AVLTreeOptions, BinaryTreeDeletedResult, BinaryT
|
|
|
10
10
|
import {IAVLTree, IAVLTreeNode} from '../interfaces';
|
|
11
11
|
|
|
12
12
|
export class AVLTreeNode<T = any, NEIGHBOR extends AVLTreeNode<T, NEIGHBOR> = AVLTreeNodeNested<T>> extends BSTNode<T, NEIGHBOR> implements IAVLTreeNode<T, NEIGHBOR> {
|
|
13
|
+
constructor(id: BinaryTreeNodeId, val?: T) {
|
|
14
|
+
super(id, val);
|
|
15
|
+
}
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode> extends BST<N> implements IAVLTree<N> {
|
|
@@ -43,6 +46,7 @@ export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode> extends B
|
|
|
43
46
|
* @returns The method is returning the inserted node, or null or undefined if the insertion was not successful.
|
|
44
47
|
*/
|
|
45
48
|
override add(id: BinaryTreeNodeId, val?: N['val']): N | null | undefined {
|
|
49
|
+
// TODO support node as a param
|
|
46
50
|
const inserted = super.add(id, val);
|
|
47
51
|
if (inserted) this.balancePath(inserted);
|
|
48
52
|
return inserted;
|
|
@@ -8,10 +8,12 @@
|
|
|
8
8
|
|
|
9
9
|
import type {BinaryTreeNodeId, BinaryTreeNodeNested, BinaryTreeOptions} from '../types';
|
|
10
10
|
import {AbstractBinaryTree, AbstractBinaryTreeNode} from './abstract-binary-tree';
|
|
11
|
-
import {IBinaryTree, IBinaryTreeNode} from '../interfaces
|
|
11
|
+
import {IBinaryTree, IBinaryTreeNode} from '../interfaces';
|
|
12
12
|
|
|
13
13
|
export class BinaryTreeNode<T = any, NEIGHBOR extends BinaryTreeNode<T, NEIGHBOR> = BinaryTreeNodeNested<T>> extends AbstractBinaryTreeNode<T, NEIGHBOR> implements IBinaryTreeNode<T, NEIGHBOR> {
|
|
14
|
-
|
|
14
|
+
constructor(id: BinaryTreeNodeId, val?: T) {
|
|
15
|
+
super(id, val);
|
|
16
|
+
}
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode> extends AbstractBinaryTree<N> implements IBinaryTree<N> {
|
|
@@ -11,7 +11,9 @@ import {BinaryTree, BinaryTreeNode} from './binary-tree';
|
|
|
11
11
|
import {IBST, IBSTNode} from '../interfaces';
|
|
12
12
|
|
|
13
13
|
export class BSTNode<T = any, NEIGHBOR extends BSTNode<T, NEIGHBOR> = BSTNodeNested<T>> extends BinaryTreeNode<T, NEIGHBOR> implements IBSTNode<T, NEIGHBOR> {
|
|
14
|
-
|
|
14
|
+
constructor(id: BinaryTreeNodeId, val?: T) {
|
|
15
|
+
super(id, val);
|
|
16
|
+
}
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N> implements IBST<N> {
|
|
@@ -51,6 +53,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
|
|
|
51
53
|
* If the node was not added (e.g., due to a duplicate ID), it returns `null` or `undefined`.
|
|
52
54
|
*/
|
|
53
55
|
override add(id: BinaryTreeNodeId, val?: N['val']): N | null | undefined {
|
|
56
|
+
// TODO support node as a param
|
|
54
57
|
let inserted: N | null = null;
|
|
55
58
|
const newNode = this.createNode(id, val);
|
|
56
59
|
if (this.root === null) {
|
|
@@ -4,12 +4,12 @@ import {BST, BSTNode} from './bst';
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
export class RBTreeNode<T = any, NEIGHBOR extends RBTreeNode<T, NEIGHBOR> = RBTreeNodeNested<T>> extends BSTNode<T, NEIGHBOR> implements IRBTreeNode<T, NEIGHBOR> {
|
|
7
|
-
constructor(id: BinaryTreeNodeId, color: RBColor
|
|
7
|
+
constructor(id: BinaryTreeNodeId, val?: T, color: RBColor = RBColor.RED) {
|
|
8
8
|
super(id, val);
|
|
9
9
|
this._color = color;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
private _color: RBColor
|
|
12
|
+
private _color: RBColor;
|
|
13
13
|
|
|
14
14
|
get color(): RBColor {
|
|
15
15
|
return this._color;
|
|
@@ -60,7 +60,7 @@ export class RBTree<N extends RBTreeNode<N['val'], N> = RBTreeNode> extends BST<
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
override createNode(id: BinaryTreeNodeId, val?: N['val']): N {
|
|
63
|
-
return new RBTreeNode(id, RBColor.RED
|
|
63
|
+
return new RBTreeNode(id, val, RBColor.RED) as N;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
// private override _root: BinaryTreeNode<N> | null = null;
|