max-priority-queue-typed 2.4.0 → 2.4.1
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/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/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/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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "max-priority-queue-typed",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"description": "Max Priority Queue",
|
|
5
5
|
"browser": "dist/umd/max-priority-queue-typed.min.js",
|
|
6
6
|
"umd:main": "dist/umd/max-priority-queue-typed.min.js",
|
|
@@ -165,6 +165,6 @@
|
|
|
165
165
|
"typescript": "^4.9.5"
|
|
166
166
|
},
|
|
167
167
|
"dependencies": {
|
|
168
|
-
"data-structure-typed": "^2.4.
|
|
168
|
+
"data-structure-typed": "^2.4.1"
|
|
169
169
|
}
|
|
170
170
|
}
|
|
@@ -75,7 +75,7 @@ export abstract class LinearBase<
|
|
|
75
75
|
* @param options - `{ maxLen?, ... }` bounds/behavior options.
|
|
76
76
|
* @remarks Time O(1), Space O(1)
|
|
77
77
|
*/
|
|
78
|
-
|
|
78
|
+
constructor(options?: LinearBaseOptions<E, R>) {
|
|
79
79
|
super(options);
|
|
80
80
|
if (options) {
|
|
81
81
|
const { maxLen } = options;
|
|
@@ -156,14 +156,6 @@ export abstract class LinearBase<
|
|
|
156
156
|
return -1;
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
/**
|
|
160
|
-
* Concatenate multiple containers of the same species.
|
|
161
|
-
* @param items - Other lists to append.
|
|
162
|
-
* @returns New container with combined elements (`this` type).
|
|
163
|
-
* @remarks Time O(sum(length)), Space O(sum(length))
|
|
164
|
-
*/
|
|
165
|
-
concat(...items: this[]): this;
|
|
166
|
-
|
|
167
159
|
/**
|
|
168
160
|
* Concatenate elements and/or containers.
|
|
169
161
|
* @param items - Elements or other containers.
|
|
@@ -412,7 +404,7 @@ export abstract class LinearLinkedBase<
|
|
|
412
404
|
R = any,
|
|
413
405
|
NODE extends LinkedListNode<E> = LinkedListNode<E>
|
|
414
406
|
> extends LinearBase<E, R, NODE> {
|
|
415
|
-
|
|
407
|
+
constructor(options?: LinearBaseOptions<E, R>) {
|
|
416
408
|
super(options);
|
|
417
409
|
if (options) {
|
|
418
410
|
const { maxLen } = options;
|
|
@@ -478,8 +470,6 @@ export abstract class LinearLinkedBase<
|
|
|
478
470
|
* @returns New list with combined elements (`this` type).
|
|
479
471
|
* @remarks Time O(sum(length)), Space O(sum(length))
|
|
480
472
|
*/
|
|
481
|
-
override concat(...items: LinearBase<E, R>[]): this;
|
|
482
|
-
|
|
483
473
|
override concat(...items: (E | LinearBase<E, R>)[]): this {
|
|
484
474
|
const newList = this.clone();
|
|
485
475
|
|
|
@@ -383,7 +383,7 @@ export class AVLTree<K = any, V = any, R = any> extends BST<K, V, R> implements
|
|
|
383
383
|
* @returns The newly created AVLTreeNode.
|
|
384
384
|
*/
|
|
385
385
|
override createNode(key: K, value?: V): AVLTreeNode<K, V> {
|
|
386
|
-
return new AVLTreeNode<K, V>(key,
|
|
386
|
+
return new AVLTreeNode<K, V>(key, value) as AVLTreeNode<K, V>;
|
|
387
387
|
}
|
|
388
388
|
|
|
389
389
|
/**
|
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
BinaryTreeDeleteResult,
|
|
11
11
|
BinaryTreeOptions,
|
|
12
12
|
BinaryTreePrintOptions,
|
|
13
|
-
BTNEntry,
|
|
13
|
+
BTNEntry, BTNRep,
|
|
14
14
|
DFSOrderPattern,
|
|
15
15
|
DFSStackItem,
|
|
16
16
|
EntryCallback,
|
|
@@ -401,7 +401,10 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
401
401
|
return this._isDuplicate;
|
|
402
402
|
}
|
|
403
403
|
|
|
404
|
-
|
|
404
|
+
// Map mode acceleration store:
|
|
405
|
+
// - isMapMode=false: unused
|
|
406
|
+
// - isMapMode=true: key -> node reference (O(1) has/getNode + fast get)
|
|
407
|
+
protected _store = new Map<K, BinaryTreeNode<K, V>>();
|
|
405
408
|
|
|
406
409
|
/**
|
|
407
410
|
* Gets the external value store (used in Map mode).
|
|
@@ -470,7 +473,7 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
470
473
|
* @returns The newly created node.
|
|
471
474
|
*/
|
|
472
475
|
createNode(key: K, value?: V): BinaryTreeNode<K, V> {
|
|
473
|
-
return new BinaryTreeNode<K, V>(key,
|
|
476
|
+
return new BinaryTreeNode<K, V>(key, value);
|
|
474
477
|
}
|
|
475
478
|
|
|
476
479
|
/**
|
|
@@ -661,12 +664,12 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
661
664
|
value?: V
|
|
662
665
|
): boolean {
|
|
663
666
|
|
|
664
|
-
const [newNode
|
|
667
|
+
const [newNode] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
|
|
665
668
|
if (newNode === undefined) return false;
|
|
666
669
|
|
|
667
670
|
if (!this._root) {
|
|
668
671
|
this._setRoot(newNode);
|
|
669
|
-
if (this._isMapMode) this.
|
|
672
|
+
if (this._isMapMode && newNode !== null && newNode !== undefined) this._store.set(newNode.key, newNode);
|
|
670
673
|
this._size = 1;
|
|
671
674
|
return true;
|
|
672
675
|
}
|
|
@@ -681,7 +684,7 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
681
684
|
if (!this._isDuplicate) {
|
|
682
685
|
if (newNode !== null && cur.key === newNode.key) {
|
|
683
686
|
this._replaceNode(cur, newNode);
|
|
684
|
-
if (this._isMapMode) this.
|
|
687
|
+
if (this._isMapMode && newNode !== null) this._store.set(cur.key, newNode);
|
|
685
688
|
return true; // Replaced existing node
|
|
686
689
|
}
|
|
687
690
|
}
|
|
@@ -704,7 +707,7 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
704
707
|
} else if (potentialParent.right === undefined) {
|
|
705
708
|
potentialParent.right = newNode;
|
|
706
709
|
}
|
|
707
|
-
if (this._isMapMode) this.
|
|
710
|
+
if (this._isMapMode && newNode !== null && newNode !== undefined) this._store.set(newNode.key, newNode);
|
|
708
711
|
this._size++;
|
|
709
712
|
return true;
|
|
710
713
|
}
|
|
@@ -795,16 +798,16 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
795
798
|
* Deletes a node from the tree.
|
|
796
799
|
* @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).
|
|
797
800
|
*
|
|
798
|
-
* @param
|
|
801
|
+
* @param keyNodeEntryRawOrPredicate - The node to delete.
|
|
799
802
|
* @returns An array containing deletion results (for compatibility with self-balancing trees).
|
|
800
803
|
*/
|
|
801
804
|
delete(
|
|
802
|
-
|
|
805
|
+
keyNodeEntryRawOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V> | null>
|
|
803
806
|
): BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[] {
|
|
804
807
|
const deletedResult: BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[] = [];
|
|
805
808
|
if (!this._root) return deletedResult;
|
|
806
809
|
|
|
807
|
-
const curr = this.getNode(
|
|
810
|
+
const curr = this.getNode(keyNodeEntryRawOrPredicate);
|
|
808
811
|
if (!curr) return deletedResult;
|
|
809
812
|
|
|
810
813
|
const parent: BinaryTreeNode<K, V> | undefined = curr?.parent;
|
|
@@ -822,6 +825,13 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
822
825
|
const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
|
|
823
826
|
// Swap properties
|
|
824
827
|
orgCurrent = this._swapProperties(curr, leftSubTreeRightMost);
|
|
828
|
+
|
|
829
|
+
// Map mode store tracks key -> node reference; after swapping keys we must re-index both nodes.
|
|
830
|
+
if (this._isMapMode) {
|
|
831
|
+
this._store.set(curr.key, curr);
|
|
832
|
+
this._store.set(leftSubTreeRightMost.key, leftSubTreeRightMost);
|
|
833
|
+
}
|
|
834
|
+
|
|
825
835
|
// `orgCurrent` is now the node to be physically deleted (which was the rightmost)
|
|
826
836
|
if (parentOfLeftSubTreeMax) {
|
|
827
837
|
// Unlink the rightmost node
|
|
@@ -1002,6 +1012,13 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
1002
1012
|
startNode: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined = this._root,
|
|
1003
1013
|
iterationType: IterationType = this.iterationType
|
|
1004
1014
|
): BinaryTreeNode<K, V> | null | undefined {
|
|
1015
|
+
if (this._isMapMode && keyNodeEntryOrPredicate !== null && keyNodeEntryOrPredicate !== undefined) {
|
|
1016
|
+
if (!this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
1017
|
+
const key = this._extractKey(keyNodeEntryOrPredicate as any);
|
|
1018
|
+
if (key === null || key === undefined) return;
|
|
1019
|
+
return this._store.get(key);
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1005
1022
|
return this.search(keyNodeEntryOrPredicate, true, node => node, startNode, iterationType)[0];
|
|
1006
1023
|
}
|
|
1007
1024
|
|
|
@@ -1022,7 +1039,7 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
1022
1039
|
if (this._isMapMode) {
|
|
1023
1040
|
const key = this._extractKey(keyNodeEntryOrPredicate);
|
|
1024
1041
|
if (key === null || key === undefined) return;
|
|
1025
|
-
return this._store.get(key);
|
|
1042
|
+
return this._store.get(key)?.value;
|
|
1026
1043
|
}
|
|
1027
1044
|
return this.getNode(keyNodeEntryOrPredicate, startNode, iterationType)?.value;
|
|
1028
1045
|
}
|
|
@@ -1059,6 +1076,13 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
1059
1076
|
startNode: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined = this._root,
|
|
1060
1077
|
iterationType: IterationType = this.iterationType
|
|
1061
1078
|
): boolean {
|
|
1079
|
+
if (this._isMapMode && keyNodeEntryOrPredicate !== undefined && keyNodeEntryOrPredicate !== null) {
|
|
1080
|
+
if (!this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
1081
|
+
const key = this._extractKey(keyNodeEntryOrPredicate as any);
|
|
1082
|
+
if (key === null || key === undefined) return false;
|
|
1083
|
+
return this._store.has(key);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1062
1086
|
return this.search(keyNodeEntryOrPredicate, true, node => node, startNode, iterationType).length > 0;
|
|
1063
1087
|
}
|
|
1064
1088
|
|
|
@@ -1139,7 +1163,7 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
1139
1163
|
}
|
|
1140
1164
|
return true;
|
|
1141
1165
|
};
|
|
1142
|
-
const isStandardBST = checkBST(
|
|
1166
|
+
const isStandardBST = checkBST();
|
|
1143
1167
|
const isInverseBST = checkBST(true);
|
|
1144
1168
|
return isStandardBST || isInverseBST;
|
|
1145
1169
|
}
|
|
@@ -2086,8 +2110,7 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
2086
2110
|
current = stack.pop();
|
|
2087
2111
|
|
|
2088
2112
|
if (this.isRealNode(current)) {
|
|
2089
|
-
|
|
2090
|
-
else yield [current.key, current.value];
|
|
2113
|
+
yield [current.key, current.value];
|
|
2091
2114
|
// Move to the right subtree
|
|
2092
2115
|
current = current.right;
|
|
2093
2116
|
}
|
|
@@ -2098,8 +2121,7 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
2098
2121
|
yield* this[Symbol.iterator](node.left);
|
|
2099
2122
|
}
|
|
2100
2123
|
|
|
2101
|
-
|
|
2102
|
-
else yield [node.key, node.value];
|
|
2124
|
+
yield [node.key, node.value];
|
|
2103
2125
|
|
|
2104
2126
|
if (node.right && this.isRealNode(node)) {
|
|
2105
2127
|
yield* this[Symbol.iterator](node.right);
|
|
@@ -2212,15 +2234,14 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
2212
2234
|
node => {
|
|
2213
2235
|
if (node === null) cloned.set(null);
|
|
2214
2236
|
else {
|
|
2215
|
-
|
|
2216
|
-
else cloned.set([node.key, node.value]);
|
|
2237
|
+
cloned.set([node.key, node.value]);
|
|
2217
2238
|
}
|
|
2218
2239
|
},
|
|
2219
2240
|
this._root,
|
|
2220
2241
|
this.iterationType,
|
|
2221
2242
|
true // Include nulls
|
|
2222
2243
|
);
|
|
2223
|
-
|
|
2244
|
+
// Map mode: store is rebuilt via set() calls above.
|
|
2224
2245
|
}
|
|
2225
2246
|
|
|
2226
2247
|
/**
|
|
@@ -2468,8 +2489,11 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
2468
2489
|
*/
|
|
2469
2490
|
protected _setValue(key: K | null | undefined, value: V | undefined) {
|
|
2470
2491
|
if (key === null || key === undefined) return false;
|
|
2471
|
-
|
|
2472
|
-
|
|
2492
|
+
// Map mode stores node references; update the node value in-place.
|
|
2493
|
+
const node = this._store.get(key);
|
|
2494
|
+
if (!node) return false;
|
|
2495
|
+
node.value = value as V;
|
|
2496
|
+
return true;
|
|
2473
2497
|
}
|
|
2474
2498
|
|
|
2475
2499
|
/**
|