binary-tree-typed 1.53.7 → 1.54.0
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/common/index.js +5 -0
- package/dist/data-structures/base/iterable-entry-base.js +4 -4
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +34 -27
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +63 -53
- package/dist/data-structures/binary-tree/avl-tree.d.ts +3 -14
- package/dist/data-structures/binary-tree/avl-tree.js +22 -25
- package/dist/data-structures/binary-tree/binary-tree.d.ts +33 -17
- package/dist/data-structures/binary-tree/binary-tree.js +45 -26
- package/dist/data-structures/binary-tree/bst.d.ts +67 -46
- package/dist/data-structures/binary-tree/bst.js +87 -54
- 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 → red-black-tree.d.ts} +75 -16
- package/dist/data-structures/binary-tree/{rb-tree.js → red-black-tree.js} +93 -60
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +20 -16
- package/dist/data-structures/binary-tree/tree-multi-map.js +41 -28
- package/dist/data-structures/graph/abstract-graph.js +2 -2
- package/dist/data-structures/hash/hash-map.d.ts +31 -1
- package/dist/data-structures/hash/hash-map.js +35 -5
- package/dist/data-structures/heap/heap.d.ts +20 -3
- package/dist/data-structures/heap/heap.js +31 -11
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +46 -11
- package/dist/data-structures/linked-list/doubly-linked-list.js +68 -21
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +44 -11
- package/dist/data-structures/linked-list/singly-linked-list.js +70 -26
- package/dist/data-structures/queue/deque.d.ts +37 -8
- package/dist/data-structures/queue/deque.js +73 -29
- package/dist/data-structures/queue/queue.d.ts +41 -1
- package/dist/data-structures/queue/queue.js +51 -9
- package/dist/data-structures/stack/stack.d.ts +27 -10
- package/dist/data-structures/stack/stack.js +39 -20
- package/dist/data-structures/trie/trie.d.ts +8 -3
- package/dist/data-structures/trie/trie.js +8 -3
- package/dist/interfaces/binary-tree.d.ts +1 -1
- package/dist/types/data-structures/base/base.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +2 -2
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +2 -2
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +2 -2
- package/dist/types/data-structures/binary-tree/bst.d.ts +3 -3
- package/dist/types/data-structures/binary-tree/rb-tree.d.ts +3 -3
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +4 -4
- package/package.json +2 -2
- package/src/common/index.ts +7 -1
- package/src/data-structures/base/iterable-entry-base.ts +4 -4
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +84 -65
- package/src/data-structures/binary-tree/avl-tree.ts +40 -34
- package/src/data-structures/binary-tree/binary-tree.ts +76 -32
- package/src/data-structures/binary-tree/bst.ts +121 -68
- package/src/data-structures/binary-tree/index.ts +1 -1
- package/src/data-structures/binary-tree/{rb-tree.ts → red-black-tree.ts} +116 -71
- package/src/data-structures/binary-tree/tree-multi-map.ts +59 -33
- package/src/data-structures/graph/abstract-graph.ts +2 -2
- package/src/data-structures/hash/hash-map.ts +37 -7
- package/src/data-structures/heap/heap.ts +33 -10
- package/src/data-structures/linked-list/doubly-linked-list.ts +75 -21
- package/src/data-structures/linked-list/singly-linked-list.ts +77 -27
- package/src/data-structures/queue/deque.ts +72 -28
- package/src/data-structures/queue/queue.ts +50 -7
- package/src/data-structures/stack/stack.ts +39 -20
- package/src/data-structures/trie/trie.ts +8 -3
- package/src/interfaces/binary-tree.ts +4 -1
- package/src/types/data-structures/base/base.ts +1 -1
- package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +2 -2
- package/src/types/data-structures/binary-tree/avl-tree.ts +2 -2
- package/src/types/data-structures/binary-tree/binary-tree.ts +2 -2
- package/src/types/data-structures/binary-tree/bst.ts +3 -3
- package/src/types/data-structures/binary-tree/rb-tree.ts +3 -3
- package/src/types/data-structures/binary-tree/tree-multi-map.ts +4 -4
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
NodeDisplayLayout,
|
|
24
24
|
NodePredicate,
|
|
25
25
|
OptNodeOrNull,
|
|
26
|
+
type RBTNColor,
|
|
26
27
|
ToEntryFn
|
|
27
28
|
} from '../../types';
|
|
28
29
|
import { IBinaryTree } from '../../interfaces';
|
|
@@ -52,7 +53,7 @@ export class BinaryTreeNode<
|
|
|
52
53
|
this.value = value;
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
_left?: OptNodeOrNull<NODE>;
|
|
56
57
|
|
|
57
58
|
get left(): OptNodeOrNull<NODE> {
|
|
58
59
|
return this._left;
|
|
@@ -65,7 +66,7 @@ export class BinaryTreeNode<
|
|
|
65
66
|
this._left = v;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
_right?: OptNodeOrNull<NODE>;
|
|
69
70
|
|
|
70
71
|
get right(): OptNodeOrNull<NODE> {
|
|
71
72
|
return this._right;
|
|
@@ -78,6 +79,36 @@ export class BinaryTreeNode<
|
|
|
78
79
|
this._right = v;
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
_height: number = 0;
|
|
83
|
+
|
|
84
|
+
get height(): number {
|
|
85
|
+
return this._height;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
set height(value: number) {
|
|
89
|
+
this._height = value;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
_color: RBTNColor = 'BLACK';
|
|
93
|
+
|
|
94
|
+
get color(): RBTNColor {
|
|
95
|
+
return this._color;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
set color(value: RBTNColor) {
|
|
99
|
+
this._color = value;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
_count: number = 1;
|
|
103
|
+
|
|
104
|
+
get count(): number {
|
|
105
|
+
return this._count;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
set count(value: number) {
|
|
109
|
+
this._count = value;
|
|
110
|
+
}
|
|
111
|
+
|
|
81
112
|
get familyPosition(): FamilyPosition {
|
|
82
113
|
const that = this as unknown as NODE;
|
|
83
114
|
if (!this.parent) {
|
|
@@ -105,11 +136,23 @@ export class BinaryTree<
|
|
|
105
136
|
K = any,
|
|
106
137
|
V = any,
|
|
107
138
|
R = object,
|
|
139
|
+
MK = any,
|
|
140
|
+
MV = any,
|
|
141
|
+
MR = object,
|
|
108
142
|
NODE extends BinaryTreeNode<K, V, NODE> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>,
|
|
109
|
-
TREE extends BinaryTree<K, V, R,
|
|
143
|
+
TREE extends BinaryTree<K, V, R, MK, MV, MR, NODE, TREE> = BinaryTree<
|
|
144
|
+
K,
|
|
145
|
+
V,
|
|
146
|
+
R,
|
|
147
|
+
MK,
|
|
148
|
+
MV,
|
|
149
|
+
MR,
|
|
150
|
+
NODE,
|
|
151
|
+
BinaryTreeNested<K, V, R, MK, MV, MR, NODE>
|
|
152
|
+
>
|
|
110
153
|
>
|
|
111
154
|
extends IterableEntryBase<K, V | undefined>
|
|
112
|
-
implements IBinaryTree<K, V, R, NODE, TREE>
|
|
155
|
+
implements IBinaryTree<K, V, R, MK, MV, MR, NODE, TREE>
|
|
113
156
|
{
|
|
114
157
|
iterationType: IterationType = 'ITERATIVE';
|
|
115
158
|
|
|
@@ -172,6 +215,9 @@ export class BinaryTree<
|
|
|
172
215
|
}
|
|
173
216
|
|
|
174
217
|
/**
|
|
218
|
+
* Time Complexity: O(1)
|
|
219
|
+
* Space Complexity: O(1)
|
|
220
|
+
*
|
|
175
221
|
* The function creates a new binary tree node with a specified key and optional value.
|
|
176
222
|
* @param {K} key - The `key` parameter is the key of the node being created in the binary tree.
|
|
177
223
|
* @param {V} [value] - The `value` parameter in the `createNode` function is optional, meaning it is
|
|
@@ -193,7 +239,7 @@ export class BinaryTree<
|
|
|
193
239
|
* @returns A new instance of a binary tree with the specified options is being returned.
|
|
194
240
|
*/
|
|
195
241
|
createTree(options?: BinaryTreeOptions<K, V, R>): TREE {
|
|
196
|
-
return new BinaryTree<K, V, R, NODE, TREE>([], {
|
|
242
|
+
return new BinaryTree<K, V, R, MK, MV, MR, NODE, TREE>([], {
|
|
197
243
|
iterationType: this.iterationType,
|
|
198
244
|
isMapMode: this._isMapMode,
|
|
199
245
|
toEntryFn: this._toEntryFn,
|
|
@@ -216,7 +262,7 @@ export class BinaryTree<
|
|
|
216
262
|
* input parameter (`keyNodeEntryOrRaw`) and processes it accordingly to return a node or null
|
|
217
263
|
* value.
|
|
218
264
|
*/
|
|
219
|
-
|
|
265
|
+
protected _keyValueNodeEntryRawToNodeAndValue(
|
|
220
266
|
keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
|
|
221
267
|
value?: V
|
|
222
268
|
): [OptNodeOrNull<NODE>, V | undefined] {
|
|
@@ -420,7 +466,7 @@ export class BinaryTree<
|
|
|
420
466
|
* key was found and the node was replaced instead of inserted.
|
|
421
467
|
*/
|
|
422
468
|
add(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R, value?: V): boolean {
|
|
423
|
-
const [newNode, newValue] = this.
|
|
469
|
+
const [newNode, newValue] = this._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
|
|
424
470
|
if (newNode === undefined) return false;
|
|
425
471
|
|
|
426
472
|
// If the tree is empty, directly set the new node as the root node
|
|
@@ -1673,7 +1719,7 @@ export class BinaryTree<
|
|
|
1673
1719
|
const newTree = this.createTree();
|
|
1674
1720
|
let index = 0;
|
|
1675
1721
|
for (const [key, value] of this) {
|
|
1676
|
-
if (predicate.call(thisArg,
|
|
1722
|
+
if (predicate.call(thisArg, key, value, index++, this)) {
|
|
1677
1723
|
newTree.add([key, value]);
|
|
1678
1724
|
}
|
|
1679
1725
|
}
|
|
@@ -1684,36 +1730,34 @@ export class BinaryTree<
|
|
|
1684
1730
|
* Time Complexity: O(n)
|
|
1685
1731
|
* Space Complexity: O(n)
|
|
1686
1732
|
*
|
|
1687
|
-
* The `map` function
|
|
1688
|
-
*
|
|
1689
|
-
* @param callback -
|
|
1690
|
-
*
|
|
1691
|
-
*
|
|
1692
|
-
*
|
|
1693
|
-
*
|
|
1694
|
-
*
|
|
1695
|
-
*
|
|
1696
|
-
*
|
|
1733
|
+
* The `map` function in TypeScript creates a new BinaryTree by applying a callback function to each
|
|
1734
|
+
* entry in the original BinaryTree.
|
|
1735
|
+
* @param callback - A function that will be called for each entry in the current binary tree. It
|
|
1736
|
+
* takes the key, value (which can be undefined), and an array containing the mapped key and value as
|
|
1737
|
+
* arguments.
|
|
1738
|
+
* @param [options] - The `options` parameter in the `map` method is of type `BinaryTreeOptions<MK,
|
|
1739
|
+
* MV, MR>`. It is an optional parameter that allows you to specify additional options for the binary
|
|
1740
|
+
* tree being created during the mapping process. These options could include things like custom
|
|
1741
|
+
* comparators, initial
|
|
1742
|
+
* @param {any} [thisArg] - The `thisArg` parameter in the `map` method is used to specify the value
|
|
1743
|
+
* of `this` when executing the `callback` function. It allows you to set the context (value of
|
|
1744
|
+
* `this`) within the callback function. If `thisArg` is provided, it will be passed
|
|
1745
|
+
* @returns The `map` function is returning a new `BinaryTree` instance filled with entries that are
|
|
1746
|
+
* the result of applying the provided `callback` function to each entry in the original tree.
|
|
1697
1747
|
*/
|
|
1698
|
-
map(
|
|
1699
|
-
|
|
1748
|
+
map(
|
|
1749
|
+
callback: EntryCallback<K, V | undefined, [MK, MV]>,
|
|
1750
|
+
options?: BinaryTreeOptions<MK, MV, MR>,
|
|
1751
|
+
thisArg?: any
|
|
1752
|
+
): BinaryTree<MK, MV, MR> {
|
|
1753
|
+
const newTree = new BinaryTree<MK, MV, MR>([], options);
|
|
1700
1754
|
let index = 0;
|
|
1701
1755
|
for (const [key, value] of this) {
|
|
1702
|
-
newTree.add(
|
|
1756
|
+
newTree.add(callback.call(thisArg, key, value, index++, this));
|
|
1703
1757
|
}
|
|
1704
1758
|
return newTree;
|
|
1705
1759
|
}
|
|
1706
1760
|
|
|
1707
|
-
// // TODO Type error, need to return a TREE<NV> that is a value type only for callback function.
|
|
1708
|
-
// // map<NV>(callback: (entry: [K, V | undefined], tree: this) => NV) {
|
|
1709
|
-
// // const newTree = this.createTree();
|
|
1710
|
-
// // for (const [key, value] of this) {
|
|
1711
|
-
// // newTree.add(key, callback([key, value], this));
|
|
1712
|
-
// // }
|
|
1713
|
-
// // return newTree;
|
|
1714
|
-
// // }
|
|
1715
|
-
//
|
|
1716
|
-
|
|
1717
1761
|
/**
|
|
1718
1762
|
* Time Complexity: O(n)
|
|
1719
1763
|
* Space Complexity: O(n)
|
|
@@ -1743,7 +1787,7 @@ export class BinaryTree<
|
|
|
1743
1787
|
if (opts.isShowRedBlackNIL) output += `S for Sentinel Node(NIL)\n`;
|
|
1744
1788
|
|
|
1745
1789
|
const display = (root: OptNodeOrNull<NODE>): void => {
|
|
1746
|
-
const [lines, ,
|
|
1790
|
+
const [lines, ,] = this._displayAux(root, opts);
|
|
1747
1791
|
let paragraph = '';
|
|
1748
1792
|
for (const line of lines) {
|
|
1749
1793
|
paragraph += line + '\n';
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
-
import
|
|
8
|
+
import {
|
|
9
9
|
BSTNested,
|
|
10
10
|
BSTNodeNested,
|
|
11
11
|
BSTNOptKeyOrNode,
|
|
@@ -15,10 +15,12 @@ import type {
|
|
|
15
15
|
Comparator,
|
|
16
16
|
CP,
|
|
17
17
|
DFSOrderPattern,
|
|
18
|
+
EntryCallback,
|
|
18
19
|
IterationType,
|
|
19
20
|
NodeCallback,
|
|
20
21
|
NodePredicate,
|
|
21
|
-
OptNode
|
|
22
|
+
OptNode,
|
|
23
|
+
OptNodeOrNull
|
|
22
24
|
} from '../../types';
|
|
23
25
|
import { BinaryTree, BinaryTreeNode } from './binary-tree';
|
|
24
26
|
import { IBinaryTree } from '../../interfaces';
|
|
@@ -40,13 +42,13 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
|
|
|
40
42
|
this._right = undefined;
|
|
41
43
|
}
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
override _left?: OptNodeOrNull<NODE>;
|
|
44
46
|
|
|
45
47
|
/**
|
|
46
48
|
* The function returns the value of the `_left` property.
|
|
47
49
|
* @returns The `_left` property of the current object is being returned.
|
|
48
50
|
*/
|
|
49
|
-
override get left():
|
|
51
|
+
override get left(): OptNodeOrNull<NODE> {
|
|
50
52
|
return this._left;
|
|
51
53
|
}
|
|
52
54
|
|
|
@@ -55,21 +57,21 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
|
|
|
55
57
|
* @param {OptNode<NODE>} v - The parameter `v` is of type `OptNode<NODE>`. It can either be an
|
|
56
58
|
* instance of the `NODE` class or `undefined`.
|
|
57
59
|
*/
|
|
58
|
-
override set left(v:
|
|
60
|
+
override set left(v: OptNodeOrNull<NODE>) {
|
|
59
61
|
if (v) {
|
|
60
62
|
v.parent = this as unknown as NODE;
|
|
61
63
|
}
|
|
62
64
|
this._left = v;
|
|
63
65
|
}
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
override _right?: OptNodeOrNull<NODE>;
|
|
66
68
|
|
|
67
69
|
/**
|
|
68
70
|
* The function returns the right node of a binary tree or undefined if there is no right node.
|
|
69
71
|
* @returns The method is returning the value of the `_right` property, which is of type `NODE` or
|
|
70
72
|
* `undefined`.
|
|
71
73
|
*/
|
|
72
|
-
override get right():
|
|
74
|
+
override get right(): OptNodeOrNull<NODE> {
|
|
73
75
|
return this._right;
|
|
74
76
|
}
|
|
75
77
|
|
|
@@ -78,7 +80,7 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
|
|
|
78
80
|
* @param {OptNode<NODE>} v - The parameter `v` is of type `OptNode<NODE>`. It can either be a
|
|
79
81
|
* `NODE` object or `undefined`.
|
|
80
82
|
*/
|
|
81
|
-
override set right(v:
|
|
83
|
+
override set right(v: OptNodeOrNull<NODE>) {
|
|
82
84
|
if (v) {
|
|
83
85
|
v.parent = this as unknown as NODE;
|
|
84
86
|
}
|
|
@@ -95,32 +97,48 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
|
|
|
95
97
|
* 6. Balance Variability: Can become unbalanced; special types maintain balance.
|
|
96
98
|
* 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.
|
|
97
99
|
* @example
|
|
98
|
-
* //
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
100
|
+
* // Merge 3 sorted datasets
|
|
101
|
+
* const dataset1 = new BST<number, string>([
|
|
102
|
+
* [1, 'A'],
|
|
103
|
+
* [7, 'G']
|
|
104
|
+
* ]);
|
|
105
|
+
* const dataset2 = [
|
|
106
|
+
* [2, 'B'],
|
|
107
|
+
* [6, 'F']
|
|
108
|
+
* ];
|
|
109
|
+
* const dataset3 = new BST<number, string>([
|
|
110
|
+
* [3, 'C'],
|
|
111
|
+
* [5, 'E'],
|
|
112
|
+
* [4, 'D']
|
|
113
|
+
* ]);
|
|
102
114
|
*
|
|
103
|
-
* //
|
|
104
|
-
* const
|
|
105
|
-
*
|
|
106
|
-
*
|
|
115
|
+
* // Merge datasets into a single BinarySearchTree
|
|
116
|
+
* const merged = new BST<number, string>(dataset1);
|
|
117
|
+
* merged.addMany(dataset2);
|
|
118
|
+
* merged.merge(dataset3);
|
|
107
119
|
*
|
|
108
|
-
* //
|
|
109
|
-
* console.log(
|
|
110
|
-
* console.log(findKthSmallest(3)); // 4
|
|
111
|
-
* console.log(findKthSmallest(7)); // 8
|
|
120
|
+
* // Verify merged dataset is in sorted order
|
|
121
|
+
* console.log([...merged.values()]); // ['A', 'B', 'C', 'D', 'E', 'F', 'G']
|
|
112
122
|
* @example
|
|
113
123
|
* // Find elements in a range
|
|
114
124
|
* const bst = new BST<number>([10, 5, 15, 3, 7, 12, 18]);
|
|
115
125
|
* console.log(bst.search(new Range(5, 10))); // [10, 5, 7]
|
|
116
|
-
* console.log(bst.
|
|
126
|
+
* console.log(bst.rangeSearch([4, 12], node => node.key.toString())); // ['10', '12', '5', '7']
|
|
117
127
|
* console.log(bst.search(new Range(4, 12, true, false))); // [10, 5, 7]
|
|
118
|
-
* console.log(bst.
|
|
128
|
+
* console.log(bst.rangeSearch([15, 20])); // [15, 18]
|
|
119
129
|
* console.log(bst.search(new Range(15, 20, false))); // [18]
|
|
120
130
|
* @example
|
|
121
131
|
* // Find lowest common ancestor
|
|
122
132
|
* const bst = new BST<number>([20, 10, 30, 5, 15, 25, 35, 3, 7, 12, 18]);
|
|
123
133
|
*
|
|
134
|
+
* // LCA helper function
|
|
135
|
+
* const findLCA = (num1: number, num2: number): number | undefined => {
|
|
136
|
+
* const path1 = bst.getPathToRoot(num1);
|
|
137
|
+
* const path2 = bst.getPathToRoot(num2);
|
|
138
|
+
* // Find the first common ancestor
|
|
139
|
+
* return findFirstCommon(path1, path2);
|
|
140
|
+
* };
|
|
141
|
+
*
|
|
124
142
|
* function findFirstCommon(arr1: number[], arr2: number[]): number | undefined {
|
|
125
143
|
* for (const num of arr1) {
|
|
126
144
|
* if (arr2.indexOf(num) !== -1) {
|
|
@@ -130,14 +148,6 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
|
|
|
130
148
|
* return undefined;
|
|
131
149
|
* }
|
|
132
150
|
*
|
|
133
|
-
* // LCA helper function
|
|
134
|
-
* const findLCA = (num1: number, num2: number): number | undefined => {
|
|
135
|
-
* const path1 = bst.getPathToRoot(num1);
|
|
136
|
-
* const path2 = bst.getPathToRoot(num2);
|
|
137
|
-
* // Find the first common ancestor
|
|
138
|
-
* return findFirstCommon(path1, path2);
|
|
139
|
-
* };
|
|
140
|
-
*
|
|
141
151
|
* // Assertions
|
|
142
152
|
* console.log(findLCA(3, 10)); // 7
|
|
143
153
|
* console.log(findLCA(5, 35)); // 15
|
|
@@ -147,11 +157,23 @@ export class BST<
|
|
|
147
157
|
K = any,
|
|
148
158
|
V = any,
|
|
149
159
|
R = object,
|
|
160
|
+
MK = any,
|
|
161
|
+
MV = any,
|
|
162
|
+
MR = object,
|
|
150
163
|
NODE extends BSTNode<K, V, NODE> = BSTNode<K, V, BSTNodeNested<K, V>>,
|
|
151
|
-
TREE extends BST<K, V, R,
|
|
164
|
+
TREE extends BST<K, V, R, MK, MV, MR, NODE, TREE> = BST<
|
|
165
|
+
K,
|
|
166
|
+
V,
|
|
167
|
+
R,
|
|
168
|
+
MK,
|
|
169
|
+
MV,
|
|
170
|
+
MR,
|
|
171
|
+
NODE,
|
|
172
|
+
BSTNested<K, V, R, MK, MV, MR, NODE>
|
|
173
|
+
>
|
|
152
174
|
>
|
|
153
|
-
extends BinaryTree<K, V, R, NODE, TREE>
|
|
154
|
-
implements IBinaryTree<K, V, R, NODE, TREE>
|
|
175
|
+
extends BinaryTree<K, V, R, MK, MV, MR, NODE, TREE>
|
|
176
|
+
implements IBinaryTree<K, V, R, MK, MV, MR, NODE, TREE>
|
|
155
177
|
{
|
|
156
178
|
/**
|
|
157
179
|
* This is the constructor function for a Binary Search Tree class in TypeScript.
|
|
@@ -165,8 +187,8 @@ export class BST<
|
|
|
165
187
|
super([], options);
|
|
166
188
|
|
|
167
189
|
if (options) {
|
|
168
|
-
const {
|
|
169
|
-
if (typeof
|
|
190
|
+
const { specifyComparable, isReverse } = options;
|
|
191
|
+
if (typeof specifyComparable === 'function') this._specifyComparable = specifyComparable;
|
|
170
192
|
if (isReverse !== undefined) this._isReverse = isReverse;
|
|
171
193
|
}
|
|
172
194
|
|
|
@@ -214,10 +236,10 @@ export class BST<
|
|
|
214
236
|
* @returns a new instance of the BST class with the provided options.
|
|
215
237
|
*/
|
|
216
238
|
override createTree(options?: BSTOptions<K, V, R>): TREE {
|
|
217
|
-
return new BST<K, V, R, NODE, TREE>([], {
|
|
239
|
+
return new BST<K, V, R, MK, MV, MR, NODE, TREE>([], {
|
|
218
240
|
iterationType: this.iterationType,
|
|
219
241
|
isMapMode: this._isMapMode,
|
|
220
|
-
|
|
242
|
+
specifyComparable: this._specifyComparable,
|
|
221
243
|
toEntryFn: this._toEntryFn,
|
|
222
244
|
isReverse: this._isReverse,
|
|
223
245
|
...options
|
|
@@ -233,11 +255,11 @@ export class BST<
|
|
|
233
255
|
* value associated with a key in a key-value pair.
|
|
234
256
|
* @returns either a NODE object or undefined.
|
|
235
257
|
*/
|
|
236
|
-
override
|
|
258
|
+
protected override _keyValueNodeEntryRawToNodeAndValue(
|
|
237
259
|
keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
|
|
238
260
|
value?: V
|
|
239
261
|
): [OptNode<NODE>, V | undefined] {
|
|
240
|
-
const [node, entryValue] = super.
|
|
262
|
+
const [node, entryValue] = super._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
|
|
241
263
|
if (node === null) return [undefined, undefined];
|
|
242
264
|
return [node, value ?? entryValue];
|
|
243
265
|
}
|
|
@@ -284,7 +306,7 @@ export class BST<
|
|
|
284
306
|
* this._DEFAULT_COMPARATOR`.
|
|
285
307
|
*/
|
|
286
308
|
override isKey(key: any): key is K {
|
|
287
|
-
return isComparable(key, this.
|
|
309
|
+
return isComparable(key, this._specifyComparable !== undefined);
|
|
288
310
|
}
|
|
289
311
|
|
|
290
312
|
/**
|
|
@@ -299,7 +321,7 @@ export class BST<
|
|
|
299
321
|
* @returns a boolean value.
|
|
300
322
|
*/
|
|
301
323
|
override add(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R, value?: V): boolean {
|
|
302
|
-
const [newNode, newValue] = this.
|
|
324
|
+
const [newNode, newValue] = this._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
|
|
303
325
|
if (newNode === undefined) return false;
|
|
304
326
|
|
|
305
327
|
if (this._root === undefined) {
|
|
@@ -322,7 +344,7 @@ export class BST<
|
|
|
322
344
|
this._size++;
|
|
323
345
|
return true;
|
|
324
346
|
}
|
|
325
|
-
current = current.left;
|
|
347
|
+
if (current.left !== null) current = current.left;
|
|
326
348
|
} else {
|
|
327
349
|
if (current.right === undefined) {
|
|
328
350
|
current.right = newNode;
|
|
@@ -330,7 +352,7 @@ export class BST<
|
|
|
330
352
|
this._size++;
|
|
331
353
|
return true;
|
|
332
354
|
}
|
|
333
|
-
current = current.right;
|
|
355
|
+
if (current.right !== null) current = current.right;
|
|
334
356
|
}
|
|
335
357
|
}
|
|
336
358
|
|
|
@@ -455,19 +477,6 @@ export class BST<
|
|
|
455
477
|
return inserted;
|
|
456
478
|
}
|
|
457
479
|
|
|
458
|
-
/**
|
|
459
|
-
* Time Complexity: O(n)
|
|
460
|
-
* Space Complexity: O(1)
|
|
461
|
-
*
|
|
462
|
-
* The `merge` function overrides the base class method by adding elements from another
|
|
463
|
-
* binary search tree.
|
|
464
|
-
* @param anotherTree - `anotherTree` is an instance of a Binary Search Tree (BST) with key type `K`,
|
|
465
|
-
* value type `V`, return type `R`, node type `NODE`, and tree type `TREE`.
|
|
466
|
-
*/
|
|
467
|
-
override merge(anotherTree: BST<K, V, R, NODE, TREE>) {
|
|
468
|
-
this.addMany(anotherTree, [], false);
|
|
469
|
-
}
|
|
470
|
-
|
|
471
480
|
/**
|
|
472
481
|
* Time Complexity: O(log n)
|
|
473
482
|
* Space Complexity: O(k + log n)
|
|
@@ -609,6 +618,37 @@ export class BST<
|
|
|
609
618
|
return ans;
|
|
610
619
|
}
|
|
611
620
|
|
|
621
|
+
/**
|
|
622
|
+
* Time Complexity: O(log n)
|
|
623
|
+
* Space Complexity: O(n)
|
|
624
|
+
*
|
|
625
|
+
* The `rangeSearch` function searches for nodes within a specified range in a binary search tree.
|
|
626
|
+
* @param {Range<K> | [K, K]} range - The `range` parameter in the `rangeSearch` function can be
|
|
627
|
+
* either a `Range` object or an array of two elements representing the range boundaries.
|
|
628
|
+
* @param {C} callback - The `callback` parameter in the `rangeSearch` function is a callback
|
|
629
|
+
* function that is used to process each node that is found within the specified range during the
|
|
630
|
+
* search operation. It is of type `NodeCallback<NODE>`, where `NODE` is the type of nodes in the
|
|
631
|
+
* data structure.
|
|
632
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `rangeSearch`
|
|
633
|
+
* function represents the node from which the search for nodes within the specified range will
|
|
634
|
+
* begin. It is the starting point for the range search operation.
|
|
635
|
+
* @param {IterationType} iterationType - The `iterationType` parameter in the `rangeSearch` function
|
|
636
|
+
* is used to specify the type of iteration to be performed during the search operation. It has a
|
|
637
|
+
* default value of `this.iterationType`, which suggests that it is likely a property of the class or
|
|
638
|
+
* object that the `rangeSearch`
|
|
639
|
+
* @returns The `rangeSearch` function is returning the result of calling the `search` method with
|
|
640
|
+
* the specified parameters.
|
|
641
|
+
*/
|
|
642
|
+
rangeSearch<C extends NodeCallback<NODE>>(
|
|
643
|
+
range: Range<K> | [K, K],
|
|
644
|
+
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
645
|
+
startNode: BTNRep<K, V, NODE> | R = this._root,
|
|
646
|
+
iterationType: IterationType = this.iterationType
|
|
647
|
+
) {
|
|
648
|
+
const searchRange: Range<K> = range instanceof Range ? range : new Range(range[0], range[1]);
|
|
649
|
+
return this.search(searchRange, false, callback, startNode, iterationType);
|
|
650
|
+
}
|
|
651
|
+
|
|
612
652
|
/**
|
|
613
653
|
* Time Complexity: O(log n)
|
|
614
654
|
* Space Complexity: O(1)
|
|
@@ -847,7 +887,7 @@ export class BST<
|
|
|
847
887
|
let balanced = true;
|
|
848
888
|
|
|
849
889
|
if (iterationType === 'RECURSIVE') {
|
|
850
|
-
const _height = (cur:
|
|
890
|
+
const _height = (cur: OptNodeOrNull<NODE>): number => {
|
|
851
891
|
if (!cur) return 0;
|
|
852
892
|
const leftHeight = _height(cur.left),
|
|
853
893
|
rightHeight = _height(cur.right);
|
|
@@ -864,7 +904,7 @@ export class BST<
|
|
|
864
904
|
while (stack.length > 0 || node) {
|
|
865
905
|
if (node) {
|
|
866
906
|
stack.push(node);
|
|
867
|
-
node = node.left;
|
|
907
|
+
if (node.left !== null) node = node.left;
|
|
868
908
|
} else {
|
|
869
909
|
node = stack[stack.length - 1];
|
|
870
910
|
if (!node.right || last === node.right) {
|
|
@@ -891,14 +931,14 @@ export class BST<
|
|
|
891
931
|
if (a < b) return -1;
|
|
892
932
|
return 0;
|
|
893
933
|
}
|
|
894
|
-
if (this.
|
|
895
|
-
if (this.
|
|
896
|
-
if (this.
|
|
934
|
+
if (this._specifyComparable) {
|
|
935
|
+
if (this._specifyComparable(a) > this._specifyComparable(b)) return 1;
|
|
936
|
+
if (this._specifyComparable(a) < this._specifyComparable(b)) return -1;
|
|
897
937
|
return 0;
|
|
898
938
|
}
|
|
899
939
|
if (typeof a === 'object' || typeof b === 'object') {
|
|
900
940
|
throw TypeError(
|
|
901
|
-
`When comparing object types, a custom
|
|
941
|
+
`When comparing object types, a custom specifyComparable must be defined in the constructor's options parameter.`
|
|
902
942
|
);
|
|
903
943
|
}
|
|
904
944
|
|
|
@@ -913,15 +953,15 @@ export class BST<
|
|
|
913
953
|
return this._comparator;
|
|
914
954
|
}
|
|
915
955
|
|
|
916
|
-
protected
|
|
956
|
+
protected _specifyComparable?: (key: K) => Comparable;
|
|
917
957
|
|
|
918
958
|
/**
|
|
919
|
-
* This function returns the value of the `
|
|
920
|
-
* @returns The method `
|
|
921
|
-
* `
|
|
959
|
+
* This function returns the value of the `_specifyComparable` property.
|
|
960
|
+
* @returns The method `specifyComparable()` is being returned, which is a getter method for the
|
|
961
|
+
* `_specifyComparable` property.
|
|
922
962
|
*/
|
|
923
|
-
get
|
|
924
|
-
return this.
|
|
963
|
+
get specifyComparable() {
|
|
964
|
+
return this._specifyComparable;
|
|
925
965
|
}
|
|
926
966
|
|
|
927
967
|
/**
|
|
@@ -939,4 +979,17 @@ export class BST<
|
|
|
939
979
|
protected _compare(a: K, b: K) {
|
|
940
980
|
return this._isReverse ? -this._comparator(a, b) : this._comparator(a, b);
|
|
941
981
|
}
|
|
982
|
+
|
|
983
|
+
override map(
|
|
984
|
+
callback: EntryCallback<K, V | undefined, [MK, MV]>,
|
|
985
|
+
options?: BSTOptions<MK, MV, MR>,
|
|
986
|
+
thisArg?: any
|
|
987
|
+
): BST<MK, MV, MR> {
|
|
988
|
+
const newTree = new BST<MK, MV, MR>([], options);
|
|
989
|
+
let index = 0;
|
|
990
|
+
for (const [key, value] of this) {
|
|
991
|
+
newTree.add(callback.call(thisArg, key, value, index++, this));
|
|
992
|
+
}
|
|
993
|
+
return newTree;
|
|
994
|
+
}
|
|
942
995
|
}
|