avl-tree-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 +102 -29
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +105 -33
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +102 -29
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +105 -33
- 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/avl-tree-typed.js +105 -33
- package/dist/umd/avl-tree-typed.js.map +1 -1
- package/dist/umd/avl-tree-typed.min.js +2 -2
- package/dist/umd/avl-tree-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;
|
|
@@ -1202,6 +1202,9 @@ var avlTreeTyped = (() => {
|
|
|
1202
1202
|
__publicField(this, "iterationType", "ITERATIVE");
|
|
1203
1203
|
__publicField(this, "_isMapMode", true);
|
|
1204
1204
|
__publicField(this, "_isDuplicate", false);
|
|
1205
|
+
// Map mode acceleration store:
|
|
1206
|
+
// - isMapMode=false: unused
|
|
1207
|
+
// - isMapMode=true: key -> node reference (O(1) has/getNode + fast get)
|
|
1205
1208
|
__publicField(this, "_store", /* @__PURE__ */ new Map());
|
|
1206
1209
|
__publicField(this, "_root");
|
|
1207
1210
|
__publicField(this, "_size", 0);
|
|
@@ -1297,7 +1300,7 @@ var avlTreeTyped = (() => {
|
|
|
1297
1300
|
* @returns The newly created node.
|
|
1298
1301
|
*/
|
|
1299
1302
|
createNode(key, value) {
|
|
1300
|
-
return new BinaryTreeNode(key,
|
|
1303
|
+
return new BinaryTreeNode(key, value);
|
|
1301
1304
|
}
|
|
1302
1305
|
/**
|
|
1303
1306
|
* Creates a new, empty tree of the same type and configuration.
|
|
@@ -1444,11 +1447,11 @@ var avlTreeTyped = (() => {
|
|
|
1444
1447
|
* @returns True if the addition was successful, false otherwise.
|
|
1445
1448
|
*/
|
|
1446
1449
|
set(keyNodeOrEntry, value) {
|
|
1447
|
-
const [newNode
|
|
1450
|
+
const [newNode] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
|
|
1448
1451
|
if (newNode === void 0) return false;
|
|
1449
1452
|
if (!this._root) {
|
|
1450
1453
|
this._setRoot(newNode);
|
|
1451
|
-
if (this._isMapMode
|
|
1454
|
+
if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
|
|
1452
1455
|
this._size = 1;
|
|
1453
1456
|
return true;
|
|
1454
1457
|
}
|
|
@@ -1460,7 +1463,7 @@ var avlTreeTyped = (() => {
|
|
|
1460
1463
|
if (!this._isDuplicate) {
|
|
1461
1464
|
if (newNode !== null && cur.key === newNode.key) {
|
|
1462
1465
|
this._replaceNode(cur, newNode);
|
|
1463
|
-
if (this._isMapMode) this.
|
|
1466
|
+
if (this._isMapMode && newNode !== null) this._store.set(cur.key, newNode);
|
|
1464
1467
|
return true;
|
|
1465
1468
|
}
|
|
1466
1469
|
}
|
|
@@ -1480,7 +1483,7 @@ var avlTreeTyped = (() => {
|
|
|
1480
1483
|
} else if (potentialParent.right === void 0) {
|
|
1481
1484
|
potentialParent.right = newNode;
|
|
1482
1485
|
}
|
|
1483
|
-
if (this._isMapMode
|
|
1486
|
+
if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
|
|
1484
1487
|
this._size++;
|
|
1485
1488
|
return true;
|
|
1486
1489
|
}
|
|
@@ -1547,13 +1550,13 @@ var avlTreeTyped = (() => {
|
|
|
1547
1550
|
* Deletes a node from the tree.
|
|
1548
1551
|
* @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).
|
|
1549
1552
|
*
|
|
1550
|
-
* @param
|
|
1553
|
+
* @param keyNodeEntryRawOrPredicate - The node to delete.
|
|
1551
1554
|
* @returns An array containing deletion results (for compatibility with self-balancing trees).
|
|
1552
1555
|
*/
|
|
1553
|
-
delete(
|
|
1556
|
+
delete(keyNodeEntryRawOrPredicate) {
|
|
1554
1557
|
const deletedResult = [];
|
|
1555
1558
|
if (!this._root) return deletedResult;
|
|
1556
|
-
const curr = this.getNode(
|
|
1559
|
+
const curr = this.getNode(keyNodeEntryRawOrPredicate);
|
|
1557
1560
|
if (!curr) return deletedResult;
|
|
1558
1561
|
const parent = curr == null ? void 0 : curr.parent;
|
|
1559
1562
|
let needBalanced;
|
|
@@ -1565,6 +1568,10 @@ var avlTreeTyped = (() => {
|
|
|
1565
1568
|
if (leftSubTreeRightMost) {
|
|
1566
1569
|
const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
|
|
1567
1570
|
orgCurrent = this._swapProperties(curr, leftSubTreeRightMost);
|
|
1571
|
+
if (this._isMapMode) {
|
|
1572
|
+
this._store.set(curr.key, curr);
|
|
1573
|
+
this._store.set(leftSubTreeRightMost.key, leftSubTreeRightMost);
|
|
1574
|
+
}
|
|
1568
1575
|
if (parentOfLeftSubTreeMax) {
|
|
1569
1576
|
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
|
|
1570
1577
|
parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
|
|
@@ -1648,6 +1655,13 @@ var avlTreeTyped = (() => {
|
|
|
1648
1655
|
* @returns The first matching node, or undefined if not found.
|
|
1649
1656
|
*/
|
|
1650
1657
|
getNode(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
1658
|
+
if (this._isMapMode && keyNodeEntryOrPredicate !== null && keyNodeEntryOrPredicate !== void 0) {
|
|
1659
|
+
if (!this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
1660
|
+
const key = this._extractKey(keyNodeEntryOrPredicate);
|
|
1661
|
+
if (key === null || key === void 0) return;
|
|
1662
|
+
return this._store.get(key);
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1651
1665
|
return this.search(keyNodeEntryOrPredicate, true, (node) => node, startNode, iterationType)[0];
|
|
1652
1666
|
}
|
|
1653
1667
|
/**
|
|
@@ -1660,15 +1674,22 @@ var avlTreeTyped = (() => {
|
|
|
1660
1674
|
* @returns The associated value, or undefined.
|
|
1661
1675
|
*/
|
|
1662
1676
|
get(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
1663
|
-
var _a;
|
|
1677
|
+
var _a, _b;
|
|
1664
1678
|
if (this._isMapMode) {
|
|
1665
1679
|
const key = this._extractKey(keyNodeEntryOrPredicate);
|
|
1666
1680
|
if (key === null || key === void 0) return;
|
|
1667
|
-
return this._store.get(key);
|
|
1681
|
+
return (_a = this._store.get(key)) == null ? void 0 : _a.value;
|
|
1668
1682
|
}
|
|
1669
|
-
return (
|
|
1683
|
+
return (_b = this.getNode(keyNodeEntryOrPredicate, startNode, iterationType)) == null ? void 0 : _b.value;
|
|
1670
1684
|
}
|
|
1671
1685
|
has(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
1686
|
+
if (this._isMapMode && keyNodeEntryOrPredicate !== void 0 && keyNodeEntryOrPredicate !== null) {
|
|
1687
|
+
if (!this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
1688
|
+
const key = this._extractKey(keyNodeEntryOrPredicate);
|
|
1689
|
+
if (key === null || key === void 0) return false;
|
|
1690
|
+
return this._store.has(key);
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1672
1693
|
return this.search(keyNodeEntryOrPredicate, true, (node) => node, startNode, iterationType).length > 0;
|
|
1673
1694
|
}
|
|
1674
1695
|
/**
|
|
@@ -1737,7 +1758,7 @@ var avlTreeTyped = (() => {
|
|
|
1737
1758
|
}
|
|
1738
1759
|
return true;
|
|
1739
1760
|
};
|
|
1740
|
-
const isStandardBST = checkBST(
|
|
1761
|
+
const isStandardBST = checkBST();
|
|
1741
1762
|
const isInverseBST = checkBST(true);
|
|
1742
1763
|
return isStandardBST || isInverseBST;
|
|
1743
1764
|
}
|
|
@@ -2413,8 +2434,7 @@ var avlTreeTyped = (() => {
|
|
|
2413
2434
|
}
|
|
2414
2435
|
current = stack.pop();
|
|
2415
2436
|
if (this.isRealNode(current)) {
|
|
2416
|
-
|
|
2417
|
-
else yield [current.key, current.value];
|
|
2437
|
+
yield [current.key, current.value];
|
|
2418
2438
|
current = current.right;
|
|
2419
2439
|
}
|
|
2420
2440
|
}
|
|
@@ -2422,8 +2442,7 @@ var avlTreeTyped = (() => {
|
|
|
2422
2442
|
if (node.left && this.isRealNode(node)) {
|
|
2423
2443
|
yield* this[Symbol.iterator](node.left);
|
|
2424
2444
|
}
|
|
2425
|
-
|
|
2426
|
-
else yield [node.key, node.value];
|
|
2445
|
+
yield [node.key, node.value];
|
|
2427
2446
|
if (node.right && this.isRealNode(node)) {
|
|
2428
2447
|
yield* this[Symbol.iterator](node.right);
|
|
2429
2448
|
}
|
|
@@ -2501,8 +2520,7 @@ var avlTreeTyped = (() => {
|
|
|
2501
2520
|
(node) => {
|
|
2502
2521
|
if (node === null) cloned.set(null);
|
|
2503
2522
|
else {
|
|
2504
|
-
|
|
2505
|
-
else cloned.set([node.key, node.value]);
|
|
2523
|
+
cloned.set([node.key, node.value]);
|
|
2506
2524
|
}
|
|
2507
2525
|
},
|
|
2508
2526
|
this._root,
|
|
@@ -2510,7 +2528,6 @@ var avlTreeTyped = (() => {
|
|
|
2510
2528
|
true
|
|
2511
2529
|
// Include nulls
|
|
2512
2530
|
);
|
|
2513
|
-
if (this._isMapMode) cloned._store = this._store;
|
|
2514
2531
|
}
|
|
2515
2532
|
/**
|
|
2516
2533
|
* (Protected) Recursive helper for `toVisual`.
|
|
@@ -2673,8 +2690,10 @@ var avlTreeTyped = (() => {
|
|
|
2673
2690
|
*/
|
|
2674
2691
|
_setValue(key, value) {
|
|
2675
2692
|
if (key === null || key === void 0) return false;
|
|
2676
|
-
|
|
2677
|
-
|
|
2693
|
+
const node = this._store.get(key);
|
|
2694
|
+
if (!node) return false;
|
|
2695
|
+
node.value = value;
|
|
2696
|
+
return true;
|
|
2678
2697
|
}
|
|
2679
2698
|
/**
|
|
2680
2699
|
* (Protected) Clears all nodes from the tree.
|
|
@@ -2879,7 +2898,7 @@ var avlTreeTyped = (() => {
|
|
|
2879
2898
|
* @returns The newly created BSTNode.
|
|
2880
2899
|
*/
|
|
2881
2900
|
createNode(key, value) {
|
|
2882
|
-
return new BSTNode(key,
|
|
2901
|
+
return new BSTNode(key, value);
|
|
2883
2902
|
}
|
|
2884
2903
|
/**
|
|
2885
2904
|
* Ensures the input is a node. If it's a key or entry, it searches for the node.
|
|
@@ -2964,8 +2983,40 @@ var avlTreeTyped = (() => {
|
|
|
2964
2983
|
* @returns The first matching node, or undefined if not found.
|
|
2965
2984
|
*/
|
|
2966
2985
|
getNode(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
2967
|
-
var _a;
|
|
2968
|
-
|
|
2986
|
+
var _a, _b;
|
|
2987
|
+
if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === void 0) return void 0;
|
|
2988
|
+
if (this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
2989
|
+
return (_a = this.getNodes(keyNodeEntryOrPredicate, true, startNode, iterationType)[0]) != null ? _a : void 0;
|
|
2990
|
+
}
|
|
2991
|
+
if (keyNodeEntryOrPredicate instanceof Range) {
|
|
2992
|
+
return (_b = this.getNodes(
|
|
2993
|
+
keyNodeEntryOrPredicate,
|
|
2994
|
+
true,
|
|
2995
|
+
startNode,
|
|
2996
|
+
iterationType
|
|
2997
|
+
)[0]) != null ? _b : void 0;
|
|
2998
|
+
}
|
|
2999
|
+
let targetKey;
|
|
3000
|
+
if (this.isNode(keyNodeEntryOrPredicate)) {
|
|
3001
|
+
targetKey = keyNodeEntryOrPredicate.key;
|
|
3002
|
+
} else if (this.isEntry(keyNodeEntryOrPredicate)) {
|
|
3003
|
+
const k = keyNodeEntryOrPredicate[0];
|
|
3004
|
+
if (k === null || k === void 0) return void 0;
|
|
3005
|
+
targetKey = k;
|
|
3006
|
+
} else {
|
|
3007
|
+
targetKey = keyNodeEntryOrPredicate;
|
|
3008
|
+
}
|
|
3009
|
+
const start = this.ensureNode(startNode);
|
|
3010
|
+
if (!start) return void 0;
|
|
3011
|
+
const NIL = this._NIL;
|
|
3012
|
+
let cur = start;
|
|
3013
|
+
const cmpFn = this._comparator;
|
|
3014
|
+
while (cur && cur !== NIL) {
|
|
3015
|
+
const c = cmpFn(targetKey, cur.key);
|
|
3016
|
+
if (c === 0) return cur;
|
|
3017
|
+
cur = c < 0 ? cur._left : cur._right;
|
|
3018
|
+
}
|
|
3019
|
+
return void 0;
|
|
2969
3020
|
}
|
|
2970
3021
|
/**
|
|
2971
3022
|
* Searches the tree for nodes matching a predicate, key, or range.
|
|
@@ -2986,8 +3037,30 @@ var avlTreeTyped = (() => {
|
|
|
2986
3037
|
if (keyNodeEntryOrPredicate === null) return [];
|
|
2987
3038
|
startNode = this.ensureNode(startNode);
|
|
2988
3039
|
if (!startNode) return [];
|
|
2989
|
-
let predicate;
|
|
2990
3040
|
const isRange = this.isRange(keyNodeEntryOrPredicate);
|
|
3041
|
+
const isPred = !isRange && this._isPredicate(keyNodeEntryOrPredicate);
|
|
3042
|
+
if (!isRange && !isPred) {
|
|
3043
|
+
let targetKey;
|
|
3044
|
+
if (this.isNode(keyNodeEntryOrPredicate)) {
|
|
3045
|
+
targetKey = keyNodeEntryOrPredicate.key;
|
|
3046
|
+
} else if (this.isEntry(keyNodeEntryOrPredicate)) {
|
|
3047
|
+
const k = keyNodeEntryOrPredicate[0];
|
|
3048
|
+
if (k !== null && k !== void 0) targetKey = k;
|
|
3049
|
+
} else {
|
|
3050
|
+
targetKey = keyNodeEntryOrPredicate;
|
|
3051
|
+
}
|
|
3052
|
+
if (targetKey === void 0) return [];
|
|
3053
|
+
const NIL = this._NIL;
|
|
3054
|
+
const cmpFn = this._comparator;
|
|
3055
|
+
let cur = startNode;
|
|
3056
|
+
while (cur && cur !== NIL) {
|
|
3057
|
+
const c = cmpFn(targetKey, cur.key);
|
|
3058
|
+
if (c === 0) return [callback(cur)];
|
|
3059
|
+
cur = c < 0 ? cur._left : cur._right;
|
|
3060
|
+
}
|
|
3061
|
+
return [];
|
|
3062
|
+
}
|
|
3063
|
+
let predicate;
|
|
2991
3064
|
if (isRange) {
|
|
2992
3065
|
predicate = (node) => {
|
|
2993
3066
|
if (!node) return false;
|
|
@@ -3066,11 +3139,11 @@ var avlTreeTyped = (() => {
|
|
|
3066
3139
|
* @returns True if the addition was successful, false otherwise.
|
|
3067
3140
|
*/
|
|
3068
3141
|
set(keyNodeOrEntry, value) {
|
|
3069
|
-
const [newNode
|
|
3142
|
+
const [newNode] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
|
|
3070
3143
|
if (newNode === void 0) return false;
|
|
3071
3144
|
if (this._root === void 0) {
|
|
3072
3145
|
this._setRoot(newNode);
|
|
3073
|
-
if (this._isMapMode
|
|
3146
|
+
if (this._isMapMode && this.isRealNode(newNode)) this._store.set(newNode.key, newNode);
|
|
3074
3147
|
this._size++;
|
|
3075
3148
|
return true;
|
|
3076
3149
|
}
|
|
@@ -3078,12 +3151,12 @@ var avlTreeTyped = (() => {
|
|
|
3078
3151
|
while (current !== void 0) {
|
|
3079
3152
|
if (this._compare(current.key, newNode.key) === 0) {
|
|
3080
3153
|
this._replaceNode(current, newNode);
|
|
3081
|
-
if (this._isMapMode) this.
|
|
3154
|
+
if (this._isMapMode && this.isRealNode(newNode)) this._store.set(current.key, newNode);
|
|
3082
3155
|
return true;
|
|
3083
3156
|
} else if (this._compare(current.key, newNode.key) > 0) {
|
|
3084
3157
|
if (current.left === void 0) {
|
|
3085
3158
|
current.left = newNode;
|
|
3086
|
-
if (this._isMapMode
|
|
3159
|
+
if (this._isMapMode && this.isRealNode(newNode)) this._store.set(newNode.key, newNode);
|
|
3087
3160
|
this._size++;
|
|
3088
3161
|
return true;
|
|
3089
3162
|
}
|
|
@@ -3091,7 +3164,7 @@ var avlTreeTyped = (() => {
|
|
|
3091
3164
|
} else {
|
|
3092
3165
|
if (current.right === void 0) {
|
|
3093
3166
|
current.right = newNode;
|
|
3094
|
-
if (this._isMapMode
|
|
3167
|
+
if (this._isMapMode && this.isRealNode(newNode)) this._store.set(newNode.key, newNode);
|
|
3095
3168
|
this._size++;
|
|
3096
3169
|
return true;
|
|
3097
3170
|
}
|
|
@@ -3874,7 +3947,6 @@ var avlTreeTyped = (() => {
|
|
|
3874
3947
|
* @returns True if the node was found and deleted, false otherwise.
|
|
3875
3948
|
*/
|
|
3876
3949
|
_deleteByKey(key) {
|
|
3877
|
-
var _a;
|
|
3878
3950
|
let node = this._root;
|
|
3879
3951
|
while (node) {
|
|
3880
3952
|
const cmp = this._compare(node.key, key);
|
|
@@ -3913,7 +3985,7 @@ var avlTreeTyped = (() => {
|
|
|
3913
3985
|
succ.left = node.left;
|
|
3914
3986
|
if (succ.left) succ.left.parent = succ;
|
|
3915
3987
|
}
|
|
3916
|
-
this._size = Math.max(0,
|
|
3988
|
+
this._size = Math.max(0, this._size - 1);
|
|
3917
3989
|
return true;
|
|
3918
3990
|
}
|
|
3919
3991
|
};
|
|
@@ -4074,7 +4146,7 @@ var avlTreeTyped = (() => {
|
|
|
4074
4146
|
* @returns The newly created AVLTreeNode.
|
|
4075
4147
|
*/
|
|
4076
4148
|
createNode(key, value) {
|
|
4077
|
-
return new AVLTreeNode(key,
|
|
4149
|
+
return new AVLTreeNode(key, value);
|
|
4078
4150
|
}
|
|
4079
4151
|
/**
|
|
4080
4152
|
* Checks if the given item is an `AVLTreeNode` instance.
|