min-heap-typed 1.42.3 → 1.42.5
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/.prettierignore +1 -1
- package/README.md +1 -1
- package/dist/data-structures/binary-tree/avl-tree.d.ts +2 -2
- package/dist/data-structures/binary-tree/avl-tree.js +5 -3
- package/dist/data-structures/binary-tree/binary-tree.d.ts +56 -52
- package/dist/data-structures/binary-tree/binary-tree.js +115 -53
- package/dist/data-structures/binary-tree/bst.d.ts +42 -15
- package/dist/data-structures/binary-tree/bst.js +77 -21
- package/dist/data-structures/binary-tree/index.d.ts +1 -1
- package/dist/data-structures/binary-tree/index.js +1 -1
- package/dist/data-structures/binary-tree/rb-tree.d.ts +28 -51
- package/dist/data-structures/binary-tree/rb-tree.js +148 -180
- package/dist/data-structures/binary-tree/{tree-multiset.d.ts → tree-multimap.d.ts} +20 -20
- package/dist/data-structures/binary-tree/{tree-multiset.js → tree-multimap.js} +34 -31
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/index.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/index.js +1 -1
- package/dist/types/data-structures/binary-tree/rb-tree.d.ts +4 -0
- package/dist/types/data-structures/binary-tree/rb-tree.js +0 -5
- package/dist/types/data-structures/binary-tree/tree-multimap.d.ts +4 -0
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree.ts +5 -4
- package/src/data-structures/binary-tree/binary-tree.ts +201 -131
- package/src/data-structures/binary-tree/bst.ts +100 -34
- package/src/data-structures/binary-tree/index.ts +1 -1
- package/src/data-structures/binary-tree/rb-tree.ts +227 -236
- package/src/data-structures/binary-tree/{tree-multiset.ts → tree-multimap.ts} +38 -37
- package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
- package/src/types/data-structures/binary-tree/index.ts +1 -1
- package/src/types/data-structures/binary-tree/rb-tree.ts +5 -5
- package/src/types/data-structures/binary-tree/tree-multimap.ts +6 -0
- package/dist/types/data-structures/binary-tree/tree-multiset.d.ts +0 -4
- package/src/types/data-structures/binary-tree/tree-multiset.ts +0 -6
- /package/dist/types/data-structures/binary-tree/{tree-multiset.js → tree-multimap.js} +0 -0
|
@@ -123,12 +123,12 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
protected _root: N | null =
|
|
126
|
+
protected _root: N | null | undefined = undefined;
|
|
127
127
|
|
|
128
128
|
/**
|
|
129
129
|
* Get the root node of the binary tree.
|
|
130
130
|
*/
|
|
131
|
-
get root(): N | null {
|
|
131
|
+
get root(): N | null | undefined {
|
|
132
132
|
return this._root;
|
|
133
133
|
}
|
|
134
134
|
|
|
@@ -155,7 +155,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
155
155
|
* Clear the binary tree, removing all nodes.
|
|
156
156
|
*/
|
|
157
157
|
clear() {
|
|
158
|
-
this._setRoot(
|
|
158
|
+
this._setRoot(undefined);
|
|
159
159
|
this._size = 0;
|
|
160
160
|
}
|
|
161
161
|
|
|
@@ -173,7 +173,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
173
173
|
* @param {V} value - The value for the new node (optional).
|
|
174
174
|
* @returns {N | null | undefined} - The inserted node, or null if nothing was inserted, or undefined if the operation failed.
|
|
175
175
|
*/
|
|
176
|
-
add(keyOrNode: BTNKey | N | null, value?: V): N | null | undefined {
|
|
176
|
+
add(keyOrNode: BTNKey | N | null | undefined, value?: V): N | null | undefined {
|
|
177
177
|
const _bfs = (root: N, newNode: N | null): N | undefined | null => {
|
|
178
178
|
const queue = new Queue<N | null>([root]);
|
|
179
179
|
while (queue.size > 0) {
|
|
@@ -236,7 +236,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
236
236
|
* the value of the nodes will be `undefined`.
|
|
237
237
|
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
|
|
238
238
|
*/
|
|
239
|
-
addMany(keysOrNodes: (BTNKey | null)[] | (N | null)[], values?: V[]): (N | null | undefined)[] {
|
|
239
|
+
addMany(keysOrNodes: (BTNKey | null | undefined)[] | (N | null | undefined)[], values?: V[]): (N | null | undefined)[] {
|
|
240
240
|
// TODO not sure addMany not be run multi times
|
|
241
241
|
return keysOrNodes.map((keyOrNode, i) => {
|
|
242
242
|
if (keyOrNode instanceof BinaryTreeNode) {
|
|
@@ -261,14 +261,14 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
261
261
|
* array. Each value in the `data` array will be assigned to the
|
|
262
262
|
* @returns The method is returning a boolean value.
|
|
263
263
|
*/
|
|
264
|
-
refill(keysOrNodes: (BTNKey | null)[] | (N | null)[], data?: Array<V>): boolean {
|
|
264
|
+
refill(keysOrNodes: (BTNKey | null | undefined)[] | (N | null | undefined)[], data?: Array<V>): boolean {
|
|
265
265
|
this.clear();
|
|
266
266
|
return keysOrNodes.length === this.addMany(keysOrNodes, data).length;
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
delete<C extends BTNCallback<N, BTNKey>>(identifier: BTNKey, callback?: C): BinaryTreeDeletedResult<N>[];
|
|
270
270
|
|
|
271
|
-
delete<C extends BTNCallback<N, N>>(identifier: N | null, callback?: C): BinaryTreeDeletedResult<N>[];
|
|
271
|
+
delete<C extends BTNCallback<N, N>>(identifier: N | null | undefined, callback?: C): BinaryTreeDeletedResult<N>[];
|
|
272
272
|
|
|
273
273
|
delete<C extends BTNCallback<N>>(identifier: ReturnType<C>, callback: C): BinaryTreeDeletedResult<N>[];
|
|
274
274
|
|
|
@@ -287,7 +287,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
287
287
|
* `this.defaultOneParamCallback`, which
|
|
288
288
|
*/
|
|
289
289
|
delete<C extends BTNCallback<N>>(
|
|
290
|
-
identifier: ReturnType<C> | null,
|
|
290
|
+
identifier: ReturnType<C> | null | undefined,
|
|
291
291
|
callback: C = this.defaultOneParamCallback as C
|
|
292
292
|
): BinaryTreeDeletedResult<N>[] {
|
|
293
293
|
const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
|
|
@@ -297,8 +297,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
297
297
|
const curr = this.getNode(identifier, callback);
|
|
298
298
|
if (!curr) return bstDeletedResult;
|
|
299
299
|
|
|
300
|
-
const parent: N | null = curr?.parent ? curr.parent : null;
|
|
301
|
-
let needBalanced: N | null = null,
|
|
300
|
+
const parent: N | null | undefined = curr?.parent ? curr.parent : null;
|
|
301
|
+
let needBalanced: N | null | undefined = null,
|
|
302
302
|
orgCurrent = curr;
|
|
303
303
|
|
|
304
304
|
if (!curr.left) {
|
|
@@ -336,16 +336,16 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
336
336
|
/**
|
|
337
337
|
* The function `getDepth` calculates the depth of a given node in a binary tree relative to a
|
|
338
338
|
* specified root node.
|
|
339
|
-
* @param {BTNKey | N | null} distNode - The `distNode` parameter represents the node
|
|
339
|
+
* @param {BTNKey | N | null | undefined} distNode - The `distNode` parameter represents the node
|
|
340
340
|
* whose depth we want to find in the binary tree. It can be either a node object (`N`), a key value
|
|
341
341
|
* of the node (`BTNKey`), or `null`.
|
|
342
|
-
* @param {BTNKey | N | null} beginRoot - The `beginRoot` parameter represents the
|
|
342
|
+
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
|
|
343
343
|
* starting node from which we want to calculate the depth. It can be either a node object or the key
|
|
344
344
|
* of a node in the binary tree. If no value is provided for `beginRoot`, it defaults to the root
|
|
345
345
|
* node of the binary tree.
|
|
346
346
|
* @returns the depth of the `distNode` relative to the `beginRoot`.
|
|
347
347
|
*/
|
|
348
|
-
getDepth(distNode: BTNKey | N | null, beginRoot: BTNKey | N | null = this.root): number {
|
|
348
|
+
getDepth(distNode: BTNKey | N | null | undefined, beginRoot: BTNKey | N | null | undefined = this.root): number {
|
|
349
349
|
if (typeof distNode === 'number') distNode = this.getNode(distNode);
|
|
350
350
|
if (typeof beginRoot === 'number') beginRoot = this.getNode(beginRoot);
|
|
351
351
|
let depth = 0;
|
|
@@ -362,7 +362,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
362
362
|
/**
|
|
363
363
|
* The `getHeight` function calculates the maximum height of a binary tree using either recursive or
|
|
364
364
|
* iterative approach.
|
|
365
|
-
* @param {BTNKey | N | null} beginRoot - The `beginRoot` parameter represents the
|
|
365
|
+
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
|
|
366
366
|
* starting node from which the height of the binary tree is calculated. It can be either a node
|
|
367
367
|
* object (`N`), a key value of a node in the tree (`BTNKey`), or `null` if no starting
|
|
368
368
|
* node is specified. If `
|
|
@@ -371,7 +371,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
371
371
|
* possible values:
|
|
372
372
|
* @returns the height of the binary tree.
|
|
373
373
|
*/
|
|
374
|
-
getHeight(beginRoot: BTNKey | N | null = this.root, iterationType = this.iterationType): number {
|
|
374
|
+
getHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): number {
|
|
375
375
|
if (typeof beginRoot === 'number') beginRoot = this.getNode(beginRoot);
|
|
376
376
|
if (!beginRoot) return -1;
|
|
377
377
|
|
|
@@ -413,14 +413,14 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
413
413
|
/**
|
|
414
414
|
* The `getMinHeight` function calculates the minimum height of a binary tree using either a
|
|
415
415
|
* recursive or iterative approach.
|
|
416
|
-
* @param {N | null} beginRoot - The `beginRoot` parameter is the starting node from which we want to
|
|
416
|
+
* @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node from which we want to
|
|
417
417
|
* calculate the minimum height of the tree. It is optional and defaults to the root of the tree if
|
|
418
418
|
* not provided.
|
|
419
419
|
* @param iterationType - The `iterationType` parameter is used to determine the method of iteration
|
|
420
420
|
* to calculate the minimum height of a binary tree. It can have two possible values:
|
|
421
421
|
* @returns The function `getMinHeight` returns the minimum height of a binary tree.
|
|
422
422
|
*/
|
|
423
|
-
getMinHeight(beginRoot: N | null = this.root, iterationType = this.iterationType): number {
|
|
423
|
+
getMinHeight(beginRoot: N | null | undefined = this.root, iterationType = this.iterationType): number {
|
|
424
424
|
if (!beginRoot) return -1;
|
|
425
425
|
|
|
426
426
|
if (iterationType === IterationType.RECURSIVE) {
|
|
@@ -436,7 +436,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
436
436
|
} else {
|
|
437
437
|
const stack: N[] = [];
|
|
438
438
|
let node: N | null | undefined = beginRoot,
|
|
439
|
-
last: N | null = null;
|
|
439
|
+
last: N | null | undefined = null;
|
|
440
440
|
const depths: Map<N, number> = new Map();
|
|
441
441
|
|
|
442
442
|
while (stack.length > 0 || node) {
|
|
@@ -465,11 +465,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
465
465
|
/**
|
|
466
466
|
* The function checks if a binary tree is perfectly balanced by comparing the minimum height and the
|
|
467
467
|
* height of the tree.
|
|
468
|
-
* @param {N | null} beginRoot - The parameter `beginRoot` is of type `N | null`, which means it can
|
|
468
|
+
* @param {N | null | undefined} beginRoot - The parameter `beginRoot` is of type `N | null | undefined`, which means it can
|
|
469
469
|
* either be of type `N` (representing a node in a tree) or `null` (representing an empty tree).
|
|
470
470
|
* @returns The method is returning a boolean value.
|
|
471
471
|
*/
|
|
472
|
-
isPerfectlyBalanced(beginRoot: N | null = this.root): boolean {
|
|
472
|
+
isPerfectlyBalanced(beginRoot: N | null | undefined = this.root): boolean {
|
|
473
473
|
return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
|
|
474
474
|
}
|
|
475
475
|
|
|
@@ -477,15 +477,15 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
477
477
|
identifier: BTNKey,
|
|
478
478
|
callback?: C,
|
|
479
479
|
onlyOne?: boolean,
|
|
480
|
-
beginRoot?: N | null,
|
|
480
|
+
beginRoot?: N | null | undefined,
|
|
481
481
|
iterationType?: IterationType
|
|
482
482
|
): N[];
|
|
483
483
|
|
|
484
484
|
getNodes<C extends BTNCallback<N, N>>(
|
|
485
|
-
identifier: N | null,
|
|
485
|
+
identifier: N | null | undefined,
|
|
486
486
|
callback?: C,
|
|
487
487
|
onlyOne?: boolean,
|
|
488
|
-
beginRoot?: N | null,
|
|
488
|
+
beginRoot?: N | null | undefined,
|
|
489
489
|
iterationType?: IterationType
|
|
490
490
|
): N[];
|
|
491
491
|
|
|
@@ -493,7 +493,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
493
493
|
identifier: ReturnType<C>,
|
|
494
494
|
callback: C,
|
|
495
495
|
onlyOne?: boolean,
|
|
496
|
-
beginRoot?: N | null,
|
|
496
|
+
beginRoot?: N | null | undefined,
|
|
497
497
|
iterationType?: IterationType
|
|
498
498
|
): N[];
|
|
499
499
|
|
|
@@ -511,7 +511,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
511
511
|
* first node that matches the identifier. If set to true, the function will return an array with
|
|
512
512
|
* only one element (or an empty array if no matching node is found). If set to false (default), the
|
|
513
513
|
* function will continue searching for all
|
|
514
|
-
* @param {N | null} beginRoot - The `beginRoot` parameter is the starting node from which the
|
|
514
|
+
* @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node from which the
|
|
515
515
|
* traversal of the binary tree will begin. It is optional and defaults to the root of the binary
|
|
516
516
|
* tree.
|
|
517
517
|
* @param iterationType - The `iterationType` parameter determines the type of iteration used to
|
|
@@ -519,10 +519,10 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
519
519
|
* @returns The function `getNodes` returns an array of nodes (`N[]`).
|
|
520
520
|
*/
|
|
521
521
|
getNodes<C extends BTNCallback<N>>(
|
|
522
|
-
identifier: ReturnType<C> | null,
|
|
522
|
+
identifier: ReturnType<C> | null | undefined,
|
|
523
523
|
callback: C = this.defaultOneParamCallback as C,
|
|
524
524
|
onlyOne = false,
|
|
525
|
-
beginRoot: N | null = this.root,
|
|
525
|
+
beginRoot: N | null | undefined = this.root,
|
|
526
526
|
iterationType = this.iterationType
|
|
527
527
|
): N[] {
|
|
528
528
|
if (!beginRoot) return [];
|
|
@@ -562,21 +562,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
562
562
|
has<C extends BTNCallback<N, BTNKey>>(
|
|
563
563
|
identifier: BTNKey,
|
|
564
564
|
callback?: C,
|
|
565
|
-
beginRoot?: N | null,
|
|
565
|
+
beginRoot?: N | null | undefined,
|
|
566
566
|
iterationType?: IterationType
|
|
567
567
|
): boolean;
|
|
568
568
|
|
|
569
569
|
has<C extends BTNCallback<N, N>>(
|
|
570
|
-
identifier: N | null,
|
|
570
|
+
identifier: N | null | undefined,
|
|
571
571
|
callback?: C,
|
|
572
|
-
beginRoot?: N | null,
|
|
572
|
+
beginRoot?: N | null | undefined,
|
|
573
573
|
iterationType?: IterationType
|
|
574
574
|
): boolean;
|
|
575
575
|
|
|
576
576
|
has<C extends BTNCallback<N>>(
|
|
577
|
-
identifier: ReturnType<C> | null,
|
|
577
|
+
identifier: ReturnType<C> | null | undefined,
|
|
578
578
|
callback: C,
|
|
579
|
-
beginRoot?: N | null,
|
|
579
|
+
beginRoot?: N | null | undefined,
|
|
580
580
|
iterationType?: IterationType
|
|
581
581
|
): boolean;
|
|
582
582
|
|
|
@@ -598,7 +598,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
598
598
|
* @returns a boolean value.
|
|
599
599
|
*/
|
|
600
600
|
has<C extends BTNCallback<N>>(
|
|
601
|
-
identifier: ReturnType<C> | null,
|
|
601
|
+
identifier: ReturnType<C> | null | undefined,
|
|
602
602
|
callback: C = this.defaultOneParamCallback as C,
|
|
603
603
|
beginRoot = this.root,
|
|
604
604
|
iterationType = this.iterationType
|
|
@@ -611,23 +611,23 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
611
611
|
getNode<C extends BTNCallback<N, BTNKey>>(
|
|
612
612
|
identifier: BTNKey,
|
|
613
613
|
callback?: C,
|
|
614
|
-
beginRoot?: N | null,
|
|
614
|
+
beginRoot?: N | null | undefined,
|
|
615
615
|
iterationType?: IterationType
|
|
616
|
-
): N | null;
|
|
616
|
+
): N | null | undefined;
|
|
617
617
|
|
|
618
618
|
getNode<C extends BTNCallback<N, N>>(
|
|
619
|
-
identifier: N | null,
|
|
619
|
+
identifier: N | null | undefined,
|
|
620
620
|
callback?: C,
|
|
621
|
-
beginRoot?: N | null,
|
|
621
|
+
beginRoot?: N | null | undefined,
|
|
622
622
|
iterationType?: IterationType
|
|
623
|
-
): N | null;
|
|
623
|
+
): N | null | undefined;
|
|
624
624
|
|
|
625
625
|
getNode<C extends BTNCallback<N>>(
|
|
626
626
|
identifier: ReturnType<C>,
|
|
627
627
|
callback: C,
|
|
628
|
-
beginRoot?: N | null,
|
|
628
|
+
beginRoot?: N | null | undefined,
|
|
629
629
|
iterationType?: IterationType
|
|
630
|
-
): N | null;
|
|
630
|
+
): N | null | undefined;
|
|
631
631
|
|
|
632
632
|
/**
|
|
633
633
|
* The function `get` returns the first node in a binary tree that matches the given property or key.
|
|
@@ -645,11 +645,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
645
645
|
* @returns either the found node (of type N) or null if no node is found.
|
|
646
646
|
*/
|
|
647
647
|
getNode<C extends BTNCallback<N>>(
|
|
648
|
-
identifier: ReturnType<C> | null,
|
|
648
|
+
identifier: ReturnType<C> | null | undefined,
|
|
649
649
|
callback: C = this.defaultOneParamCallback as C,
|
|
650
650
|
beginRoot = this.root,
|
|
651
651
|
iterationType = this.iterationType
|
|
652
|
-
): N | null {
|
|
652
|
+
): N | null | undefined {
|
|
653
653
|
if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|
|
654
654
|
|
|
655
655
|
return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;
|
|
@@ -658,21 +658,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
658
658
|
get<C extends BTNCallback<N, BTNKey>>(
|
|
659
659
|
identifier: BTNKey,
|
|
660
660
|
callback?: C,
|
|
661
|
-
beginRoot?: N | null,
|
|
661
|
+
beginRoot?: N | null | undefined,
|
|
662
662
|
iterationType?: IterationType
|
|
663
663
|
): V | undefined;
|
|
664
664
|
|
|
665
665
|
get<C extends BTNCallback<N, N>>(
|
|
666
|
-
identifier: N | null,
|
|
666
|
+
identifier: N | null | undefined,
|
|
667
667
|
callback?: C,
|
|
668
|
-
beginRoot?: N | null,
|
|
668
|
+
beginRoot?: N | null | undefined,
|
|
669
669
|
iterationType?: IterationType
|
|
670
670
|
): V | undefined;
|
|
671
671
|
|
|
672
672
|
get<C extends BTNCallback<N>>(
|
|
673
673
|
identifier: ReturnType<C>,
|
|
674
674
|
callback: C,
|
|
675
|
-
beginRoot?: N | null,
|
|
675
|
+
beginRoot?: N | null | undefined,
|
|
676
676
|
iterationType?: IterationType
|
|
677
677
|
): V | undefined;
|
|
678
678
|
|
|
@@ -692,7 +692,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
692
692
|
* @returns either the found value (of type V) or undefined if no node value is found.
|
|
693
693
|
*/
|
|
694
694
|
get<C extends BTNCallback<N>>(
|
|
695
|
-
identifier: ReturnType<C> | null,
|
|
695
|
+
identifier: ReturnType<C> | null | undefined,
|
|
696
696
|
callback: C = this.defaultOneParamCallback as C,
|
|
697
697
|
beginRoot = this.root,
|
|
698
698
|
iterationType = this.iterationType
|
|
@@ -728,7 +728,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
728
728
|
/**
|
|
729
729
|
* The function `getLeftMost` returns the leftmost node in a binary tree, either using recursive or
|
|
730
730
|
* iterative traversal.
|
|
731
|
-
* @param {BTNKey | N | null} beginRoot - The `beginRoot` parameter is the starting point
|
|
731
|
+
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
|
|
732
732
|
* for finding the leftmost node in a binary tree. It can be either a node object (`N`), a key value
|
|
733
733
|
* of a node (`BTNKey`), or `null` if the tree is empty.
|
|
734
734
|
* @param iterationType - The `iterationType` parameter is used to determine the type of iteration to
|
|
@@ -736,7 +736,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
736
736
|
* @returns The function `getLeftMost` returns the leftmost node (`N`) in a binary tree. If there is
|
|
737
737
|
* no leftmost node, it returns `null`.
|
|
738
738
|
*/
|
|
739
|
-
getLeftMost(beginRoot: BTNKey | N | null = this.root, iterationType = this.iterationType): N | null {
|
|
739
|
+
getLeftMost(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): N | null | undefined {
|
|
740
740
|
if (typeof beginRoot === 'number') beginRoot = this.getNode(beginRoot);
|
|
741
741
|
|
|
742
742
|
if (!beginRoot) return beginRoot;
|
|
@@ -762,15 +762,15 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
762
762
|
/**
|
|
763
763
|
* The function `getRightMost` returns the rightmost node in a binary tree, either recursively or
|
|
764
764
|
* iteratively.
|
|
765
|
-
* @param {N | null} beginRoot - The `beginRoot` parameter is the starting node from which we want to
|
|
766
|
-
* find the rightmost node. It is of type `N | null`, which means it can either be a node of type `N`
|
|
765
|
+
* @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node from which we want to
|
|
766
|
+
* find the rightmost node. It is of type `N | null | undefined`, which means it can either be a node of type `N`
|
|
767
767
|
* or `null`. If it is `null`, it means there is no starting node
|
|
768
768
|
* @param iterationType - The `iterationType` parameter is used to determine the type of iteration to
|
|
769
769
|
* be performed when finding the rightmost node in a binary tree. It can have two possible values:
|
|
770
770
|
* @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If the
|
|
771
771
|
* `beginRoot` parameter is `null`, it returns `null`.
|
|
772
772
|
*/
|
|
773
|
-
getRightMost(beginRoot: N | null = this.root, iterationType = this.iterationType): N | null {
|
|
773
|
+
getRightMost(beginRoot: N | null | undefined = this.root, iterationType = this.iterationType): N | null | undefined {
|
|
774
774
|
// TODO support get right most by passing key in
|
|
775
775
|
if (!beginRoot) return beginRoot;
|
|
776
776
|
|
|
@@ -801,7 +801,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
801
801
|
* possible values:
|
|
802
802
|
* @returns The function `isSubtreeBST` returns a boolean value.
|
|
803
803
|
*/
|
|
804
|
-
isSubtreeBST(beginRoot: N | null, iterationType = this.iterationType): boolean {
|
|
804
|
+
isSubtreeBST(beginRoot: N | null | undefined, iterationType = this.iterationType): boolean {
|
|
805
805
|
// TODO there is a bug
|
|
806
806
|
if (!beginRoot) return true;
|
|
807
807
|
|
|
@@ -846,21 +846,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
846
846
|
|
|
847
847
|
subTreeTraverse<C extends BTNCallback<N>>(
|
|
848
848
|
callback?: C,
|
|
849
|
-
beginRoot?: BTNKey | N | null,
|
|
849
|
+
beginRoot?: BTNKey | N | null | undefined,
|
|
850
850
|
iterationType?: IterationType,
|
|
851
851
|
includeNull?: false
|
|
852
852
|
): ReturnType<C>[];
|
|
853
853
|
|
|
854
854
|
subTreeTraverse<C extends BTNCallback<N>>(
|
|
855
855
|
callback?: C,
|
|
856
|
-
beginRoot?: BTNKey | N | null,
|
|
856
|
+
beginRoot?: BTNKey | N | null | undefined,
|
|
857
857
|
iterationType?: IterationType,
|
|
858
858
|
includeNull?: undefined
|
|
859
859
|
): ReturnType<C>[];
|
|
860
860
|
|
|
861
|
-
subTreeTraverse<C extends BTNCallback<N | null>>(
|
|
861
|
+
subTreeTraverse<C extends BTNCallback<N | null | undefined>>(
|
|
862
862
|
callback?: C,
|
|
863
|
-
beginRoot?: BTNKey | N | null,
|
|
863
|
+
beginRoot?: BTNKey | N | null | undefined,
|
|
864
864
|
iterationType?: IterationType,
|
|
865
865
|
includeNull?: true
|
|
866
866
|
): ReturnType<C>[];
|
|
@@ -872,7 +872,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
872
872
|
* subtree traversal. It takes a single argument, which is the current node being traversed, and
|
|
873
873
|
* returns a value. The return values from each callback invocation will be collected and returned as
|
|
874
874
|
* an array.
|
|
875
|
-
* @param {BTNKey | N | null} beginRoot - The `beginRoot` parameter is the starting point
|
|
875
|
+
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
|
|
876
876
|
* for traversing the subtree. It can be either a node object, a key value of a node, or `null` to
|
|
877
877
|
* start from the root of the tree.
|
|
878
878
|
* @param iterationType - The `iterationType` parameter determines the type of traversal to be
|
|
@@ -880,56 +880,68 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
880
880
|
* @param includeNull - The choice to output null values during binary tree traversal should be provided.
|
|
881
881
|
* @returns The function `subTreeTraverse` returns an array of `ReturnType<BTNCallback<N>>`.
|
|
882
882
|
*/
|
|
883
|
-
subTreeTraverse<C extends BTNCallback<N | null>>(
|
|
883
|
+
subTreeTraverse<C extends BTNCallback<N | null | undefined>>(
|
|
884
884
|
callback: C = this.defaultOneParamCallback as C,
|
|
885
|
-
beginRoot: BTNKey | N | null = this.root,
|
|
885
|
+
beginRoot: BTNKey | N | null | undefined = this.root,
|
|
886
886
|
iterationType = this.iterationType,
|
|
887
887
|
includeNull = false
|
|
888
888
|
): ReturnType<C>[] {
|
|
889
889
|
if (typeof beginRoot === 'number') beginRoot = this.getNode(beginRoot);
|
|
890
890
|
|
|
891
|
-
const ans: (ReturnType<BTNCallback<N>> | null)[] = [];
|
|
891
|
+
const ans: (ReturnType<BTNCallback<N>> | null | undefined)[] = [];
|
|
892
892
|
if (!beginRoot) return ans;
|
|
893
893
|
|
|
894
894
|
if (iterationType === IterationType.RECURSIVE) {
|
|
895
|
-
const _traverse = (cur: N | null) => {
|
|
895
|
+
const _traverse = (cur: N | null | undefined) => {
|
|
896
896
|
if (cur !== undefined) {
|
|
897
897
|
ans.push(callback(cur));
|
|
898
898
|
if (includeNull) {
|
|
899
|
-
cur
|
|
900
|
-
cur
|
|
899
|
+
cur && this.isNodeOrNull(cur.left) && _traverse(cur.left);
|
|
900
|
+
cur && this.isNodeOrNull(cur.right) && _traverse(cur.right);
|
|
901
901
|
} else {
|
|
902
|
-
cur
|
|
903
|
-
cur
|
|
902
|
+
cur && cur.left && _traverse(cur.left);
|
|
903
|
+
cur && cur.right && _traverse(cur.right);
|
|
904
904
|
}
|
|
905
905
|
}
|
|
906
906
|
};
|
|
907
907
|
|
|
908
908
|
_traverse(beginRoot);
|
|
909
909
|
} else {
|
|
910
|
-
const stack: (N | null)[] = [beginRoot];
|
|
910
|
+
const stack: (N | null | undefined)[] = [beginRoot];
|
|
911
911
|
|
|
912
912
|
while (stack.length > 0) {
|
|
913
913
|
const cur = stack.pop();
|
|
914
914
|
if (cur !== undefined) {
|
|
915
915
|
ans.push(callback(cur));
|
|
916
916
|
if (includeNull) {
|
|
917
|
-
cur
|
|
918
|
-
cur
|
|
917
|
+
cur && this.isNodeOrNull(cur.right) && stack.push(cur.right);
|
|
918
|
+
cur && this.isNodeOrNull(cur.left) && stack.push(cur.left);
|
|
919
919
|
} else {
|
|
920
|
-
cur
|
|
921
|
-
cur
|
|
920
|
+
cur && cur.right && stack.push(cur.right);
|
|
921
|
+
cur && cur.left && stack.push(cur.left);
|
|
922
922
|
}
|
|
923
923
|
}
|
|
924
924
|
}
|
|
925
925
|
}
|
|
926
926
|
return ans;
|
|
927
927
|
}
|
|
928
|
+
|
|
929
|
+
isNode(node: any): node is N {
|
|
930
|
+
return node instanceof BinaryTreeNode && node.key.toString() !== 'NaN';
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
isNIL(node: any) {
|
|
934
|
+
return node instanceof BinaryTreeNode && node.key.toString() === 'NaN';
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
isNodeOrNull(node: any): node is (N | null){
|
|
938
|
+
return this.isNode(node) || node === null;
|
|
939
|
+
}
|
|
928
940
|
|
|
929
941
|
dfs<C extends BTNCallback<N>>(
|
|
930
942
|
callback?: C,
|
|
931
943
|
pattern?: DFSOrderPattern,
|
|
932
|
-
beginRoot?: N | null,
|
|
944
|
+
beginRoot?: N | null | undefined,
|
|
933
945
|
iterationType?: IterationType,
|
|
934
946
|
includeNull?: false
|
|
935
947
|
): ReturnType<C>[];
|
|
@@ -937,15 +949,15 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
937
949
|
dfs<C extends BTNCallback<N>>(
|
|
938
950
|
callback?: C,
|
|
939
951
|
pattern?: DFSOrderPattern,
|
|
940
|
-
beginRoot?: N | null,
|
|
952
|
+
beginRoot?: N | null | undefined,
|
|
941
953
|
iterationType?: IterationType,
|
|
942
954
|
includeNull?: undefined
|
|
943
955
|
): ReturnType<C>[];
|
|
944
956
|
|
|
945
|
-
dfs<C extends BTNCallback<N | null>>(
|
|
957
|
+
dfs<C extends BTNCallback<N | null | undefined>>(
|
|
946
958
|
callback?: C,
|
|
947
959
|
pattern?: DFSOrderPattern,
|
|
948
|
-
beginRoot?: N | null,
|
|
960
|
+
beginRoot?: N | null | undefined,
|
|
949
961
|
iterationType?: IterationType,
|
|
950
962
|
includeNull?: true
|
|
951
963
|
): ReturnType<C>[];
|
|
@@ -958,7 +970,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
958
970
|
* is `this.defaultOneParamCallback`, which is a callback function defined elsewhere in the code.
|
|
959
971
|
* @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter determines the order in which the
|
|
960
972
|
* nodes are visited during the depth-first search. There are three possible values for `pattern`:
|
|
961
|
-
* @param {N | null} beginRoot - The `beginRoot` parameter is the starting node for the depth-first
|
|
973
|
+
* @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node for the depth-first
|
|
962
974
|
* search. It determines where the search will begin in the tree or graph structure. If `beginRoot`
|
|
963
975
|
* is `null`, an empty array will be returned.
|
|
964
976
|
* @param {IterationType} iterationType - The `iterationType` parameter determines the type of
|
|
@@ -966,49 +978,49 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
966
978
|
* @param includeNull - The choice to output null values during binary tree traversal should be provided.
|
|
967
979
|
* @returns The function `dfs` returns an array of `ReturnType<BTNCallback<N>>` values.
|
|
968
980
|
*/
|
|
969
|
-
dfs<C extends BTNCallback<N | null>>(
|
|
981
|
+
dfs<C extends BTNCallback<N | null | undefined>>(
|
|
970
982
|
callback: C = this.defaultOneParamCallback as C,
|
|
971
983
|
pattern: DFSOrderPattern = 'in',
|
|
972
|
-
beginRoot: N | null = this.root,
|
|
984
|
+
beginRoot: N | null | undefined = this.root,
|
|
973
985
|
iterationType: IterationType = IterationType.ITERATIVE,
|
|
974
986
|
includeNull = false
|
|
975
987
|
): ReturnType<C>[] {
|
|
976
988
|
if (!beginRoot) return [];
|
|
977
989
|
const ans: ReturnType<C>[] = [];
|
|
978
990
|
if (iterationType === IterationType.RECURSIVE) {
|
|
979
|
-
const _traverse = (node: N | null) => {
|
|
991
|
+
const _traverse = (node: N | null | undefined) => {
|
|
980
992
|
switch (pattern) {
|
|
981
993
|
case 'in':
|
|
982
994
|
if (includeNull) {
|
|
983
|
-
if (node
|
|
984
|
-
ans.push(callback(node));
|
|
985
|
-
if (node
|
|
995
|
+
if (node && this.isNodeOrNull(node.left)) _traverse(node.left);
|
|
996
|
+
this.isNodeOrNull(node) && ans.push(callback(node));
|
|
997
|
+
if (node && this.isNodeOrNull(node.right)) _traverse(node.right);
|
|
986
998
|
} else {
|
|
987
|
-
if (node
|
|
988
|
-
ans.push(callback(node));
|
|
989
|
-
if (node
|
|
999
|
+
if (node && node.left) _traverse(node.left);
|
|
1000
|
+
this.isNode(node) && ans.push(callback(node));
|
|
1001
|
+
if (node && node.right) _traverse(node.right);
|
|
990
1002
|
}
|
|
991
1003
|
break;
|
|
992
1004
|
case 'pre':
|
|
993
1005
|
if (includeNull) {
|
|
994
|
-
ans.push(callback(node));
|
|
995
|
-
if (node
|
|
996
|
-
if (node
|
|
1006
|
+
this.isNodeOrNull(node) && ans.push(callback(node));
|
|
1007
|
+
if (node && this.isNodeOrNull(node.left)) _traverse(node.left);
|
|
1008
|
+
if (node && this.isNodeOrNull(node.right)) _traverse(node.right);
|
|
997
1009
|
} else {
|
|
998
|
-
ans.push(callback(node));
|
|
999
|
-
if (node
|
|
1000
|
-
if (node
|
|
1010
|
+
this.isNode(node) && ans.push(callback(node));
|
|
1011
|
+
if (node && node.left) _traverse(node.left);
|
|
1012
|
+
if (node && node.right) _traverse(node.right);
|
|
1001
1013
|
}
|
|
1002
1014
|
break;
|
|
1003
1015
|
case 'post':
|
|
1004
1016
|
if (includeNull) {
|
|
1005
|
-
if (node
|
|
1006
|
-
if (node
|
|
1007
|
-
ans.push(callback(node));
|
|
1017
|
+
if (node && this.isNodeOrNull(node.left)) _traverse(node.left);
|
|
1018
|
+
if (node && this.isNodeOrNull(node.right)) _traverse(node.right);
|
|
1019
|
+
this.isNodeOrNull(node) && ans.push(callback(node));
|
|
1008
1020
|
} else {
|
|
1009
|
-
if (node
|
|
1010
|
-
if (node
|
|
1011
|
-
ans.push(callback(node));
|
|
1021
|
+
if (node && node.left) _traverse(node.left);
|
|
1022
|
+
if (node && node.right) _traverse(node.right);
|
|
1023
|
+
this.isNode(node) && ans.push(callback(node));
|
|
1012
1024
|
}
|
|
1013
1025
|
|
|
1014
1026
|
break;
|
|
@@ -1022,7 +1034,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1022
1034
|
|
|
1023
1035
|
while (stack.length > 0) {
|
|
1024
1036
|
const cur = stack.pop();
|
|
1025
|
-
if (cur === undefined) continue;
|
|
1037
|
+
if (cur === undefined || this.isNIL(cur.node)) continue;
|
|
1026
1038
|
if (includeNull) {
|
|
1027
1039
|
if (cur.node === undefined) continue;
|
|
1028
1040
|
} else {
|
|
@@ -1062,21 +1074,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1062
1074
|
|
|
1063
1075
|
bfs<C extends BTNCallback<N>>(
|
|
1064
1076
|
callback?: C,
|
|
1065
|
-
beginRoot?: N | null,
|
|
1077
|
+
beginRoot?: N | null | undefined,
|
|
1066
1078
|
iterationType?: IterationType,
|
|
1067
1079
|
includeNull?: false
|
|
1068
1080
|
): ReturnType<C>[];
|
|
1069
1081
|
|
|
1070
1082
|
bfs<C extends BTNCallback<N>>(
|
|
1071
1083
|
callback?: C,
|
|
1072
|
-
beginRoot?: N | null,
|
|
1084
|
+
beginRoot?: N | null | undefined,
|
|
1073
1085
|
iterationType?: IterationType,
|
|
1074
1086
|
includeNull?: undefined
|
|
1075
1087
|
): ReturnType<C>[];
|
|
1076
1088
|
|
|
1077
|
-
bfs<C extends BTNCallback<N | null>>(
|
|
1089
|
+
bfs<C extends BTNCallback<N | null | undefined>>(
|
|
1078
1090
|
callback?: C,
|
|
1079
|
-
beginRoot?: N | null,
|
|
1091
|
+
beginRoot?: N | null | undefined,
|
|
1080
1092
|
iterationType?: IterationType,
|
|
1081
1093
|
includeNull?: true
|
|
1082
1094
|
): ReturnType<C>[];
|
|
@@ -1087,7 +1099,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1087
1099
|
* @param callback - The `callback` parameter is a function that will be called for each node in the
|
|
1088
1100
|
* breadth-first search. It takes a node of type `N` as its argument and returns a value of type
|
|
1089
1101
|
* `ReturnType<BTNCallback<N>>`. The default value for this parameter is `this.defaultOneParamCallback
|
|
1090
|
-
* @param {N | null} beginRoot - The `beginRoot` parameter is the starting node for the breadth-first
|
|
1102
|
+
* @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node for the breadth-first
|
|
1091
1103
|
* search. It determines from which node the search will begin. If `beginRoot` is `null`, the search
|
|
1092
1104
|
* will not be performed and an empty array will be returned.
|
|
1093
1105
|
* @param iterationType - The `iterationType` parameter determines the type of iteration to be used
|
|
@@ -1095,9 +1107,9 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1095
1107
|
* @param includeNull - The choice to output null values during binary tree traversal should be provided.
|
|
1096
1108
|
* @returns The function `bfs` returns an array of `ReturnType<BTNCallback<N>>[]`.
|
|
1097
1109
|
*/
|
|
1098
|
-
bfs<C extends BTNCallback<N | null>>(
|
|
1110
|
+
bfs<C extends BTNCallback<N | null | undefined>>(
|
|
1099
1111
|
callback: C = this.defaultOneParamCallback as C,
|
|
1100
|
-
beginRoot: N | null = this.root,
|
|
1112
|
+
beginRoot: N | null | undefined = this.root,
|
|
1101
1113
|
iterationType = this.iterationType,
|
|
1102
1114
|
includeNull = false
|
|
1103
1115
|
): ReturnType<C>[] {
|
|
@@ -1106,7 +1118,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1106
1118
|
const ans: ReturnType<BTNCallback<N>>[] = [];
|
|
1107
1119
|
|
|
1108
1120
|
if (iterationType === IterationType.RECURSIVE) {
|
|
1109
|
-
const queue: Queue<N | null> = new Queue<N | null>([beginRoot]);
|
|
1121
|
+
const queue: Queue<N | null | undefined> = new Queue<N | null | undefined>([beginRoot]);
|
|
1110
1122
|
|
|
1111
1123
|
const traverse = (level: number) => {
|
|
1112
1124
|
if (queue.size === 0) return;
|
|
@@ -1115,8 +1127,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1115
1127
|
ans.push(callback(current));
|
|
1116
1128
|
|
|
1117
1129
|
if (includeNull) {
|
|
1118
|
-
if (current && current.left
|
|
1119
|
-
if (current && current.right
|
|
1130
|
+
if (current && this.isNodeOrNull(current.left)) queue.push(current.left);
|
|
1131
|
+
if (current && this.isNodeOrNull(current.right)) queue.push(current.right);
|
|
1120
1132
|
} else {
|
|
1121
1133
|
if (current.left) queue.push(current.left);
|
|
1122
1134
|
if (current.right) queue.push(current.right);
|
|
@@ -1127,7 +1139,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1127
1139
|
|
|
1128
1140
|
traverse(0);
|
|
1129
1141
|
} else {
|
|
1130
|
-
const queue = new Queue<N | null>([beginRoot]);
|
|
1142
|
+
const queue = new Queue<N | null | undefined>([beginRoot]);
|
|
1131
1143
|
while (queue.size > 0) {
|
|
1132
1144
|
const levelSize = queue.size;
|
|
1133
1145
|
|
|
@@ -1136,8 +1148,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1136
1148
|
ans.push(callback(current));
|
|
1137
1149
|
|
|
1138
1150
|
if (includeNull) {
|
|
1139
|
-
if (current
|
|
1140
|
-
if (current
|
|
1151
|
+
if (current && this.isNodeOrNull(current.left)) queue.push(current.left);
|
|
1152
|
+
if (current && this.isNodeOrNull(current.right)) queue.push(current.right);
|
|
1141
1153
|
} else {
|
|
1142
1154
|
if (current.left) queue.push(current.left);
|
|
1143
1155
|
if (current.right) queue.push(current.right);
|
|
@@ -1150,21 +1162,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1150
1162
|
|
|
1151
1163
|
listLevels<C extends BTNCallback<N>>(
|
|
1152
1164
|
callback?: C,
|
|
1153
|
-
beginRoot?: N | null,
|
|
1165
|
+
beginRoot?: N | null | undefined,
|
|
1154
1166
|
iterationType?: IterationType,
|
|
1155
1167
|
includeNull?: false
|
|
1156
1168
|
): ReturnType<C>[][];
|
|
1157
1169
|
|
|
1158
1170
|
listLevels<C extends BTNCallback<N>>(
|
|
1159
1171
|
callback?: C,
|
|
1160
|
-
beginRoot?: N | null,
|
|
1172
|
+
beginRoot?: N | null | undefined,
|
|
1161
1173
|
iterationType?: IterationType,
|
|
1162
1174
|
includeNull?: undefined
|
|
1163
1175
|
): ReturnType<C>[][];
|
|
1164
1176
|
|
|
1165
|
-
listLevels<C extends BTNCallback<N | null>>(
|
|
1177
|
+
listLevels<C extends BTNCallback<N | null | undefined>>(
|
|
1166
1178
|
callback?: C,
|
|
1167
|
-
beginRoot?: N | null,
|
|
1179
|
+
beginRoot?: N | null | undefined,
|
|
1168
1180
|
iterationType?: IterationType,
|
|
1169
1181
|
includeNull?: true
|
|
1170
1182
|
): ReturnType<C>[][];
|
|
@@ -1175,7 +1187,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1175
1187
|
* @param {C} callback - The `callback` parameter is a function that will be called on each node in
|
|
1176
1188
|
* the tree. It takes a node as input and returns a value. The return type of the callback function
|
|
1177
1189
|
* is determined by the generic type `C`.
|
|
1178
|
-
* @param {N | null} beginRoot - The `beginRoot` parameter represents the starting node of the binary tree
|
|
1190
|
+
* @param {N | null | undefined} beginRoot - The `beginRoot` parameter represents the starting node of the binary tree
|
|
1179
1191
|
* traversal. It can be any node in the binary tree. If no node is provided, the traversal will start
|
|
1180
1192
|
* from the root node of the binary tree.
|
|
1181
1193
|
* @param iterationType - The `iterationType` parameter determines whether the tree traversal is done
|
|
@@ -1185,9 +1197,9 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1185
1197
|
* level in a binary tree. Each inner array contains the return type of the provided callback
|
|
1186
1198
|
* function `C` applied to the nodes at that level.
|
|
1187
1199
|
*/
|
|
1188
|
-
listLevels<C extends BTNCallback<N | null>>(
|
|
1200
|
+
listLevels<C extends BTNCallback<N | null | undefined>>(
|
|
1189
1201
|
callback: C = this.defaultOneParamCallback as C,
|
|
1190
|
-
beginRoot: N | null = this.root,
|
|
1202
|
+
beginRoot: N | null | undefined = this.root,
|
|
1191
1203
|
iterationType = this.iterationType,
|
|
1192
1204
|
includeNull = false
|
|
1193
1205
|
): ReturnType<C>[][] {
|
|
@@ -1195,12 +1207,12 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1195
1207
|
const levelsNodes: ReturnType<C>[][] = [];
|
|
1196
1208
|
|
|
1197
1209
|
if (iterationType === IterationType.RECURSIVE) {
|
|
1198
|
-
const _recursive = (node: N | null, level: number) => {
|
|
1210
|
+
const _recursive = (node: N | null | undefined, level: number) => {
|
|
1199
1211
|
if (!levelsNodes[level]) levelsNodes[level] = [];
|
|
1200
1212
|
levelsNodes[level].push(callback(node));
|
|
1201
1213
|
if (includeNull) {
|
|
1202
|
-
if (node && node.left
|
|
1203
|
-
if (node && node.right
|
|
1214
|
+
if (node && this.isNodeOrNull(node.left)) _recursive(node.left, level + 1);
|
|
1215
|
+
if (node && this.isNodeOrNull(node.right)) _recursive(node.right, level + 1);
|
|
1204
1216
|
} else {
|
|
1205
1217
|
if (node && node.left) _recursive(node.left, level + 1);
|
|
1206
1218
|
if (node && node.right) _recursive(node.right, level + 1);
|
|
@@ -1209,7 +1221,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1209
1221
|
|
|
1210
1222
|
_recursive(beginRoot, 0);
|
|
1211
1223
|
} else {
|
|
1212
|
-
const stack: [N | null, number][] = [[beginRoot, 0]];
|
|
1224
|
+
const stack: [N | null | undefined, number][] = [[beginRoot, 0]];
|
|
1213
1225
|
|
|
1214
1226
|
while (stack.length > 0) {
|
|
1215
1227
|
const head = stack.pop()!;
|
|
@@ -1219,8 +1231,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1219
1231
|
levelsNodes[level].push(callback(node));
|
|
1220
1232
|
|
|
1221
1233
|
if (includeNull) {
|
|
1222
|
-
if (node && node.right
|
|
1223
|
-
if (node && node.left
|
|
1234
|
+
if (node && this.isNodeOrNull(node.right)) stack.push([node.right, level + 1]);
|
|
1235
|
+
if (node && this.isNodeOrNull(node.left)) stack.push([node.left, level + 1]);
|
|
1224
1236
|
} else {
|
|
1225
1237
|
if (node && node.right) stack.push([node.right, level + 1]);
|
|
1226
1238
|
if (node && node.left) stack.push([node.left, level + 1]);
|
|
@@ -1279,7 +1291,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1279
1291
|
* @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter in the `morris` function
|
|
1280
1292
|
* determines the order in which the nodes of a binary tree are traversed. It can have one of the
|
|
1281
1293
|
* following values:
|
|
1282
|
-
* @param {N | null} beginRoot - The `beginRoot` parameter is the starting node for the Morris
|
|
1294
|
+
* @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node for the Morris
|
|
1283
1295
|
* traversal. It specifies the root node of the tree from which the traversal should begin. If
|
|
1284
1296
|
* `beginRoot` is `null`, an empty array will be returned.
|
|
1285
1297
|
* @returns The `morris` function returns an array of `ReturnType<BTNCallback<N>>` values.
|
|
@@ -1287,7 +1299,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1287
1299
|
morris<C extends BTNCallback<N>>(
|
|
1288
1300
|
callback: C = this.defaultOneParamCallback as C,
|
|
1289
1301
|
pattern: DFSOrderPattern = 'in',
|
|
1290
|
-
beginRoot: N | null = this.root
|
|
1302
|
+
beginRoot: N | null | undefined = this.root
|
|
1291
1303
|
): ReturnType<C>[] {
|
|
1292
1304
|
if (beginRoot === null) return [];
|
|
1293
1305
|
const ans: ReturnType<BTNCallback<N>>[] = [];
|
|
@@ -1304,7 +1316,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1304
1316
|
}
|
|
1305
1317
|
return pre;
|
|
1306
1318
|
};
|
|
1307
|
-
const _printEdge = (node: N | null) => {
|
|
1319
|
+
const _printEdge = (node: N | null | undefined) => {
|
|
1308
1320
|
const tail: N | null | undefined = _reverseEdge(node);
|
|
1309
1321
|
let cur: N | null | undefined = tail;
|
|
1310
1322
|
while (cur) {
|
|
@@ -1438,7 +1450,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1438
1450
|
|
|
1439
1451
|
/**
|
|
1440
1452
|
* The function `_addTo` adds a new node to a binary tree if there is an available position.
|
|
1441
|
-
* @param {N | null} newNode - The `newNode` parameter represents the node that you want to add to
|
|
1453
|
+
* @param {N | null | undefined} newNode - The `newNode` parameter represents the node that you want to add to
|
|
1442
1454
|
* the binary tree. It can be either a node object or `null`.
|
|
1443
1455
|
* @param {N} parent - The `parent` parameter represents the parent node to which the new node will
|
|
1444
1456
|
* be added as a child.
|
|
@@ -1447,7 +1459,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1447
1459
|
* the binary tree. If neither the left nor right child is available, the function returns undefined.
|
|
1448
1460
|
* If the parent node is null, the function also returns undefined.
|
|
1449
1461
|
*/
|
|
1450
|
-
protected _addTo(newNode: N | null, parent: N): N | null | undefined {
|
|
1462
|
+
protected _addTo(newNode: N | null | undefined, parent: N): N | null | undefined {
|
|
1451
1463
|
if (parent) {
|
|
1452
1464
|
// When all leaf nodes are null, it will no longer be possible to add new entity nodes to this binary tree.
|
|
1453
1465
|
// In this scenario, null nodes serve as "sentinel nodes," "virtual nodes," or "placeholder nodes."
|
|
@@ -1474,15 +1486,73 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1474
1486
|
/**
|
|
1475
1487
|
* The function sets the root property of an object to a given value, and if the value is not null,
|
|
1476
1488
|
* it also sets the parent property of the value to undefined.
|
|
1477
|
-
* @param {N | null} v - The parameter `v` is of type `N | null`, which means it can either be of
|
|
1489
|
+
* @param {N | null | undefined} v - The parameter `v` is of type `N | null | undefined`, which means it can either be of
|
|
1478
1490
|
* type `N` or `null`.
|
|
1479
1491
|
*/
|
|
1480
|
-
protected _setRoot(v: N | null) {
|
|
1492
|
+
protected _setRoot(v: N | null | undefined) {
|
|
1481
1493
|
if (v) {
|
|
1482
1494
|
v.parent = undefined;
|
|
1483
1495
|
}
|
|
1484
1496
|
this._root = v;
|
|
1485
1497
|
}
|
|
1486
1498
|
|
|
1499
|
+
print(beginRoot: N | null | undefined = this.root) {
|
|
1500
|
+
const display = (root: N | null | undefined): void => {
|
|
1501
|
+
const [lines, , ,] = _displayAux(root);
|
|
1502
|
+
for (const line of lines) {
|
|
1503
|
+
console.log(line);
|
|
1504
|
+
}
|
|
1505
|
+
};
|
|
1506
|
+
|
|
1507
|
+
const _displayAux = (node: N | null | undefined): [string[], number, number, number] => {
|
|
1508
|
+
if (node === undefined || node === null) {
|
|
1509
|
+
return [[], 0, 0, 0];
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
if (node && node.right === undefined && node.left === undefined) {
|
|
1513
|
+
const line = `${node.key}`;
|
|
1514
|
+
const width = line.length;
|
|
1515
|
+
const height = 1;
|
|
1516
|
+
const middle = Math.floor(width / 2);
|
|
1517
|
+
return [[line], width, height, middle];
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
if (node && node.right === undefined) {
|
|
1521
|
+
const [lines, n, p, x] = _displayAux(node.left);
|
|
1522
|
+
const s = `${node.key}`;
|
|
1523
|
+
const u = s.length;
|
|
1524
|
+
const first_line = ' '.repeat(x + 1) + '_'.repeat(n - x - 1) + s;
|
|
1525
|
+
const second_line = ' '.repeat(x) + '/' + ' '.repeat(n - x - 1 + u);
|
|
1526
|
+
const shifted_lines = lines.map(line => line + ' '.repeat(u));
|
|
1527
|
+
return [[first_line, second_line, ...shifted_lines], n + u, p + 2, n + Math.floor(u / 2)];
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
if (node && node.left === undefined) {
|
|
1531
|
+
const [lines, n, p, u] = _displayAux(node.right);
|
|
1532
|
+
const s = `${node.key}`;
|
|
1533
|
+
const x = s.length;
|
|
1534
|
+
const first_line = s + '_'.repeat(x) + ' '.repeat(n - x);
|
|
1535
|
+
const second_line = ' '.repeat(u + x) + '\\' + ' '.repeat(n - x - 1);
|
|
1536
|
+
const shifted_lines = lines.map(line => ' '.repeat(u) + line);
|
|
1537
|
+
return [[first_line, second_line, ...shifted_lines], n + x, p + 2, Math.floor(u / 2)];
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
const [left, n, p, x] = _displayAux(node.left);
|
|
1541
|
+
const [right, m, q, y] = _displayAux(node.right);
|
|
1542
|
+
const s = `${node.key}`;
|
|
1543
|
+
const u = s.length;
|
|
1544
|
+
const first_line = ' '.repeat(x + 1) + '_'.repeat(n - x - 1) + s + '_'.repeat(y) + ' '.repeat(m - y);
|
|
1545
|
+
const second_line = ' '.repeat(x) + '/' + ' '.repeat(n - x - 1 + u + y) + '\\' + ' '.repeat(m - y - 1);
|
|
1546
|
+
if (p < q) {
|
|
1547
|
+
left.push(...new Array(q - p).fill(' '.repeat(n)));
|
|
1548
|
+
} else if (q < p) {
|
|
1549
|
+
right.push(...new Array(p - q).fill(' '.repeat(m)));
|
|
1550
|
+
}
|
|
1551
|
+
const zipped_lines = left.map((a, i) => a + ' '.repeat(u) + right[i]);
|
|
1552
|
+
return [[first_line, second_line, ...zipped_lines], n + m + u, Math.max(p, q) + 2, n + Math.floor(u / 2)];
|
|
1553
|
+
};
|
|
1554
|
+
|
|
1555
|
+
display(beginRoot);
|
|
1556
|
+
}
|
|
1487
1557
|
// --- end additional methods ---
|
|
1488
1558
|
}
|