avl-tree-typed 1.46.8 → 1.47.2
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 +4 -2
- package/dist/data-structures/binary-tree/avl-tree.js +10 -0
- package/dist/data-structures/binary-tree/binary-tree.d.ts +51 -13
- package/dist/data-structures/binary-tree/binary-tree.js +153 -55
- package/dist/data-structures/binary-tree/bst.d.ts +10 -9
- package/dist/data-structures/binary-tree/bst.js +16 -14
- package/dist/data-structures/binary-tree/rb-tree.d.ts +7 -5
- package/dist/data-structures/binary-tree/rb-tree.js +32 -23
- package/dist/data-structures/binary-tree/tree-multimap.d.ts +5 -3
- package/dist/data-structures/binary-tree/tree-multimap.js +11 -2
- package/dist/data-structures/hash/hash-map.d.ts +27 -0
- package/dist/data-structures/hash/hash-map.js +27 -0
- package/dist/interfaces/binary-tree.d.ts +3 -3
- package/dist/types/common.d.ts +5 -4
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +2 -1
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +3 -1
- package/dist/types/data-structures/binary-tree/binary-tree.js +0 -6
- package/dist/types/data-structures/binary-tree/bst.d.ts +2 -1
- package/dist/types/data-structures/binary-tree/rb-tree.d.ts +2 -1
- package/dist/types/data-structures/binary-tree/tree-multimap.d.ts +2 -1
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree.ts +17 -5
- package/src/data-structures/binary-tree/binary-tree.ts +175 -62
- package/src/data-structures/binary-tree/bst.ts +23 -19
- package/src/data-structures/binary-tree/rb-tree.ts +38 -27
- package/src/data-structures/binary-tree/tree-multimap.ts +19 -6
- package/src/data-structures/hash/hash-map.ts +27 -0
- package/src/interfaces/binary-tree.ts +3 -3
- package/src/types/common.ts +2 -5
- package/src/types/data-structures/binary-tree/avl-tree.ts +5 -1
- package/src/types/data-structures/binary-tree/binary-tree.ts +5 -7
- package/src/types/data-structures/binary-tree/bst.ts +3 -1
- package/src/types/data-structures/binary-tree/rb-tree.ts +3 -1
- package/src/types/data-structures/binary-tree/tree-multimap.ts +3 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { TreeMultimapNode } from '../../../data-structures';
|
|
1
|
+
import { TreeMultimap, TreeMultimapNode } from '../../../data-structures';
|
|
2
2
|
import { AVLTreeOptions } from './avl-tree';
|
|
3
3
|
export type TreeMultimapNodeNested<T> = TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
|
|
4
|
+
export type TreeMultimapNested<T, N extends TreeMultimapNode<T, N>> = TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, TreeMultimap<T, N, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
|
|
4
5
|
export type TreeMultimapOptions = Omit<AVLTreeOptions, 'isMergeDuplicatedNodeByKey'> & {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "avl-tree-typed",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.47.2",
|
|
4
4
|
"description": "AVLTree(Adelson-Velsky and Landis Tree). Javascript & Typescript Data Structure.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -163,6 +163,6 @@
|
|
|
163
163
|
"typescript": "^4.9.5"
|
|
164
164
|
},
|
|
165
165
|
"dependencies": {
|
|
166
|
-
"data-structure-typed": "^1.
|
|
166
|
+
"data-structure-typed": "^1.47.2"
|
|
167
167
|
}
|
|
168
168
|
}
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
8
|
import { BST, BSTNode } from './bst';
|
|
9
|
-
import type { AVLTreeNodeNested, AVLTreeOptions, BiTreeDeleteResult, BTNKey } from '../../types';
|
|
10
|
-
import { BTNCallback } from '../../types';
|
|
9
|
+
import type { AVLTreeNested, AVLTreeNodeNested, AVLTreeOptions, BiTreeDeleteResult, BTNKey } from '../../types';
|
|
10
|
+
import { BTNCallback, IterationType } from '../../types';
|
|
11
11
|
import { IBinaryTree } from '../../interfaces';
|
|
12
12
|
|
|
13
13
|
export class AVLTreeNode<V = any, N extends AVLTreeNode<V, N> = AVLTreeNodeNested<V>> extends BSTNode<V, N> {
|
|
@@ -19,9 +19,12 @@ export class AVLTreeNode<V = any, N extends AVLTreeNode<V, N> = AVLTreeNodeNeste
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTreeNodeNested<V>>>
|
|
23
|
-
extends BST<V, N>
|
|
24
|
-
implements IBinaryTree<V, N> {
|
|
22
|
+
export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTreeNodeNested<V>>, TREE extends AVLTree<V, N, TREE> = AVLTree<V, N, AVLTreeNested<V, N>>>
|
|
23
|
+
extends BST<V, N, TREE>
|
|
24
|
+
implements IBinaryTree<V, N, TREE> {
|
|
25
|
+
|
|
26
|
+
override options: AVLTreeOptions;
|
|
27
|
+
|
|
25
28
|
/**
|
|
26
29
|
* This is a constructor function for an AVL tree data structure in TypeScript.
|
|
27
30
|
* @param {AVLTreeOptions} [options] - The `options` parameter is an optional object that can be passed to the
|
|
@@ -30,6 +33,11 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
|
|
|
30
33
|
*/
|
|
31
34
|
constructor(options?: AVLTreeOptions) {
|
|
32
35
|
super(options);
|
|
36
|
+
if (options) {
|
|
37
|
+
this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b, ...options }
|
|
38
|
+
} else {
|
|
39
|
+
this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b };
|
|
40
|
+
}
|
|
33
41
|
}
|
|
34
42
|
|
|
35
43
|
/**
|
|
@@ -45,6 +53,10 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
|
|
|
45
53
|
return new AVLTreeNode<V, N>(key, value) as N;
|
|
46
54
|
}
|
|
47
55
|
|
|
56
|
+
override createTree(options?: AVLTreeOptions): TREE {
|
|
57
|
+
return new AVLTree<V, N, TREE>({ ...this.options, ...options }) as TREE;
|
|
58
|
+
}
|
|
59
|
+
|
|
48
60
|
/**
|
|
49
61
|
* Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity.
|
|
50
62
|
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
|
|
@@ -7,7 +7,15 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { BinaryTreeNodeNested, BinaryTreeOptions, BTNCallback, BTNKey } from '../../types';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
BinaryTreeNested,
|
|
12
|
+
BinaryTreePrintOptions,
|
|
13
|
+
BiTreeDeleteResult,
|
|
14
|
+
DFSOrderPattern,
|
|
15
|
+
FamilyPosition,
|
|
16
|
+
IterationType,
|
|
17
|
+
NodeDisplayLayout
|
|
18
|
+
} from '../../types';
|
|
11
19
|
import { IBinaryTree } from '../../interfaces';
|
|
12
20
|
import { trampoline } from '../../utils';
|
|
13
21
|
import { Queue } from '../queue';
|
|
@@ -107,9 +115,10 @@ export class BinaryTreeNode<V = any, N extends BinaryTreeNode<V, N> = BinaryTree
|
|
|
107
115
|
* Represents a binary tree data structure.
|
|
108
116
|
* @template N - The type of the binary tree's nodes.
|
|
109
117
|
*/
|
|
110
|
-
export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode<V, BinaryTreeNodeNested<V>>>
|
|
111
|
-
implements IBinaryTree<V, N> {
|
|
112
|
-
|
|
118
|
+
export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode<V, BinaryTreeNodeNested<V>>, TREE extends BinaryTree<V, N, TREE> = BinaryTree<V, N, BinaryTreeNested<V, N>>>
|
|
119
|
+
implements IBinaryTree<V, N, TREE> {
|
|
120
|
+
|
|
121
|
+
options: BinaryTreeOptions;
|
|
113
122
|
|
|
114
123
|
/**
|
|
115
124
|
* Creates a new instance of BinaryTree.
|
|
@@ -117,9 +126,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
117
126
|
*/
|
|
118
127
|
constructor(options?: BinaryTreeOptions) {
|
|
119
128
|
if (options) {
|
|
120
|
-
|
|
121
|
-
|
|
129
|
+
this.options = { iterationType: IterationType.ITERATIVE, ...options }
|
|
130
|
+
} else {
|
|
131
|
+
this.options = { iterationType: IterationType.ITERATIVE };
|
|
122
132
|
}
|
|
133
|
+
|
|
123
134
|
this._size = 0;
|
|
124
135
|
}
|
|
125
136
|
|
|
@@ -151,6 +162,10 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
151
162
|
return new BinaryTreeNode<V, N>(key, value) as N;
|
|
152
163
|
}
|
|
153
164
|
|
|
165
|
+
createTree(options?: BinaryTreeOptions): TREE {
|
|
166
|
+
return new BinaryTree<V, N, TREE>({ ...this.options, ...options }) as TREE;
|
|
167
|
+
}
|
|
168
|
+
|
|
154
169
|
/**
|
|
155
170
|
* Time Complexity: O(n)
|
|
156
171
|
* Space Complexity: O(1)
|
|
@@ -397,7 +412,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
397
412
|
* values:
|
|
398
413
|
* @returns the height of the binary tree.
|
|
399
414
|
*/
|
|
400
|
-
getHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): number {
|
|
415
|
+
getHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.options.iterationType): number {
|
|
401
416
|
beginRoot = this.ensureNotKey(beginRoot);
|
|
402
417
|
if (!beginRoot) return -1;
|
|
403
418
|
|
|
@@ -446,7 +461,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
446
461
|
* to calculate the minimum height of a binary tree. It can have two possible values:
|
|
447
462
|
* @returns The function `getMinHeight` returns the minimum height of a binary tree.
|
|
448
463
|
*/
|
|
449
|
-
getMinHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): number {
|
|
464
|
+
getMinHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.options.iterationType): number {
|
|
450
465
|
beginRoot = this.ensureNotKey(beginRoot);
|
|
451
466
|
if (!beginRoot) return -1;
|
|
452
467
|
|
|
@@ -568,7 +583,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
568
583
|
callback: C = this._defaultOneParamCallback as C,
|
|
569
584
|
onlyOne = false,
|
|
570
585
|
beginRoot: BTNKey | N | null | undefined = this.root,
|
|
571
|
-
iterationType = this.iterationType
|
|
586
|
+
iterationType = this.options.iterationType
|
|
572
587
|
): N[] {
|
|
573
588
|
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
|
|
574
589
|
callback = (node => node) as C;
|
|
@@ -657,7 +672,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
657
672
|
identifier: ReturnType<C> | null | undefined,
|
|
658
673
|
callback: C = this._defaultOneParamCallback as C,
|
|
659
674
|
beginRoot: BTNKey | N | null | undefined = this.root,
|
|
660
|
-
iterationType = this.iterationType
|
|
675
|
+
iterationType = this.options.iterationType
|
|
661
676
|
): boolean {
|
|
662
677
|
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
|
|
663
678
|
callback = (node => node) as C;
|
|
@@ -716,7 +731,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
716
731
|
identifier: ReturnType<C> | null | undefined,
|
|
717
732
|
callback: C = this._defaultOneParamCallback as C,
|
|
718
733
|
beginRoot: BTNKey | N | null | undefined = this.root,
|
|
719
|
-
iterationType = this.iterationType
|
|
734
|
+
iterationType = this.options.iterationType
|
|
720
735
|
): N | null | undefined {
|
|
721
736
|
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
|
|
722
737
|
callback = (node => node) as C;
|
|
@@ -835,7 +850,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
835
850
|
identifier: ReturnType<C> | null | undefined,
|
|
836
851
|
callback: C = this._defaultOneParamCallback as C,
|
|
837
852
|
beginRoot: BTNKey | N | null | undefined = this.root,
|
|
838
|
-
iterationType = this.iterationType
|
|
853
|
+
iterationType = this.options.iterationType
|
|
839
854
|
): V | undefined {
|
|
840
855
|
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
|
|
841
856
|
callback = (node => node) as C;
|
|
@@ -916,7 +931,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
916
931
|
*/
|
|
917
932
|
getLeftMost(
|
|
918
933
|
beginRoot: BTNKey | N | null | undefined = this.root,
|
|
919
|
-
iterationType = this.iterationType
|
|
934
|
+
iterationType = this.options.iterationType
|
|
920
935
|
): N | null | undefined {
|
|
921
936
|
beginRoot = this.ensureNotKey(beginRoot);
|
|
922
937
|
|
|
@@ -962,7 +977,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
962
977
|
*/
|
|
963
978
|
getRightMost(
|
|
964
979
|
beginRoot: BTNKey | N | null | undefined = this.root,
|
|
965
|
-
iterationType = this.iterationType
|
|
980
|
+
iterationType = this.options.iterationType
|
|
966
981
|
): N | null | undefined {
|
|
967
982
|
// TODO support get right most by passing key in
|
|
968
983
|
beginRoot = this.ensureNotKey(beginRoot);
|
|
@@ -1003,7 +1018,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1003
1018
|
* possible values:
|
|
1004
1019
|
* @returns a boolean value.
|
|
1005
1020
|
*/
|
|
1006
|
-
isSubtreeBST(beginRoot: BTNKey | N | null | undefined, iterationType = this.iterationType): boolean {
|
|
1021
|
+
isSubtreeBST(beginRoot: BTNKey | N | null | undefined, iterationType = this.options.iterationType): boolean {
|
|
1007
1022
|
// TODO there is a bug
|
|
1008
1023
|
beginRoot = this.ensureNotKey(beginRoot);
|
|
1009
1024
|
if (!beginRoot) return true;
|
|
@@ -1050,7 +1065,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1050
1065
|
* expected to be
|
|
1051
1066
|
* @returns a boolean value.
|
|
1052
1067
|
*/
|
|
1053
|
-
isBST(iterationType = this.iterationType): boolean {
|
|
1068
|
+
isBST(iterationType = this.options.iterationType): boolean {
|
|
1054
1069
|
if (this.root === null) return true;
|
|
1055
1070
|
return this.isSubtreeBST(this.root, iterationType);
|
|
1056
1071
|
}
|
|
@@ -1097,7 +1112,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1097
1112
|
* @param iterationType - The `iterationType` parameter determines the type of traversal to be
|
|
1098
1113
|
* performed on the subtree. It can have two possible values:
|
|
1099
1114
|
* @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines
|
|
1100
|
-
* whether
|
|
1115
|
+
* whether to include null values in the traversal. If `includeNull` is set to `true`, the
|
|
1101
1116
|
* traversal will include null values, otherwise it will skip them.
|
|
1102
1117
|
* @returns The function `subTreeTraverse` returns an array of values that are the result of invoking
|
|
1103
1118
|
* the `callback` function on each node in the subtree. The type of the array elements is determined
|
|
@@ -1106,7 +1121,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1106
1121
|
subTreeTraverse<C extends BTNCallback<N | null | undefined>>(
|
|
1107
1122
|
callback: C = this._defaultOneParamCallback as C,
|
|
1108
1123
|
beginRoot: BTNKey | N | null | undefined = this.root,
|
|
1109
|
-
iterationType = this.iterationType,
|
|
1124
|
+
iterationType = this.options.iterationType,
|
|
1110
1125
|
includeNull = false
|
|
1111
1126
|
): ReturnType<C>[] {
|
|
1112
1127
|
beginRoot = this.ensureNotKey(beginRoot);
|
|
@@ -1376,7 +1391,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1376
1391
|
* @param iterationType - The `iterationType` parameter determines the type of iteration to be
|
|
1377
1392
|
* performed during the breadth-first search (BFS). It can have two possible values:
|
|
1378
1393
|
* @param [includeNull=false] - The `includeNull` parameter is a boolean flag that determines whether
|
|
1379
|
-
*
|
|
1394
|
+
* to include null values in the breadth-first search traversal. If `includeNull` is set to
|
|
1380
1395
|
* `true`, null values will be included in the traversal, otherwise they will be skipped.
|
|
1381
1396
|
* @returns an array of values that are the result of invoking the callback function on each node in
|
|
1382
1397
|
* the breadth-first traversal of a binary tree.
|
|
@@ -1384,7 +1399,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1384
1399
|
bfs<C extends BTNCallback<N | null | undefined>>(
|
|
1385
1400
|
callback: C = this._defaultOneParamCallback as C,
|
|
1386
1401
|
beginRoot: BTNKey | N | null | undefined = this.root,
|
|
1387
|
-
iterationType = this.iterationType,
|
|
1402
|
+
iterationType = this.options.iterationType,
|
|
1388
1403
|
includeNull = false
|
|
1389
1404
|
): ReturnType<C>[] {
|
|
1390
1405
|
beginRoot = this.ensureNotKey(beginRoot);
|
|
@@ -1477,7 +1492,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1477
1492
|
* @param iterationType - The `iterationType` parameter determines the type of iteration to be
|
|
1478
1493
|
* performed on the tree. It can have two possible values:
|
|
1479
1494
|
* @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines
|
|
1480
|
-
* whether
|
|
1495
|
+
* whether to include null values in the resulting levels. If `includeNull` is set to `true`,
|
|
1481
1496
|
* null values will be included in the levels. If `includeNull` is set to `false`, null values will
|
|
1482
1497
|
* be excluded
|
|
1483
1498
|
* @returns The function `listLevels` returns a two-dimensional array of type `ReturnType<C>[][]`.
|
|
@@ -1485,7 +1500,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1485
1500
|
listLevels<C extends BTNCallback<N | null | undefined>>(
|
|
1486
1501
|
callback: C = this._defaultOneParamCallback as C,
|
|
1487
1502
|
beginRoot: BTNKey | N | null | undefined = this.root,
|
|
1488
|
-
iterationType = this.iterationType,
|
|
1503
|
+
iterationType = this.options.iterationType,
|
|
1489
1504
|
includeNull = false
|
|
1490
1505
|
): ReturnType<C>[][] {
|
|
1491
1506
|
beginRoot = this.ensureNotKey(beginRoot);
|
|
@@ -1685,6 +1700,80 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1685
1700
|
return ans;
|
|
1686
1701
|
}
|
|
1687
1702
|
|
|
1703
|
+
/**
|
|
1704
|
+
* The `forEach` function iterates over each entry in a tree and calls a callback function with the
|
|
1705
|
+
* entry and the tree as arguments.
|
|
1706
|
+
* @param callback - The callback parameter is a function that will be called for each entry in the
|
|
1707
|
+
* tree. It takes two parameters: entry and tree.
|
|
1708
|
+
*/
|
|
1709
|
+
forEach(callback: (entry: [BTNKey, V | undefined], tree: this) => void): void {
|
|
1710
|
+
for (const entry of this) {
|
|
1711
|
+
callback(entry, this);
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
/**
|
|
1716
|
+
* The `filter` function creates a new tree by iterating over the entries of the current tree and
|
|
1717
|
+
* adding the entries that satisfy the given predicate.
|
|
1718
|
+
* @param predicate - The `predicate` parameter is a function that takes two arguments: `entry` and
|
|
1719
|
+
* `tree`.
|
|
1720
|
+
* @returns The `filter` method is returning a new tree object that contains only the entries that
|
|
1721
|
+
* satisfy the given predicate function.
|
|
1722
|
+
*/
|
|
1723
|
+
filter(predicate: (entry: [BTNKey, V | undefined], tree: this) => boolean) {
|
|
1724
|
+
const newTree = this.createTree();
|
|
1725
|
+
for (const [key, value] of this) {
|
|
1726
|
+
if (predicate([key, value], this)) {
|
|
1727
|
+
newTree.add(key, value);
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
return newTree;
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
// TODO Type error, need to return a TREE<NV> that is a value type only for callback function.
|
|
1734
|
+
// map<NV>(callback: (entry: [BTNKey, V | undefined], tree: this) => NV) {
|
|
1735
|
+
// const newTree = this.createTree();
|
|
1736
|
+
// for (const [key, value] of this) {
|
|
1737
|
+
// newTree.add(key, callback([key, value], this));
|
|
1738
|
+
// }
|
|
1739
|
+
// return newTree;
|
|
1740
|
+
// }
|
|
1741
|
+
|
|
1742
|
+
/**
|
|
1743
|
+
* The `map` function creates a new tree by applying a callback function to each entry in the current
|
|
1744
|
+
* tree.
|
|
1745
|
+
* @param callback - The callback parameter is a function that takes two arguments: entry and tree.
|
|
1746
|
+
* @returns The `map` method is returning a new tree object.
|
|
1747
|
+
*/
|
|
1748
|
+
map(callback: (entry: [BTNKey, V | undefined], tree: this) => V) {
|
|
1749
|
+
const newTree = this.createTree();
|
|
1750
|
+
for (const [key, value] of this) {
|
|
1751
|
+
newTree.add(key, callback([key, value], this));
|
|
1752
|
+
}
|
|
1753
|
+
return newTree;
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
/**
|
|
1757
|
+
* The `reduce` function iterates over the entries of a tree and applies a callback function to each
|
|
1758
|
+
* entry, accumulating a single value.
|
|
1759
|
+
* @param callback - The callback parameter is a function that takes three arguments: accumulator,
|
|
1760
|
+
* entry, and tree. It is called for each entry in the tree and is used to accumulate a single value
|
|
1761
|
+
* based on the logic defined in the callback function.
|
|
1762
|
+
* @param {T} initialValue - The initialValue parameter is the initial value of the accumulator. It
|
|
1763
|
+
* is the value that will be passed as the first argument to the callback function when reducing the
|
|
1764
|
+
* elements of the tree.
|
|
1765
|
+
* @returns The `reduce` method is returning the final value of the accumulator after iterating over
|
|
1766
|
+
* all the entries in the tree and applying the callback function to each entry.
|
|
1767
|
+
*/
|
|
1768
|
+
reduce<T>(callback: (accumulator: T, entry: [BTNKey, V | undefined], tree: this) => T, initialValue: T): T {
|
|
1769
|
+
let accumulator = initialValue;
|
|
1770
|
+
for (const [key, value] of this) {
|
|
1771
|
+
accumulator = callback(accumulator, [key, value], this);
|
|
1772
|
+
}
|
|
1773
|
+
return accumulator;
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
|
|
1688
1777
|
/**
|
|
1689
1778
|
* The above function is an iterator for a binary tree that can be used to traverse the tree in
|
|
1690
1779
|
* either an iterative or recursive manner.
|
|
@@ -1694,32 +1783,32 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1694
1783
|
* @returns The `*[Symbol.iterator]` method returns a generator object that yields the keys of the
|
|
1695
1784
|
* binary tree nodes in a specific order.
|
|
1696
1785
|
*/
|
|
1697
|
-
* [Symbol.iterator](node = this.root): Generator<BTNKey, void, undefined> {
|
|
1698
|
-
if (!node)
|
|
1699
|
-
return;
|
|
1700
|
-
}
|
|
1786
|
+
* [Symbol.iterator](node = this.root): Generator<[BTNKey, V | undefined], void, undefined> {
|
|
1787
|
+
if (!node) return;
|
|
1701
1788
|
|
|
1702
|
-
if (this.iterationType === IterationType.ITERATIVE) {
|
|
1789
|
+
if (this.options.iterationType === IterationType.ITERATIVE) {
|
|
1703
1790
|
const stack: (N | null | undefined)[] = [];
|
|
1704
1791
|
let current: N | null | undefined = node;
|
|
1705
1792
|
|
|
1706
1793
|
while (current || stack.length > 0) {
|
|
1707
|
-
while (current) {
|
|
1794
|
+
while (current && !isNaN(current.key)) {
|
|
1708
1795
|
stack.push(current);
|
|
1709
1796
|
current = current.left;
|
|
1710
1797
|
}
|
|
1711
1798
|
|
|
1712
1799
|
current = stack.pop();
|
|
1713
1800
|
|
|
1714
|
-
if (current
|
|
1715
|
-
|
|
1801
|
+
if (current && !isNaN(current.key)) {
|
|
1802
|
+
yield [current.key, current.value];
|
|
1803
|
+
current = current.right;
|
|
1804
|
+
}
|
|
1716
1805
|
}
|
|
1717
1806
|
} else {
|
|
1718
|
-
if (node.left) {
|
|
1807
|
+
if (node.left && !isNaN(node.key)) {
|
|
1719
1808
|
yield* this[Symbol.iterator](node.left);
|
|
1720
1809
|
}
|
|
1721
|
-
yield node.key;
|
|
1722
|
-
if (node.right) {
|
|
1810
|
+
yield [node.key, node.value];
|
|
1811
|
+
if (node.right && !isNaN(node.key)) {
|
|
1723
1812
|
yield* this[Symbol.iterator](node.right);
|
|
1724
1813
|
}
|
|
1725
1814
|
}
|
|
@@ -1727,16 +1816,25 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1727
1816
|
|
|
1728
1817
|
/**
|
|
1729
1818
|
* The `print` function is used to display a binary tree structure in a visually appealing way.
|
|
1730
|
-
* @param {N | null | undefined} beginRoot - The `root` parameter is of type `BTNKey | N | null |
|
|
1819
|
+
* @param {BTNKey | N | null | undefined} [beginRoot=this.root] - The `root` parameter is of type `BTNKey | N | null |
|
|
1731
1820
|
* undefined`. It represents the root node of a binary tree. The root node can have one of the
|
|
1732
1821
|
* following types:
|
|
1822
|
+
* @param {BinaryTreePrintOptions} [options={ isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false}] - Options object that controls printing behavior. You can specify whether to display undefined, null, or sentinel nodes.
|
|
1733
1823
|
*/
|
|
1734
|
-
print(beginRoot: BTNKey | N | null | undefined = this.root): void {
|
|
1824
|
+
print(beginRoot: BTNKey | N | null | undefined = this.root, options?: BinaryTreePrintOptions): void {
|
|
1825
|
+
const opts = { isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false, ...options };
|
|
1735
1826
|
beginRoot = this.ensureNotKey(beginRoot);
|
|
1736
1827
|
if (!beginRoot) return;
|
|
1737
1828
|
|
|
1829
|
+
if (opts.isShowUndefined) console.log(`U for undefined
|
|
1830
|
+
`);
|
|
1831
|
+
if (opts.isShowNull) console.log(`N for null
|
|
1832
|
+
`);
|
|
1833
|
+
if (opts.isShowRedBlackNIL) console.log(`S for Sentinel Node
|
|
1834
|
+
`);
|
|
1835
|
+
|
|
1738
1836
|
const display = (root: N | null | undefined): void => {
|
|
1739
|
-
const [lines, , ,] = this._displayAux(root);
|
|
1837
|
+
const [lines, , ,] = this._displayAux(root, opts);
|
|
1740
1838
|
for (const line of lines) {
|
|
1741
1839
|
console.log(line);
|
|
1742
1840
|
}
|
|
@@ -1745,39 +1843,54 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|
|
1745
1843
|
display(beginRoot);
|
|
1746
1844
|
}
|
|
1747
1845
|
|
|
1748
|
-
protected _displayAux(node: N | null | undefined
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
}
|
|
1846
|
+
protected _displayAux(node: N | null | undefined, options: BinaryTreePrintOptions): NodeDisplayLayout {
|
|
1847
|
+
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
1848
|
+
const emptyDisplayLayout = <NodeDisplayLayout>[['─'], 1, 0, 0];
|
|
1752
1849
|
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
if (
|
|
1757
|
-
return
|
|
1758
|
-
}
|
|
1850
|
+
// Check if node is null or undefined or key is NaN
|
|
1851
|
+
if (node === null && !isShowNull) {
|
|
1852
|
+
return emptyDisplayLayout;
|
|
1853
|
+
} else if (node === undefined && !isShowUndefined) {
|
|
1854
|
+
return emptyDisplayLayout;
|
|
1855
|
+
} else if (node !== null && node !== undefined && isNaN(node.key) && !isShowRedBlackNIL) {
|
|
1856
|
+
return emptyDisplayLayout;
|
|
1857
|
+
} else if (node !== null && node !== undefined) {
|
|
1858
|
+
// Display logic of normal nodes
|
|
1759
1859
|
|
|
1760
|
-
|
|
1761
|
-
const [rightLines, rightWidth, rightHeight, rightMiddle] = node.right ? this._displayAux(node.right) : [[''], 0, 0, 0];
|
|
1860
|
+
const key = node.key, line = isNaN(key) ? 'S' : key.toString(), width = line.length;
|
|
1762
1861
|
|
|
1763
|
-
|
|
1764
|
-
+ '_'.repeat(Math.max(0, leftWidth - leftMiddle - 1))
|
|
1765
|
-
+ line
|
|
1766
|
-
+ '_'.repeat(Math.max(0, rightMiddle))
|
|
1767
|
-
+ ' '.repeat(Math.max(0, rightWidth - rightMiddle));
|
|
1862
|
+
return _buildNodeDisplay(line, width, this._displayAux(node.left, options), this._displayAux(node.right, options))
|
|
1768
1863
|
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1864
|
+
} else {
|
|
1865
|
+
// For cases where none of the conditions are met, null, undefined, and NaN nodes are not displayed
|
|
1866
|
+
const line = node === undefined ? 'U' : 'N', width = line.length;
|
|
1772
1867
|
|
|
1773
|
-
|
|
1774
|
-
for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
|
|
1775
|
-
const leftLine = i < leftHeight ? leftLines[i] : ' '.repeat(leftWidth);
|
|
1776
|
-
const rightLine = i < rightHeight ? rightLines[i] : ' '.repeat(rightWidth);
|
|
1777
|
-
mergedLines.push(leftLine + ' '.repeat(width) + rightLine);
|
|
1868
|
+
return _buildNodeDisplay(line, width, [[''], 1, 0, 0], [[''], 1, 0, 0])
|
|
1778
1869
|
}
|
|
1779
1870
|
|
|
1780
|
-
|
|
1871
|
+
function _buildNodeDisplay(line: string, width: number, left: NodeDisplayLayout, right: NodeDisplayLayout) {
|
|
1872
|
+
const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
|
|
1873
|
+
const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
|
|
1874
|
+
const firstLine = ' '.repeat(Math.max(0, leftMiddle + 1))
|
|
1875
|
+
+ '_'.repeat(Math.max(0, leftWidth - leftMiddle - 1))
|
|
1876
|
+
+ line
|
|
1877
|
+
+ '_'.repeat(Math.max(0, rightMiddle))
|
|
1878
|
+
+ ' '.repeat(Math.max(0, rightWidth - rightMiddle));
|
|
1879
|
+
|
|
1880
|
+
const secondLine = (leftHeight > 0 ? ' '.repeat(leftMiddle) + '/' + ' '.repeat(leftWidth - leftMiddle - 1) : ' '.repeat(leftWidth))
|
|
1881
|
+
+ ' '.repeat(width)
|
|
1882
|
+
+ (rightHeight > 0 ? ' '.repeat(rightMiddle) + '\\' + ' '.repeat(rightWidth - rightMiddle - 1) : ' '.repeat(rightWidth));
|
|
1883
|
+
|
|
1884
|
+
const mergedLines = [firstLine, secondLine];
|
|
1885
|
+
|
|
1886
|
+
for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
|
|
1887
|
+
const leftLine = i < leftHeight ? leftLines[i] : ' '.repeat(leftWidth);
|
|
1888
|
+
const rightLine = i < rightHeight ? rightLines[i] : ' '.repeat(rightWidth);
|
|
1889
|
+
mergedLines.push(leftLine + ' '.repeat(width) + rightLine);
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
return <NodeDisplayLayout>[mergedLines, leftWidth + width + rightWidth, Math.max(leftHeight, rightHeight) + 2, leftWidth + Math.floor(width / 2)];
|
|
1893
|
+
}
|
|
1781
1894
|
}
|
|
1782
1895
|
|
|
1783
1896
|
protected _defaultOneParamCallback = (node: N) => node.key;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
8
|
+
import type { BSTNested, BSTNodeNested, BSTOptions, BTNCallback, BTNKey } from '../../types';
|
|
9
9
|
import { CP, IterationType } from '../../types';
|
|
10
10
|
import { BinaryTree, BinaryTreeNode } from './binary-tree';
|
|
11
11
|
import { IBinaryTree } from '../../interfaces';
|
|
@@ -62,9 +62,12 @@ export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extend
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>>
|
|
66
|
-
extends BinaryTree<V, N>
|
|
67
|
-
implements IBinaryTree<V, N> {
|
|
65
|
+
export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>, TREE extends BST<V, N, TREE> = BST<V, N, BSTNested<V, N>>>
|
|
66
|
+
extends BinaryTree<V, N, TREE>
|
|
67
|
+
implements IBinaryTree<V, N, TREE> {
|
|
68
|
+
|
|
69
|
+
override options: BSTOptions;
|
|
70
|
+
|
|
68
71
|
/**
|
|
69
72
|
* The constructor function initializes a binary search tree with an optional comparator function.
|
|
70
73
|
* @param {BSTOptions} [options] - An optional object that contains additional configuration options
|
|
@@ -72,13 +75,12 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
72
75
|
*/
|
|
73
76
|
constructor(options?: BSTOptions) {
|
|
74
77
|
super(options);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
this._comparator = comparator;
|
|
80
|
-
}
|
|
78
|
+
if (options) {
|
|
79
|
+
this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b, ...options }
|
|
80
|
+
} else {
|
|
81
|
+
this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b };
|
|
81
82
|
}
|
|
83
|
+
this._root = undefined;
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
protected override _root?: N;
|
|
@@ -102,6 +104,10 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
102
104
|
return new BSTNode<V, N>(key, value) as N;
|
|
103
105
|
}
|
|
104
106
|
|
|
107
|
+
override createTree(options?: BSTOptions): TREE {
|
|
108
|
+
return new BST<V, N, TREE>({ ...this.options, ...options }) as TREE;
|
|
109
|
+
}
|
|
110
|
+
|
|
105
111
|
/**
|
|
106
112
|
* Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n).
|
|
107
113
|
* Space Complexity: O(1) - Constant space is used.
|
|
@@ -215,7 +221,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
215
221
|
keysOrNodes: (BTNKey | N | undefined)[],
|
|
216
222
|
data?: (V | undefined)[],
|
|
217
223
|
isBalanceAdd = true,
|
|
218
|
-
iterationType = this.iterationType
|
|
224
|
+
iterationType = this.options.iterationType
|
|
219
225
|
): (N | undefined)[] {
|
|
220
226
|
// TODO this addMany function is inefficient, it should be optimized
|
|
221
227
|
function hasNoUndefined(arr: (BTNKey | N | undefined)[]): arr is (BTNKey | N)[] {
|
|
@@ -310,7 +316,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
310
316
|
* the key of the leftmost node if the comparison result is greater than, and the key of the
|
|
311
317
|
* rightmost node otherwise. If no node is found, it returns 0.
|
|
312
318
|
*/
|
|
313
|
-
lastKey(beginRoot: BTNKey | N | undefined = this.root, iterationType = this.iterationType): BTNKey {
|
|
319
|
+
lastKey(beginRoot: BTNKey | N | undefined = this.root, iterationType = this.options.iterationType): BTNKey {
|
|
314
320
|
if (this._compare(0, 1) === CP.lt) return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
|
|
315
321
|
else if (this._compare(0, 1) === CP.gt) return this.getLeftMost(beginRoot, iterationType)?.key ?? 0;
|
|
316
322
|
else return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
|
|
@@ -406,7 +412,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
406
412
|
callback: C = this._defaultOneParamCallback as C,
|
|
407
413
|
onlyOne = false,
|
|
408
414
|
beginRoot: BTNKey | N | undefined = this.root,
|
|
409
|
-
iterationType = this.iterationType
|
|
415
|
+
iterationType = this.options.iterationType
|
|
410
416
|
): N[] {
|
|
411
417
|
beginRoot = this.ensureNotKey(beginRoot);
|
|
412
418
|
if (!beginRoot) return [];
|
|
@@ -487,7 +493,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
487
493
|
callback: C = this._defaultOneParamCallback as C,
|
|
488
494
|
lesserOrGreater: CP = CP.lt,
|
|
489
495
|
targetNode: BTNKey | N | undefined = this.root,
|
|
490
|
-
iterationType = this.iterationType
|
|
496
|
+
iterationType = this.options.iterationType
|
|
491
497
|
): ReturnType<C>[] {
|
|
492
498
|
targetNode = this.ensureNotKey(targetNode);
|
|
493
499
|
const ans: ReturnType<BTNCallback<N>>[] = [];
|
|
@@ -550,7 +556,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
550
556
|
* values:
|
|
551
557
|
* @returns The function `perfectlyBalance` returns a boolean value.
|
|
552
558
|
*/
|
|
553
|
-
perfectlyBalance(iterationType = this.iterationType): boolean {
|
|
559
|
+
perfectlyBalance(iterationType = this.options.iterationType): boolean {
|
|
554
560
|
const sorted = this.dfs(node => node, 'in'),
|
|
555
561
|
n = sorted.length;
|
|
556
562
|
this.clear();
|
|
@@ -602,7 +608,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
602
608
|
* to check if the AVL tree is balanced. It can have two possible values:
|
|
603
609
|
* @returns a boolean value.
|
|
604
610
|
*/
|
|
605
|
-
isAVLBalanced(iterationType = this.iterationType): boolean {
|
|
611
|
+
isAVLBalanced(iterationType = this.options.iterationType): boolean {
|
|
606
612
|
if (!this.root) return true;
|
|
607
613
|
|
|
608
614
|
let balanced = true;
|
|
@@ -646,8 +652,6 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
646
652
|
return balanced;
|
|
647
653
|
}
|
|
648
654
|
|
|
649
|
-
protected _comparator: BSTComparator = (a, b) => a - b;
|
|
650
|
-
|
|
651
655
|
protected _setRoot(v: N | undefined) {
|
|
652
656
|
if (v) {
|
|
653
657
|
v.parent = undefined;
|
|
@@ -664,7 +668,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
664
668
|
* than), CP.lt (less than), or CP.eq (equal).
|
|
665
669
|
*/
|
|
666
670
|
protected _compare(a: BTNKey, b: BTNKey): CP {
|
|
667
|
-
const compared = this.
|
|
671
|
+
const compared = this.options.comparator!(a, b);
|
|
668
672
|
if (compared > 0) return CP.gt;
|
|
669
673
|
else if (compared < 0) return CP.lt;
|
|
670
674
|
else return CP.eq;
|