bst-typed 2.4.0 → 2.4.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/cjs/index.cjs +101 -28
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +104 -32
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +101 -28
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +104 -32
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/data-structures/base/linear-base.d.ts +6 -6
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +6 -6
- package/dist/types/data-structures/binary-tree/bst.d.ts +2 -1
- package/dist/types/data-structures/binary-tree/index.d.ts +3 -3
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +150 -20
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +188 -0
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +238 -147
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +270 -0
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +181 -0
- package/dist/types/interfaces/binary-tree.d.ts +2 -2
- package/dist/types/types/data-structures/binary-tree/index.d.ts +3 -3
- package/dist/types/types/data-structures/binary-tree/tree-map.d.ts +33 -0
- package/dist/types/types/data-structures/binary-tree/tree-multi-set.d.ts +16 -0
- package/dist/types/types/data-structures/binary-tree/tree-set.d.ts +33 -0
- package/dist/umd/bst-typed.js +104 -32
- package/dist/umd/bst-typed.js.map +1 -1
- package/dist/umd/bst-typed.min.js +2 -2
- package/dist/umd/bst-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/data-structures/base/linear-base.ts +2 -12
- package/src/data-structures/binary-tree/avl-tree.ts +1 -1
- package/src/data-structures/binary-tree/binary-tree.ts +45 -21
- package/src/data-structures/binary-tree/bst.ts +85 -10
- package/src/data-structures/binary-tree/index.ts +3 -3
- package/src/data-structures/binary-tree/red-black-tree.ts +568 -76
- package/src/data-structures/binary-tree/tree-map.ts +439 -0
- package/src/data-structures/binary-tree/tree-multi-map.ts +488 -325
- package/src/data-structures/binary-tree/tree-multi-set.ts +502 -0
- package/src/data-structures/binary-tree/tree-set.ts +407 -0
- package/src/data-structures/queue/deque.ts +10 -0
- package/src/data-structures/trie/trie.ts +6 -8
- package/src/interfaces/binary-tree.ts +2 -2
- package/src/types/data-structures/binary-tree/index.ts +3 -3
- package/src/types/data-structures/binary-tree/tree-map.ts +45 -0
- package/src/types/data-structures/binary-tree/tree-multi-set.ts +19 -0
- package/src/types/data-structures/binary-tree/tree-set.ts +39 -0
- package/dist/types/data-structures/binary-tree/avl-tree-counter.d.ts +0 -236
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +0 -197
- package/dist/types/data-structures/binary-tree/tree-counter.d.ts +0 -243
- package/dist/types/types/data-structures/binary-tree/avl-tree-counter.d.ts +0 -2
- package/dist/types/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +0 -2
- package/dist/types/types/data-structures/binary-tree/tree-counter.d.ts +0 -2
- package/src/data-structures/binary-tree/avl-tree-counter.ts +0 -539
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +0 -438
- package/src/data-structures/binary-tree/tree-counter.ts +0 -575
- package/src/types/data-structures/binary-tree/avl-tree-counter.ts +0 -3
- package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +0 -3
- package/src/types/data-structures/binary-tree/tree-counter.ts +0 -3
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TreeSet (ordered set) — a restricted, native-like API backed by RedBlackTree.
|
|
3
|
+
*
|
|
4
|
+
* Design goals:
|
|
5
|
+
* - No node exposure (no node inputs/outputs)
|
|
6
|
+
* - Native Set-like surface + Java NavigableSet-like helpers
|
|
7
|
+
* - Strict default comparator (number/string/Date), otherwise require comparator
|
|
8
|
+
*/
|
|
9
|
+
import type { Comparator } from '../../types';
|
|
10
|
+
import type { TreeSetElementCallback, TreeSetOptions, TreeSetRangeOptions, TreeSetReduceCallback } from '../../types';
|
|
11
|
+
/**
|
|
12
|
+
* An ordered Set backed by a red-black tree.
|
|
13
|
+
*
|
|
14
|
+
* - Iteration order is ascending by key.
|
|
15
|
+
* - No node exposure: all APIs use keys only.
|
|
16
|
+
*/
|
|
17
|
+
export declare class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
18
|
+
#private;
|
|
19
|
+
/**
|
|
20
|
+
* Create a TreeSet from an iterable of keys or raw elements.
|
|
21
|
+
*
|
|
22
|
+
* @param elements - Iterable of keys, or raw elements if `toElementFn` is provided.
|
|
23
|
+
* @param options - Configuration options including optional `toElementFn` to transform raw elements.
|
|
24
|
+
* @throws {TypeError} When using the default comparator and encountering unsupported key types,
|
|
25
|
+
* or invalid keys (e.g. `NaN`, invalid `Date`).
|
|
26
|
+
* @example
|
|
27
|
+
* // Standard usage with keys
|
|
28
|
+
* const set = new TreeSet([3, 1, 2]);
|
|
29
|
+
*
|
|
30
|
+
* // Using toElementFn to transform raw objects
|
|
31
|
+
* const users = [{ id: 3, name: 'Alice' }, { id: 1, name: 'Bob' }];
|
|
32
|
+
* const set = new TreeSet<number, User>(users, { toElementFn: u => u.id });
|
|
33
|
+
*/
|
|
34
|
+
constructor(elements?: Iterable<R> | Iterable<K>, options?: TreeSetOptions<K, R>);
|
|
35
|
+
/**
|
|
36
|
+
* Create the strict default comparator.
|
|
37
|
+
*
|
|
38
|
+
* Supports:
|
|
39
|
+
* - `number` (rejects `NaN`; treats `-0` and `0` as equal)
|
|
40
|
+
* - `string`
|
|
41
|
+
* - `Date` (orders by `getTime()`, rejects invalid dates)
|
|
42
|
+
*
|
|
43
|
+
* For other key types, a custom comparator must be provided.
|
|
44
|
+
*/
|
|
45
|
+
static createDefaultComparator<K>(): Comparator<K>;
|
|
46
|
+
/**
|
|
47
|
+
* Number of elements in the set.
|
|
48
|
+
*/
|
|
49
|
+
get size(): number;
|
|
50
|
+
/**
|
|
51
|
+
* Whether the set is empty.
|
|
52
|
+
*/
|
|
53
|
+
isEmpty(): boolean;
|
|
54
|
+
private _validateKey;
|
|
55
|
+
/**
|
|
56
|
+
* Add a key to the set (no-op if already present).
|
|
57
|
+
* @remarks Expected time O(log n)
|
|
58
|
+
*/
|
|
59
|
+
add(key: K): this;
|
|
60
|
+
/**
|
|
61
|
+
* Test whether a key exists.
|
|
62
|
+
* @remarks Expected time O(log n)
|
|
63
|
+
*/
|
|
64
|
+
has(key: K): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Delete a key.
|
|
67
|
+
* @returns `true` if the key existed; otherwise `false`.
|
|
68
|
+
* @remarks Expected time O(log n)
|
|
69
|
+
*/
|
|
70
|
+
delete(key: K): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Remove all keys.
|
|
73
|
+
*/
|
|
74
|
+
clear(): void;
|
|
75
|
+
/**
|
|
76
|
+
* Iterate over keys in ascending order.
|
|
77
|
+
*/
|
|
78
|
+
keys(): IterableIterator<K>;
|
|
79
|
+
/**
|
|
80
|
+
* Iterate over values in ascending order.
|
|
81
|
+
*
|
|
82
|
+
* Note: for Set-like containers, `values()` is the same as `keys()`.
|
|
83
|
+
*/
|
|
84
|
+
values(): IterableIterator<K>;
|
|
85
|
+
/**
|
|
86
|
+
* Iterate over `[value, value]` pairs (native Set convention).
|
|
87
|
+
*
|
|
88
|
+
* Note: TreeSet stores only keys internally; `[k, k]` is created on-the-fly during iteration.
|
|
89
|
+
*/
|
|
90
|
+
entries(): IterableIterator<[K, K]>;
|
|
91
|
+
[Symbol.iterator](): IterableIterator<K>;
|
|
92
|
+
/**
|
|
93
|
+
* Visit each value in ascending order.
|
|
94
|
+
*
|
|
95
|
+
* Callback follows native Set convention: `(value, value2, set)`.
|
|
96
|
+
*/
|
|
97
|
+
forEach(cb: (value: K, value2: K, set: TreeSet<K>) => void, thisArg?: any): void;
|
|
98
|
+
/**
|
|
99
|
+
* Create a new TreeSet by mapping each value to a new key.
|
|
100
|
+
*
|
|
101
|
+
* This mirrors `RedBlackTree.map`: mapping produces a new ordered container.
|
|
102
|
+
* @remarks Time O(n log n) expected, Space O(n)
|
|
103
|
+
*/
|
|
104
|
+
map<MK>(callbackfn: TreeSetElementCallback<K, MK, TreeSet<K>>, options?: Omit<TreeSetOptions<MK>, 'toElementFn'> & {
|
|
105
|
+
comparator?: (a: MK, b: MK) => number;
|
|
106
|
+
}, thisArg?: unknown): TreeSet<MK>;
|
|
107
|
+
/**
|
|
108
|
+
* Create a new TreeSet containing only values that satisfy the predicate.
|
|
109
|
+
* @remarks Time O(n log n) expected, Space O(n)
|
|
110
|
+
*/
|
|
111
|
+
filter(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): TreeSet<K>;
|
|
112
|
+
/**
|
|
113
|
+
* Reduce values into a single accumulator.
|
|
114
|
+
* @remarks Time O(n), Space O(1)
|
|
115
|
+
*/
|
|
116
|
+
reduce<A>(callbackfn: TreeSetReduceCallback<K, A, TreeSet<K>>, initialValue: A): A;
|
|
117
|
+
/**
|
|
118
|
+
* Test whether all values satisfy a predicate.
|
|
119
|
+
* @remarks Time O(n), Space O(1)
|
|
120
|
+
*/
|
|
121
|
+
every(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Test whether any value satisfies a predicate.
|
|
124
|
+
* @remarks Time O(n), Space O(1)
|
|
125
|
+
*/
|
|
126
|
+
some(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Find the first value that satisfies a predicate.
|
|
129
|
+
* @remarks Time O(n), Space O(1)
|
|
130
|
+
*/
|
|
131
|
+
find(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): K | undefined;
|
|
132
|
+
/**
|
|
133
|
+
* Materialize the set into an array of keys.
|
|
134
|
+
* @remarks Time O(n), Space O(n)
|
|
135
|
+
*/
|
|
136
|
+
toArray(): K[];
|
|
137
|
+
/**
|
|
138
|
+
* Print a human-friendly representation.
|
|
139
|
+
* @remarks Time O(n), Space O(n)
|
|
140
|
+
*/
|
|
141
|
+
print(): void;
|
|
142
|
+
/**
|
|
143
|
+
* Smallest key in the set.
|
|
144
|
+
*/
|
|
145
|
+
first(): K | undefined;
|
|
146
|
+
/**
|
|
147
|
+
* Largest key in the set.
|
|
148
|
+
*/
|
|
149
|
+
last(): K | undefined;
|
|
150
|
+
/**
|
|
151
|
+
* Remove and return the smallest key.
|
|
152
|
+
*/
|
|
153
|
+
pollFirst(): K | undefined;
|
|
154
|
+
/**
|
|
155
|
+
* Remove and return the largest key.
|
|
156
|
+
*/
|
|
157
|
+
pollLast(): K | undefined;
|
|
158
|
+
/**
|
|
159
|
+
* Smallest key that is >= the given key.
|
|
160
|
+
*/
|
|
161
|
+
ceiling(key: K): K | undefined;
|
|
162
|
+
/**
|
|
163
|
+
* Largest key that is <= the given key.
|
|
164
|
+
*/
|
|
165
|
+
floor(key: K): K | undefined;
|
|
166
|
+
/**
|
|
167
|
+
* Smallest key that is > the given key.
|
|
168
|
+
*/
|
|
169
|
+
higher(key: K): K | undefined;
|
|
170
|
+
/**
|
|
171
|
+
* Largest key that is < the given key.
|
|
172
|
+
*/
|
|
173
|
+
lower(key: K): K | undefined;
|
|
174
|
+
/**
|
|
175
|
+
* Return all keys in a given range.
|
|
176
|
+
*
|
|
177
|
+
* @param range `[low, high]`
|
|
178
|
+
* @param options Inclusive/exclusive bounds (defaults to inclusive).
|
|
179
|
+
*/
|
|
180
|
+
rangeSearch(range: [K, K], options?: TreeSetRangeOptions): K[];
|
|
181
|
+
}
|
|
@@ -11,7 +11,7 @@ export interface IBinaryTree<K = any, V = any, R = any> {
|
|
|
11
11
|
readonly isMapMode: boolean;
|
|
12
12
|
iterationType: IterationType;
|
|
13
13
|
readonly NIL: BinaryTreeNode<K, V>;
|
|
14
|
-
readonly store: Map<K, V
|
|
14
|
+
readonly store: Map<K, BinaryTreeNode<K, V>>;
|
|
15
15
|
readonly toEntryFn?: ToEntryFn<K, V, R>;
|
|
16
16
|
readonly isDuplicate: boolean;
|
|
17
17
|
createNode(key: K, value?: BinaryTreeNode<K, V>['value']): BinaryTreeNode<K, V>;
|
|
@@ -19,7 +19,7 @@ export interface IBinaryTree<K = any, V = any, R = any> {
|
|
|
19
19
|
add(keyOrNodeOrEntryOrRawElement: BTNRep<K, V, BinaryTreeNode<K, V>>, value?: V, count?: number): boolean;
|
|
20
20
|
set(keyOrNodeOrEntryOrRawElement: BTNRep<K, V, BinaryTreeNode<K, V>>, value?: V, count?: number): boolean;
|
|
21
21
|
addMany(keysNodesEntriesOrRaws: Iterable<K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | R>, values?: Iterable<V | undefined>): boolean[];
|
|
22
|
-
delete(keyNodeEntryRawOrPredicate:
|
|
22
|
+
delete(keyNodeEntryRawOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V> | null>): BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[];
|
|
23
23
|
clear(): void;
|
|
24
24
|
isEmpty(): boolean;
|
|
25
25
|
get(keyNodeEntryOrPredicate: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): V | undefined;
|
|
@@ -2,8 +2,8 @@ export * from './binary-tree';
|
|
|
2
2
|
export * from './bst';
|
|
3
3
|
export * from './avl-tree';
|
|
4
4
|
export * from './segment-tree';
|
|
5
|
-
export * from './avl-tree-multi-map';
|
|
6
5
|
export * from './red-black-tree';
|
|
7
6
|
export * from './tree-multi-map';
|
|
8
|
-
export * from './tree-
|
|
9
|
-
export * from './
|
|
7
|
+
export * from './tree-set';
|
|
8
|
+
export * from './tree-map';
|
|
9
|
+
export * from './tree-multi-set';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Comparator } from '../../common';
|
|
2
|
+
export interface TreeMapOptions<K, V, R = [K, V]> {
|
|
3
|
+
comparator?: Comparator<K>;
|
|
4
|
+
/**
|
|
5
|
+
* Pass-through to the underlying RedBlackTree/BST `isMapMode` option.
|
|
6
|
+
*
|
|
7
|
+
* - `true` (default in core): store values in an internal key→value store.
|
|
8
|
+
* - `false`: store values on tree nodes (Node Mode).
|
|
9
|
+
*/
|
|
10
|
+
isMapMode?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Transform raw elements into `[key, value]` entries.
|
|
13
|
+
* When provided, the constructor accepts `Iterable<R>` instead of `Iterable<[K, V]>`.
|
|
14
|
+
*/
|
|
15
|
+
toEntryFn?: (rawElement: R) => [K, V];
|
|
16
|
+
}
|
|
17
|
+
export type TreeMapRangeOptions = {
|
|
18
|
+
lowInclusive?: boolean;
|
|
19
|
+
highInclusive?: boolean;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Callback used by TreeMap entry-wise utilities.
|
|
23
|
+
*
|
|
24
|
+
* `SELF` is intentionally generic to avoid type-layer circular imports.
|
|
25
|
+
* Implementations (e.g. `TreeMap<K, V>`) should bind `SELF` at use sites.
|
|
26
|
+
*/
|
|
27
|
+
export type TreeMapEntryCallback<K, V, R, SELF> = (value: V | undefined, key: K, index: number, map: SELF) => R;
|
|
28
|
+
/**
|
|
29
|
+
* Reducer callback used by TreeMap.
|
|
30
|
+
*
|
|
31
|
+
* `SELF` is intentionally generic to avoid type-layer circular imports.
|
|
32
|
+
*/
|
|
33
|
+
export type TreeMapReduceCallback<K, V, A, SELF> = (acc: A, value: V | undefined, key: K, index: number, map: SELF) => A;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Comparator } from '../../common';
|
|
2
|
+
export interface TreeMultiSetOptions<K, R = K> {
|
|
3
|
+
comparator?: Comparator<K>;
|
|
4
|
+
/**
|
|
5
|
+
* Pass-through to the underlying RedBlackTree/BST `isMapMode` option.
|
|
6
|
+
*
|
|
7
|
+
* - `true` (recommended): MapMode store uses key→node index for fast lookups.
|
|
8
|
+
* - `false`: Node Mode.
|
|
9
|
+
*/
|
|
10
|
+
isMapMode?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Transform raw elements into keys.
|
|
13
|
+
* When provided, the constructor accepts `Iterable<R>` instead of `Iterable<K>`.
|
|
14
|
+
*/
|
|
15
|
+
toElementFn?: (rawElement: R) => K;
|
|
16
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Comparator } from '../../common';
|
|
2
|
+
export interface TreeSetOptions<K, R = K> {
|
|
3
|
+
comparator?: Comparator<K>;
|
|
4
|
+
/**
|
|
5
|
+
* Pass-through to the underlying RedBlackTree/BST `isMapMode` option.
|
|
6
|
+
*
|
|
7
|
+
* - `true` (default in core): store values in an internal key→value store.
|
|
8
|
+
* - `false`: store values on tree nodes (Node Mode).
|
|
9
|
+
*/
|
|
10
|
+
isMapMode?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Transform raw elements into keys.
|
|
13
|
+
* When provided, the constructor accepts `Iterable<R>` instead of `Iterable<K>`.
|
|
14
|
+
*/
|
|
15
|
+
toElementFn?: (rawElement: R) => K;
|
|
16
|
+
}
|
|
17
|
+
export type TreeSetRangeOptions = {
|
|
18
|
+
lowInclusive?: boolean;
|
|
19
|
+
highInclusive?: boolean;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Callback used by TreeSet element-wise utilities.
|
|
23
|
+
*
|
|
24
|
+
* `SELF` is intentionally generic to avoid type-layer circular imports.
|
|
25
|
+
* Implementations (e.g. `TreeSet<K>`) should bind `SELF` at use sites.
|
|
26
|
+
*/
|
|
27
|
+
export type TreeSetElementCallback<K, R, SELF> = (value: K, index: number, set: SELF) => R;
|
|
28
|
+
/**
|
|
29
|
+
* Reducer callback used by TreeSet.
|
|
30
|
+
*
|
|
31
|
+
* `SELF` is intentionally generic to avoid type-layer circular imports.
|
|
32
|
+
*/
|
|
33
|
+
export type TreeSetReduceCallback<K, A, SELF> = (acc: A, value: K, index: number, set: SELF) => A;
|
package/dist/umd/bst-typed.js
CHANGED
|
@@ -1207,6 +1207,9 @@ var bstTyped = (() => {
|
|
|
1207
1207
|
__publicField(this, "iterationType", "ITERATIVE");
|
|
1208
1208
|
__publicField(this, "_isMapMode", true);
|
|
1209
1209
|
__publicField(this, "_isDuplicate", false);
|
|
1210
|
+
// Map mode acceleration store:
|
|
1211
|
+
// - isMapMode=false: unused
|
|
1212
|
+
// - isMapMode=true: key -> node reference (O(1) has/getNode + fast get)
|
|
1210
1213
|
__publicField(this, "_store", /* @__PURE__ */ new Map());
|
|
1211
1214
|
__publicField(this, "_root");
|
|
1212
1215
|
__publicField(this, "_size", 0);
|
|
@@ -1302,7 +1305,7 @@ var bstTyped = (() => {
|
|
|
1302
1305
|
* @returns The newly created node.
|
|
1303
1306
|
*/
|
|
1304
1307
|
createNode(key, value) {
|
|
1305
|
-
return new BinaryTreeNode(key,
|
|
1308
|
+
return new BinaryTreeNode(key, value);
|
|
1306
1309
|
}
|
|
1307
1310
|
/**
|
|
1308
1311
|
* Creates a new, empty tree of the same type and configuration.
|
|
@@ -1449,11 +1452,11 @@ var bstTyped = (() => {
|
|
|
1449
1452
|
* @returns True if the addition was successful, false otherwise.
|
|
1450
1453
|
*/
|
|
1451
1454
|
set(keyNodeOrEntry, value) {
|
|
1452
|
-
const [newNode
|
|
1455
|
+
const [newNode] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
|
|
1453
1456
|
if (newNode === void 0) return false;
|
|
1454
1457
|
if (!this._root) {
|
|
1455
1458
|
this._setRoot(newNode);
|
|
1456
|
-
if (this._isMapMode
|
|
1459
|
+
if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
|
|
1457
1460
|
this._size = 1;
|
|
1458
1461
|
return true;
|
|
1459
1462
|
}
|
|
@@ -1465,7 +1468,7 @@ var bstTyped = (() => {
|
|
|
1465
1468
|
if (!this._isDuplicate) {
|
|
1466
1469
|
if (newNode !== null && cur.key === newNode.key) {
|
|
1467
1470
|
this._replaceNode(cur, newNode);
|
|
1468
|
-
if (this._isMapMode) this.
|
|
1471
|
+
if (this._isMapMode && newNode !== null) this._store.set(cur.key, newNode);
|
|
1469
1472
|
return true;
|
|
1470
1473
|
}
|
|
1471
1474
|
}
|
|
@@ -1485,7 +1488,7 @@ var bstTyped = (() => {
|
|
|
1485
1488
|
} else if (potentialParent.right === void 0) {
|
|
1486
1489
|
potentialParent.right = newNode;
|
|
1487
1490
|
}
|
|
1488
|
-
if (this._isMapMode
|
|
1491
|
+
if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
|
|
1489
1492
|
this._size++;
|
|
1490
1493
|
return true;
|
|
1491
1494
|
}
|
|
@@ -1552,13 +1555,13 @@ var bstTyped = (() => {
|
|
|
1552
1555
|
* Deletes a node from the tree.
|
|
1553
1556
|
* @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation finds the node, and if it has two children, swaps it with the rightmost node of its left subtree (in-order predecessor) before deleting. Time O(N) in the worst case. O(N) to find the node (`getNode`) and O(H) (which is O(N) worst-case) to find the rightmost node. Space O(1) (if `getNode` is iterative, which it is).
|
|
1554
1557
|
*
|
|
1555
|
-
* @param
|
|
1558
|
+
* @param keyNodeEntryRawOrPredicate - The node to delete.
|
|
1556
1559
|
* @returns An array containing deletion results (for compatibility with self-balancing trees).
|
|
1557
1560
|
*/
|
|
1558
|
-
delete(
|
|
1561
|
+
delete(keyNodeEntryRawOrPredicate) {
|
|
1559
1562
|
const deletedResult = [];
|
|
1560
1563
|
if (!this._root) return deletedResult;
|
|
1561
|
-
const curr = this.getNode(
|
|
1564
|
+
const curr = this.getNode(keyNodeEntryRawOrPredicate);
|
|
1562
1565
|
if (!curr) return deletedResult;
|
|
1563
1566
|
const parent = curr == null ? void 0 : curr.parent;
|
|
1564
1567
|
let needBalanced;
|
|
@@ -1570,6 +1573,10 @@ var bstTyped = (() => {
|
|
|
1570
1573
|
if (leftSubTreeRightMost) {
|
|
1571
1574
|
const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
|
|
1572
1575
|
orgCurrent = this._swapProperties(curr, leftSubTreeRightMost);
|
|
1576
|
+
if (this._isMapMode) {
|
|
1577
|
+
this._store.set(curr.key, curr);
|
|
1578
|
+
this._store.set(leftSubTreeRightMost.key, leftSubTreeRightMost);
|
|
1579
|
+
}
|
|
1573
1580
|
if (parentOfLeftSubTreeMax) {
|
|
1574
1581
|
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
|
|
1575
1582
|
parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
|
|
@@ -1653,6 +1660,13 @@ var bstTyped = (() => {
|
|
|
1653
1660
|
* @returns The first matching node, or undefined if not found.
|
|
1654
1661
|
*/
|
|
1655
1662
|
getNode(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
1663
|
+
if (this._isMapMode && keyNodeEntryOrPredicate !== null && keyNodeEntryOrPredicate !== void 0) {
|
|
1664
|
+
if (!this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
1665
|
+
const key = this._extractKey(keyNodeEntryOrPredicate);
|
|
1666
|
+
if (key === null || key === void 0) return;
|
|
1667
|
+
return this._store.get(key);
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1656
1670
|
return this.search(keyNodeEntryOrPredicate, true, (node) => node, startNode, iterationType)[0];
|
|
1657
1671
|
}
|
|
1658
1672
|
/**
|
|
@@ -1665,15 +1679,22 @@ var bstTyped = (() => {
|
|
|
1665
1679
|
* @returns The associated value, or undefined.
|
|
1666
1680
|
*/
|
|
1667
1681
|
get(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
1668
|
-
var _a;
|
|
1682
|
+
var _a, _b;
|
|
1669
1683
|
if (this._isMapMode) {
|
|
1670
1684
|
const key = this._extractKey(keyNodeEntryOrPredicate);
|
|
1671
1685
|
if (key === null || key === void 0) return;
|
|
1672
|
-
return this._store.get(key);
|
|
1686
|
+
return (_a = this._store.get(key)) == null ? void 0 : _a.value;
|
|
1673
1687
|
}
|
|
1674
|
-
return (
|
|
1688
|
+
return (_b = this.getNode(keyNodeEntryOrPredicate, startNode, iterationType)) == null ? void 0 : _b.value;
|
|
1675
1689
|
}
|
|
1676
1690
|
has(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
1691
|
+
if (this._isMapMode && keyNodeEntryOrPredicate !== void 0 && keyNodeEntryOrPredicate !== null) {
|
|
1692
|
+
if (!this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
1693
|
+
const key = this._extractKey(keyNodeEntryOrPredicate);
|
|
1694
|
+
if (key === null || key === void 0) return false;
|
|
1695
|
+
return this._store.has(key);
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1677
1698
|
return this.search(keyNodeEntryOrPredicate, true, (node) => node, startNode, iterationType).length > 0;
|
|
1678
1699
|
}
|
|
1679
1700
|
/**
|
|
@@ -1742,7 +1763,7 @@ var bstTyped = (() => {
|
|
|
1742
1763
|
}
|
|
1743
1764
|
return true;
|
|
1744
1765
|
};
|
|
1745
|
-
const isStandardBST = checkBST(
|
|
1766
|
+
const isStandardBST = checkBST();
|
|
1746
1767
|
const isInverseBST = checkBST(true);
|
|
1747
1768
|
return isStandardBST || isInverseBST;
|
|
1748
1769
|
}
|
|
@@ -2418,8 +2439,7 @@ var bstTyped = (() => {
|
|
|
2418
2439
|
}
|
|
2419
2440
|
current = stack.pop();
|
|
2420
2441
|
if (this.isRealNode(current)) {
|
|
2421
|
-
|
|
2422
|
-
else yield [current.key, current.value];
|
|
2442
|
+
yield [current.key, current.value];
|
|
2423
2443
|
current = current.right;
|
|
2424
2444
|
}
|
|
2425
2445
|
}
|
|
@@ -2427,8 +2447,7 @@ var bstTyped = (() => {
|
|
|
2427
2447
|
if (node.left && this.isRealNode(node)) {
|
|
2428
2448
|
yield* this[Symbol.iterator](node.left);
|
|
2429
2449
|
}
|
|
2430
|
-
|
|
2431
|
-
else yield [node.key, node.value];
|
|
2450
|
+
yield [node.key, node.value];
|
|
2432
2451
|
if (node.right && this.isRealNode(node)) {
|
|
2433
2452
|
yield* this[Symbol.iterator](node.right);
|
|
2434
2453
|
}
|
|
@@ -2506,8 +2525,7 @@ var bstTyped = (() => {
|
|
|
2506
2525
|
(node) => {
|
|
2507
2526
|
if (node === null) cloned.set(null);
|
|
2508
2527
|
else {
|
|
2509
|
-
|
|
2510
|
-
else cloned.set([node.key, node.value]);
|
|
2528
|
+
cloned.set([node.key, node.value]);
|
|
2511
2529
|
}
|
|
2512
2530
|
},
|
|
2513
2531
|
this._root,
|
|
@@ -2515,7 +2533,6 @@ var bstTyped = (() => {
|
|
|
2515
2533
|
true
|
|
2516
2534
|
// Include nulls
|
|
2517
2535
|
);
|
|
2518
|
-
if (this._isMapMode) cloned._store = this._store;
|
|
2519
2536
|
}
|
|
2520
2537
|
/**
|
|
2521
2538
|
* (Protected) Recursive helper for `toVisual`.
|
|
@@ -2678,8 +2695,10 @@ var bstTyped = (() => {
|
|
|
2678
2695
|
*/
|
|
2679
2696
|
_setValue(key, value) {
|
|
2680
2697
|
if (key === null || key === void 0) return false;
|
|
2681
|
-
|
|
2682
|
-
|
|
2698
|
+
const node = this._store.get(key);
|
|
2699
|
+
if (!node) return false;
|
|
2700
|
+
node.value = value;
|
|
2701
|
+
return true;
|
|
2683
2702
|
}
|
|
2684
2703
|
/**
|
|
2685
2704
|
* (Protected) Clears all nodes from the tree.
|
|
@@ -2884,7 +2903,7 @@ var bstTyped = (() => {
|
|
|
2884
2903
|
* @returns The newly created BSTNode.
|
|
2885
2904
|
*/
|
|
2886
2905
|
createNode(key, value) {
|
|
2887
|
-
return new BSTNode(key,
|
|
2906
|
+
return new BSTNode(key, value);
|
|
2888
2907
|
}
|
|
2889
2908
|
/**
|
|
2890
2909
|
* Ensures the input is a node. If it's a key or entry, it searches for the node.
|
|
@@ -2969,8 +2988,40 @@ var bstTyped = (() => {
|
|
|
2969
2988
|
* @returns The first matching node, or undefined if not found.
|
|
2970
2989
|
*/
|
|
2971
2990
|
getNode(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
2972
|
-
var _a;
|
|
2973
|
-
|
|
2991
|
+
var _a, _b;
|
|
2992
|
+
if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === void 0) return void 0;
|
|
2993
|
+
if (this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
2994
|
+
return (_a = this.getNodes(keyNodeEntryOrPredicate, true, startNode, iterationType)[0]) != null ? _a : void 0;
|
|
2995
|
+
}
|
|
2996
|
+
if (keyNodeEntryOrPredicate instanceof Range) {
|
|
2997
|
+
return (_b = this.getNodes(
|
|
2998
|
+
keyNodeEntryOrPredicate,
|
|
2999
|
+
true,
|
|
3000
|
+
startNode,
|
|
3001
|
+
iterationType
|
|
3002
|
+
)[0]) != null ? _b : void 0;
|
|
3003
|
+
}
|
|
3004
|
+
let targetKey;
|
|
3005
|
+
if (this.isNode(keyNodeEntryOrPredicate)) {
|
|
3006
|
+
targetKey = keyNodeEntryOrPredicate.key;
|
|
3007
|
+
} else if (this.isEntry(keyNodeEntryOrPredicate)) {
|
|
3008
|
+
const k = keyNodeEntryOrPredicate[0];
|
|
3009
|
+
if (k === null || k === void 0) return void 0;
|
|
3010
|
+
targetKey = k;
|
|
3011
|
+
} else {
|
|
3012
|
+
targetKey = keyNodeEntryOrPredicate;
|
|
3013
|
+
}
|
|
3014
|
+
const start = this.ensureNode(startNode);
|
|
3015
|
+
if (!start) return void 0;
|
|
3016
|
+
const NIL = this._NIL;
|
|
3017
|
+
let cur = start;
|
|
3018
|
+
const cmpFn = this._comparator;
|
|
3019
|
+
while (cur && cur !== NIL) {
|
|
3020
|
+
const c = cmpFn(targetKey, cur.key);
|
|
3021
|
+
if (c === 0) return cur;
|
|
3022
|
+
cur = c < 0 ? cur._left : cur._right;
|
|
3023
|
+
}
|
|
3024
|
+
return void 0;
|
|
2974
3025
|
}
|
|
2975
3026
|
/**
|
|
2976
3027
|
* Searches the tree for nodes matching a predicate, key, or range.
|
|
@@ -2991,8 +3042,30 @@ var bstTyped = (() => {
|
|
|
2991
3042
|
if (keyNodeEntryOrPredicate === null) return [];
|
|
2992
3043
|
startNode = this.ensureNode(startNode);
|
|
2993
3044
|
if (!startNode) return [];
|
|
2994
|
-
let predicate;
|
|
2995
3045
|
const isRange = this.isRange(keyNodeEntryOrPredicate);
|
|
3046
|
+
const isPred = !isRange && this._isPredicate(keyNodeEntryOrPredicate);
|
|
3047
|
+
if (!isRange && !isPred) {
|
|
3048
|
+
let targetKey;
|
|
3049
|
+
if (this.isNode(keyNodeEntryOrPredicate)) {
|
|
3050
|
+
targetKey = keyNodeEntryOrPredicate.key;
|
|
3051
|
+
} else if (this.isEntry(keyNodeEntryOrPredicate)) {
|
|
3052
|
+
const k = keyNodeEntryOrPredicate[0];
|
|
3053
|
+
if (k !== null && k !== void 0) targetKey = k;
|
|
3054
|
+
} else {
|
|
3055
|
+
targetKey = keyNodeEntryOrPredicate;
|
|
3056
|
+
}
|
|
3057
|
+
if (targetKey === void 0) return [];
|
|
3058
|
+
const NIL = this._NIL;
|
|
3059
|
+
const cmpFn = this._comparator;
|
|
3060
|
+
let cur = startNode;
|
|
3061
|
+
while (cur && cur !== NIL) {
|
|
3062
|
+
const c = cmpFn(targetKey, cur.key);
|
|
3063
|
+
if (c === 0) return [callback(cur)];
|
|
3064
|
+
cur = c < 0 ? cur._left : cur._right;
|
|
3065
|
+
}
|
|
3066
|
+
return [];
|
|
3067
|
+
}
|
|
3068
|
+
let predicate;
|
|
2996
3069
|
if (isRange) {
|
|
2997
3070
|
predicate = (node) => {
|
|
2998
3071
|
if (!node) return false;
|
|
@@ -3071,11 +3144,11 @@ var bstTyped = (() => {
|
|
|
3071
3144
|
* @returns True if the addition was successful, false otherwise.
|
|
3072
3145
|
*/
|
|
3073
3146
|
set(keyNodeOrEntry, value) {
|
|
3074
|
-
const [newNode
|
|
3147
|
+
const [newNode] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
|
|
3075
3148
|
if (newNode === void 0) return false;
|
|
3076
3149
|
if (this._root === void 0) {
|
|
3077
3150
|
this._setRoot(newNode);
|
|
3078
|
-
if (this._isMapMode
|
|
3151
|
+
if (this._isMapMode && this.isRealNode(newNode)) this._store.set(newNode.key, newNode);
|
|
3079
3152
|
this._size++;
|
|
3080
3153
|
return true;
|
|
3081
3154
|
}
|
|
@@ -3083,12 +3156,12 @@ var bstTyped = (() => {
|
|
|
3083
3156
|
while (current !== void 0) {
|
|
3084
3157
|
if (this._compare(current.key, newNode.key) === 0) {
|
|
3085
3158
|
this._replaceNode(current, newNode);
|
|
3086
|
-
if (this._isMapMode) this.
|
|
3159
|
+
if (this._isMapMode && this.isRealNode(newNode)) this._store.set(current.key, newNode);
|
|
3087
3160
|
return true;
|
|
3088
3161
|
} else if (this._compare(current.key, newNode.key) > 0) {
|
|
3089
3162
|
if (current.left === void 0) {
|
|
3090
3163
|
current.left = newNode;
|
|
3091
|
-
if (this._isMapMode
|
|
3164
|
+
if (this._isMapMode && this.isRealNode(newNode)) this._store.set(newNode.key, newNode);
|
|
3092
3165
|
this._size++;
|
|
3093
3166
|
return true;
|
|
3094
3167
|
}
|
|
@@ -3096,7 +3169,7 @@ var bstTyped = (() => {
|
|
|
3096
3169
|
} else {
|
|
3097
3170
|
if (current.right === void 0) {
|
|
3098
3171
|
current.right = newNode;
|
|
3099
|
-
if (this._isMapMode
|
|
3172
|
+
if (this._isMapMode && this.isRealNode(newNode)) this._store.set(newNode.key, newNode);
|
|
3100
3173
|
this._size++;
|
|
3101
3174
|
return true;
|
|
3102
3175
|
}
|
|
@@ -3879,7 +3952,6 @@ var bstTyped = (() => {
|
|
|
3879
3952
|
* @returns True if the node was found and deleted, false otherwise.
|
|
3880
3953
|
*/
|
|
3881
3954
|
_deleteByKey(key) {
|
|
3882
|
-
var _a;
|
|
3883
3955
|
let node = this._root;
|
|
3884
3956
|
while (node) {
|
|
3885
3957
|
const cmp = this._compare(node.key, key);
|
|
@@ -3918,7 +3990,7 @@ var bstTyped = (() => {
|
|
|
3918
3990
|
succ.left = node.left;
|
|
3919
3991
|
if (succ.left) succ.left.parent = succ;
|
|
3920
3992
|
}
|
|
3921
|
-
this._size = Math.max(0,
|
|
3993
|
+
this._size = Math.max(0, this._size - 1);
|
|
3922
3994
|
return true;
|
|
3923
3995
|
}
|
|
3924
3996
|
};
|