data-structure-typed 2.2.7 → 2.2.8
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/CHANGELOG.md +1 -1
- package/README.md +14 -3
- package/README_CN.md +119 -275
- package/benchmark/report.html +1 -1
- package/benchmark/report.json +20 -324
- package/dist/cjs/index.cjs +106 -107
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +106 -107
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +106 -107
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +106 -107
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/leetcode/avl-tree-counter.mjs +2957 -0
- package/dist/leetcode/avl-tree-multi-map.mjs +2889 -0
- package/dist/leetcode/avl-tree.mjs +2720 -0
- package/dist/leetcode/binary-tree.mjs +1594 -0
- package/dist/leetcode/bst.mjs +2398 -0
- package/dist/leetcode/deque.mjs +683 -0
- package/dist/leetcode/directed-graph.mjs +1733 -0
- package/dist/leetcode/doubly-linked-list.mjs +709 -0
- package/dist/leetcode/hash-map.mjs +493 -0
- package/dist/leetcode/heap.mjs +542 -0
- package/dist/leetcode/max-heap.mjs +375 -0
- package/dist/leetcode/max-priority-queue.mjs +383 -0
- package/dist/leetcode/min-heap.mjs +363 -0
- package/dist/leetcode/min-priority-queue.mjs +371 -0
- package/dist/leetcode/priority-queue.mjs +363 -0
- package/dist/leetcode/queue.mjs +943 -0
- package/dist/leetcode/red-black-tree.mjs +2765 -0
- package/dist/leetcode/singly-linked-list.mjs +754 -0
- package/dist/leetcode/stack.mjs +217 -0
- package/dist/leetcode/tree-counter.mjs +3039 -0
- package/dist/leetcode/tree-multi-map.mjs +2913 -0
- package/dist/leetcode/trie.mjs +413 -0
- package/dist/leetcode/undirected-graph.mjs +1650 -0
- package/dist/types/data-structures/binary-tree/avl-tree-counter.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +2 -2
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +10 -10
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +22 -23
- package/dist/types/data-structures/binary-tree/bst.d.ts +11 -11
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/tree-counter.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +2 -2
- package/dist/umd/data-structure-typed.js +102 -103
- package/dist/umd/data-structure-typed.js.map +1 -1
- package/dist/umd/data-structure-typed.min.js +2 -2
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +48 -171
- package/src/data-structures/binary-tree/avl-tree-counter.ts +6 -6
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +13 -13
- package/src/data-structures/binary-tree/avl-tree.ts +15 -15
- package/src/data-structures/binary-tree/binary-tree.ts +53 -55
- package/src/data-structures/binary-tree/bst.ts +21 -22
- package/src/data-structures/binary-tree/red-black-tree.ts +3 -3
- package/src/data-structures/binary-tree/tree-counter.ts +4 -4
- package/src/data-structures/binary-tree/tree-multi-map.ts +13 -13
- package/test/performance/data-structures/binary-tree/red-black-tree.test.ts +1 -2
- package/test/unit/data-structures/binary-tree/avl-tree-counter.test.ts +30 -30
- package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +46 -46
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +43 -43
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +151 -151
- package/test/unit/data-structures/binary-tree/bst.test.ts +99 -99
- package/test/unit/data-structures/binary-tree/overall.test.ts +20 -20
- package/test/unit/data-structures/binary-tree/red-black-tree.test.ts +141 -141
- package/test/unit/data-structures/binary-tree/tree-counter.test.ts +37 -37
- package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +145 -145
- package/tsup.config.js +50 -21
- package/tsup.umd.config.js +29 -0
- package/tsup.node.config.js +0 -83
|
@@ -0,0 +1,2889 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
function isPrimitiveComparable(value) {
|
|
4
|
+
const valueType = typeof value;
|
|
5
|
+
if (valueType === "number") return true;
|
|
6
|
+
return valueType === "bigint" || valueType === "string" || valueType === "boolean";
|
|
7
|
+
}
|
|
8
|
+
__name(isPrimitiveComparable, "isPrimitiveComparable");
|
|
9
|
+
function tryObjectToPrimitive(obj) {
|
|
10
|
+
if (typeof obj.valueOf === "function") {
|
|
11
|
+
const valueOfResult = obj.valueOf();
|
|
12
|
+
if (valueOfResult !== obj) {
|
|
13
|
+
if (isPrimitiveComparable(valueOfResult)) return valueOfResult;
|
|
14
|
+
if (typeof valueOfResult === "object" && valueOfResult !== null) return tryObjectToPrimitive(valueOfResult);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (typeof obj.toString === "function") {
|
|
18
|
+
const stringResult = obj.toString();
|
|
19
|
+
if (stringResult !== "[object Object]") return stringResult;
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
__name(tryObjectToPrimitive, "tryObjectToPrimitive");
|
|
24
|
+
function isComparable(value, isForceObjectComparable = false) {
|
|
25
|
+
if (value === null || value === void 0) return false;
|
|
26
|
+
if (isPrimitiveComparable(value)) return true;
|
|
27
|
+
if (typeof value !== "object") return false;
|
|
28
|
+
if (value instanceof Date) return true;
|
|
29
|
+
if (isForceObjectComparable) return true;
|
|
30
|
+
const comparableValue = tryObjectToPrimitive(value);
|
|
31
|
+
if (comparableValue === null || comparableValue === void 0) return false;
|
|
32
|
+
return isPrimitiveComparable(comparableValue);
|
|
33
|
+
}
|
|
34
|
+
__name(isComparable, "isComparable");
|
|
35
|
+
var makeTrampolineThunk = __name((computation) => ({
|
|
36
|
+
isThunk: true,
|
|
37
|
+
fn: computation
|
|
38
|
+
}), "makeTrampolineThunk");
|
|
39
|
+
var isTrampolineThunk = __name((value) => typeof value === "object" && // Must be an object
|
|
40
|
+
value !== null && // Must not be null
|
|
41
|
+
"isThunk" in value && // Must have the 'isThunk' property
|
|
42
|
+
value.isThunk, "isTrampolineThunk");
|
|
43
|
+
function trampoline(initial) {
|
|
44
|
+
let current = initial;
|
|
45
|
+
while (isTrampolineThunk(current)) {
|
|
46
|
+
current = current.fn();
|
|
47
|
+
}
|
|
48
|
+
return current;
|
|
49
|
+
}
|
|
50
|
+
__name(trampoline, "trampoline");
|
|
51
|
+
function makeTrampoline(fn) {
|
|
52
|
+
return (...args) => trampoline(fn(...args));
|
|
53
|
+
}
|
|
54
|
+
__name(makeTrampoline, "makeTrampoline");
|
|
55
|
+
var IterableElementBase = class {
|
|
56
|
+
static {
|
|
57
|
+
__name(this, "IterableElementBase");
|
|
58
|
+
}
|
|
59
|
+
constructor(options) {
|
|
60
|
+
if (options) {
|
|
61
|
+
const { toElementFn } = options;
|
|
62
|
+
if (typeof toElementFn === "function") this._toElementFn = toElementFn;
|
|
63
|
+
else if (toElementFn) throw new TypeError("toElementFn must be a function type");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
_toElementFn;
|
|
67
|
+
get toElementFn() {
|
|
68
|
+
return this._toElementFn;
|
|
69
|
+
}
|
|
70
|
+
*[Symbol.iterator](...args) {
|
|
71
|
+
yield* this._getIterator(...args);
|
|
72
|
+
}
|
|
73
|
+
*values() {
|
|
74
|
+
for (const item of this) yield item;
|
|
75
|
+
}
|
|
76
|
+
every(predicate, thisArg) {
|
|
77
|
+
let index = 0;
|
|
78
|
+
for (const item of this) {
|
|
79
|
+
if (thisArg === void 0) {
|
|
80
|
+
if (!predicate(item, index++, this)) return false;
|
|
81
|
+
} else {
|
|
82
|
+
const fn = predicate;
|
|
83
|
+
if (!fn.call(thisArg, item, index++, this)) return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
some(predicate, thisArg) {
|
|
89
|
+
let index = 0;
|
|
90
|
+
for (const item of this) {
|
|
91
|
+
if (thisArg === void 0) {
|
|
92
|
+
if (predicate(item, index++, this)) return true;
|
|
93
|
+
} else {
|
|
94
|
+
const fn = predicate;
|
|
95
|
+
if (fn.call(thisArg, item, index++, this)) return true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
forEach(callbackfn, thisArg) {
|
|
101
|
+
let index = 0;
|
|
102
|
+
for (const item of this) {
|
|
103
|
+
if (thisArg === void 0) {
|
|
104
|
+
callbackfn(item, index++, this);
|
|
105
|
+
} else {
|
|
106
|
+
const fn = callbackfn;
|
|
107
|
+
fn.call(thisArg, item, index++, this);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
find(predicate, thisArg) {
|
|
112
|
+
let index = 0;
|
|
113
|
+
for (const item of this) {
|
|
114
|
+
if (thisArg === void 0) {
|
|
115
|
+
if (predicate(item, index++, this)) return item;
|
|
116
|
+
} else {
|
|
117
|
+
const fn = predicate;
|
|
118
|
+
if (fn.call(thisArg, item, index++, this)) return item;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
has(element) {
|
|
124
|
+
for (const ele of this) if (ele === element) return true;
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
reduce(callbackfn, initialValue) {
|
|
128
|
+
let index = 0;
|
|
129
|
+
const iter = this[Symbol.iterator]();
|
|
130
|
+
let acc;
|
|
131
|
+
if (arguments.length >= 2) {
|
|
132
|
+
acc = initialValue;
|
|
133
|
+
} else {
|
|
134
|
+
const first = iter.next();
|
|
135
|
+
if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
|
|
136
|
+
acc = first.value;
|
|
137
|
+
index = 1;
|
|
138
|
+
}
|
|
139
|
+
for (const value of iter) {
|
|
140
|
+
acc = callbackfn(acc, value, index++, this);
|
|
141
|
+
}
|
|
142
|
+
return acc;
|
|
143
|
+
}
|
|
144
|
+
toArray() {
|
|
145
|
+
return [...this];
|
|
146
|
+
}
|
|
147
|
+
toVisual() {
|
|
148
|
+
return [...this];
|
|
149
|
+
}
|
|
150
|
+
print() {
|
|
151
|
+
console.log(this.toVisual());
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
var LinearBase = class _LinearBase extends IterableElementBase {
|
|
155
|
+
static {
|
|
156
|
+
__name(this, "LinearBase");
|
|
157
|
+
}
|
|
158
|
+
constructor(options) {
|
|
159
|
+
super(options);
|
|
160
|
+
if (options) {
|
|
161
|
+
const { maxLen } = options;
|
|
162
|
+
if (typeof maxLen === "number" && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
_maxLen = -1;
|
|
166
|
+
get maxLen() {
|
|
167
|
+
return this._maxLen;
|
|
168
|
+
}
|
|
169
|
+
indexOf(searchElement, fromIndex = 0) {
|
|
170
|
+
if (this.length === 0) return -1;
|
|
171
|
+
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
172
|
+
if (fromIndex < 0) fromIndex = 0;
|
|
173
|
+
for (let i = fromIndex; i < this.length; i++) {
|
|
174
|
+
const element = this.at(i);
|
|
175
|
+
if (element === searchElement) return i;
|
|
176
|
+
}
|
|
177
|
+
return -1;
|
|
178
|
+
}
|
|
179
|
+
lastIndexOf(searchElement, fromIndex = this.length - 1) {
|
|
180
|
+
if (this.length === 0) return -1;
|
|
181
|
+
if (fromIndex >= this.length) fromIndex = this.length - 1;
|
|
182
|
+
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
183
|
+
for (let i = fromIndex; i >= 0; i--) {
|
|
184
|
+
const element = this.at(i);
|
|
185
|
+
if (element === searchElement) return i;
|
|
186
|
+
}
|
|
187
|
+
return -1;
|
|
188
|
+
}
|
|
189
|
+
findIndex(predicate, thisArg) {
|
|
190
|
+
for (let i = 0; i < this.length; i++) {
|
|
191
|
+
const item = this.at(i);
|
|
192
|
+
if (item !== void 0 && predicate.call(thisArg, item, i, this)) return i;
|
|
193
|
+
}
|
|
194
|
+
return -1;
|
|
195
|
+
}
|
|
196
|
+
concat(...items) {
|
|
197
|
+
const newList = this.clone();
|
|
198
|
+
for (const item of items) {
|
|
199
|
+
if (item instanceof _LinearBase) {
|
|
200
|
+
newList.pushMany(item);
|
|
201
|
+
} else {
|
|
202
|
+
newList.push(item);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return newList;
|
|
206
|
+
}
|
|
207
|
+
sort(compareFn) {
|
|
208
|
+
const arr = this.toArray();
|
|
209
|
+
arr.sort(compareFn);
|
|
210
|
+
this.clear();
|
|
211
|
+
for (const item of arr) this.push(item);
|
|
212
|
+
return this;
|
|
213
|
+
}
|
|
214
|
+
splice(start, deleteCount = 0, ...items) {
|
|
215
|
+
const removedList = this._createInstance();
|
|
216
|
+
start = start < 0 ? this.length + start : start;
|
|
217
|
+
start = Math.max(0, Math.min(start, this.length));
|
|
218
|
+
deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
|
|
219
|
+
for (let i = 0; i < deleteCount; i++) {
|
|
220
|
+
const removed = this.deleteAt(start);
|
|
221
|
+
if (removed !== void 0) {
|
|
222
|
+
removedList.push(removed);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
for (let i = 0; i < items.length; i++) {
|
|
226
|
+
this.addAt(start + i, items[i]);
|
|
227
|
+
}
|
|
228
|
+
return removedList;
|
|
229
|
+
}
|
|
230
|
+
join(separator = ",") {
|
|
231
|
+
return this.toArray().join(separator);
|
|
232
|
+
}
|
|
233
|
+
toReversedArray() {
|
|
234
|
+
const array = [];
|
|
235
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
236
|
+
array.push(this.at(i));
|
|
237
|
+
}
|
|
238
|
+
return array;
|
|
239
|
+
}
|
|
240
|
+
reduceRight(callbackfn, initialValue) {
|
|
241
|
+
let accumulator = initialValue ?? 0;
|
|
242
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
243
|
+
accumulator = callbackfn(accumulator, this.at(i), i, this);
|
|
244
|
+
}
|
|
245
|
+
return accumulator;
|
|
246
|
+
}
|
|
247
|
+
slice(start = 0, end = this.length) {
|
|
248
|
+
start = start < 0 ? this.length + start : start;
|
|
249
|
+
end = end < 0 ? this.length + end : end;
|
|
250
|
+
const newList = this._createInstance();
|
|
251
|
+
for (let i = start; i < end; i++) {
|
|
252
|
+
newList.push(this.at(i));
|
|
253
|
+
}
|
|
254
|
+
return newList;
|
|
255
|
+
}
|
|
256
|
+
fill(value, start = 0, end = this.length) {
|
|
257
|
+
start = start < 0 ? this.length + start : start;
|
|
258
|
+
end = end < 0 ? this.length + end : end;
|
|
259
|
+
if (start < 0) start = 0;
|
|
260
|
+
if (end > this.length) end = this.length;
|
|
261
|
+
if (start >= end) return this;
|
|
262
|
+
for (let i = start; i < end; i++) {
|
|
263
|
+
this.setAt(i, value);
|
|
264
|
+
}
|
|
265
|
+
return this;
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
var Queue = class _Queue extends LinearBase {
|
|
269
|
+
static {
|
|
270
|
+
__name(this, "Queue");
|
|
271
|
+
}
|
|
272
|
+
constructor(elements = [], options) {
|
|
273
|
+
super(options);
|
|
274
|
+
if (options) {
|
|
275
|
+
const { autoCompactRatio = 0.5 } = options;
|
|
276
|
+
this._autoCompactRatio = autoCompactRatio;
|
|
277
|
+
}
|
|
278
|
+
this.pushMany(elements);
|
|
279
|
+
}
|
|
280
|
+
_elements = [];
|
|
281
|
+
get elements() {
|
|
282
|
+
return this._elements;
|
|
283
|
+
}
|
|
284
|
+
_offset = 0;
|
|
285
|
+
get offset() {
|
|
286
|
+
return this._offset;
|
|
287
|
+
}
|
|
288
|
+
_autoCompactRatio = 0.5;
|
|
289
|
+
get autoCompactRatio() {
|
|
290
|
+
return this._autoCompactRatio;
|
|
291
|
+
}
|
|
292
|
+
set autoCompactRatio(value) {
|
|
293
|
+
this._autoCompactRatio = value;
|
|
294
|
+
}
|
|
295
|
+
get length() {
|
|
296
|
+
return this.elements.length - this._offset;
|
|
297
|
+
}
|
|
298
|
+
get first() {
|
|
299
|
+
return this.length > 0 ? this.elements[this._offset] : void 0;
|
|
300
|
+
}
|
|
301
|
+
get last() {
|
|
302
|
+
return this.length > 0 ? this.elements[this.elements.length - 1] : void 0;
|
|
303
|
+
}
|
|
304
|
+
static fromArray(elements) {
|
|
305
|
+
return new _Queue(elements);
|
|
306
|
+
}
|
|
307
|
+
isEmpty() {
|
|
308
|
+
return this.length === 0;
|
|
309
|
+
}
|
|
310
|
+
push(element) {
|
|
311
|
+
this.elements.push(element);
|
|
312
|
+
if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
|
|
313
|
+
return true;
|
|
314
|
+
}
|
|
315
|
+
pushMany(elements) {
|
|
316
|
+
const ans = [];
|
|
317
|
+
for (const el of elements) {
|
|
318
|
+
if (this.toElementFn) ans.push(this.push(this.toElementFn(el)));
|
|
319
|
+
else ans.push(this.push(el));
|
|
320
|
+
}
|
|
321
|
+
return ans;
|
|
322
|
+
}
|
|
323
|
+
shift() {
|
|
324
|
+
if (this.length === 0) return void 0;
|
|
325
|
+
const first = this.first;
|
|
326
|
+
this._offset += 1;
|
|
327
|
+
if (this.elements.length > 0 && this.offset / this.elements.length > this.autoCompactRatio) this.compact();
|
|
328
|
+
return first;
|
|
329
|
+
}
|
|
330
|
+
delete(element) {
|
|
331
|
+
for (let i = this._offset; i < this.elements.length; i++) {
|
|
332
|
+
if (Object.is(this.elements[i], element)) {
|
|
333
|
+
this.elements.splice(i, 1);
|
|
334
|
+
return true;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
at(index) {
|
|
340
|
+
if (index < 0 || index >= this.length) return void 0;
|
|
341
|
+
return this._elements[this._offset + index];
|
|
342
|
+
}
|
|
343
|
+
deleteAt(index) {
|
|
344
|
+
if (index < 0 || index >= this.length) return void 0;
|
|
345
|
+
const gi = this._offset + index;
|
|
346
|
+
const [deleted] = this.elements.splice(gi, 1);
|
|
347
|
+
return deleted;
|
|
348
|
+
}
|
|
349
|
+
addAt(index, newElement) {
|
|
350
|
+
if (index < 0 || index > this.length) return false;
|
|
351
|
+
this._elements.splice(this._offset + index, 0, newElement);
|
|
352
|
+
return true;
|
|
353
|
+
}
|
|
354
|
+
setAt(index, newElement) {
|
|
355
|
+
if (index < 0 || index >= this.length) return false;
|
|
356
|
+
this._elements[this._offset + index] = newElement;
|
|
357
|
+
return true;
|
|
358
|
+
}
|
|
359
|
+
reverse() {
|
|
360
|
+
this._elements = this.elements.slice(this._offset).reverse();
|
|
361
|
+
this._offset = 0;
|
|
362
|
+
return this;
|
|
363
|
+
}
|
|
364
|
+
clear() {
|
|
365
|
+
this._elements = [];
|
|
366
|
+
this._offset = 0;
|
|
367
|
+
}
|
|
368
|
+
compact() {
|
|
369
|
+
this._elements = this.elements.slice(this._offset);
|
|
370
|
+
this._offset = 0;
|
|
371
|
+
return true;
|
|
372
|
+
}
|
|
373
|
+
splice(start, deleteCount = 0, ...items) {
|
|
374
|
+
start = Math.max(0, Math.min(start, this.length));
|
|
375
|
+
deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
|
|
376
|
+
const gi = this._offset + start;
|
|
377
|
+
const removedArray = this._elements.splice(gi, deleteCount, ...items);
|
|
378
|
+
if (this.elements.length > 0 && this.offset / this.elements.length > this.autoCompactRatio) this.compact();
|
|
379
|
+
const removed = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
380
|
+
removed._setAutoCompactRatio(this._autoCompactRatio);
|
|
381
|
+
removed.pushMany(removedArray);
|
|
382
|
+
return removed;
|
|
383
|
+
}
|
|
384
|
+
clone() {
|
|
385
|
+
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
386
|
+
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
387
|
+
for (let i = this._offset; i < this.elements.length; i++) out.push(this.elements[i]);
|
|
388
|
+
return out;
|
|
389
|
+
}
|
|
390
|
+
filter(predicate, thisArg) {
|
|
391
|
+
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
392
|
+
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
393
|
+
let index = 0;
|
|
394
|
+
for (const v of this) {
|
|
395
|
+
if (predicate.call(thisArg, v, index, this)) out.push(v);
|
|
396
|
+
index++;
|
|
397
|
+
}
|
|
398
|
+
return out;
|
|
399
|
+
}
|
|
400
|
+
map(callback, options, thisArg) {
|
|
401
|
+
const out = new this.constructor([], {
|
|
402
|
+
toElementFn: options?.toElementFn,
|
|
403
|
+
maxLen: options?.maxLen ?? this._maxLen,
|
|
404
|
+
autoCompactRatio: options?.autoCompactRatio ?? this._autoCompactRatio
|
|
405
|
+
});
|
|
406
|
+
let index = 0;
|
|
407
|
+
for (const v of this)
|
|
408
|
+
out.push(thisArg === void 0 ? callback(v, index++, this) : callback.call(thisArg, v, index++, this));
|
|
409
|
+
return out;
|
|
410
|
+
}
|
|
411
|
+
mapSame(callback, thisArg) {
|
|
412
|
+
const Ctor = this.constructor;
|
|
413
|
+
const out = new Ctor([], {
|
|
414
|
+
toElementFn: this.toElementFn,
|
|
415
|
+
maxLen: this._maxLen,
|
|
416
|
+
autoCompactRatio: this._autoCompactRatio
|
|
417
|
+
});
|
|
418
|
+
out._setAutoCompactRatio?.(this._autoCompactRatio);
|
|
419
|
+
let index = 0;
|
|
420
|
+
for (const v of this) {
|
|
421
|
+
const mv = thisArg === void 0 ? callback(v, index++, this) : callback.call(thisArg, v, index++, this);
|
|
422
|
+
out.push(mv);
|
|
423
|
+
}
|
|
424
|
+
return out;
|
|
425
|
+
}
|
|
426
|
+
_setAutoCompactRatio(value) {
|
|
427
|
+
this._autoCompactRatio = value;
|
|
428
|
+
}
|
|
429
|
+
*_getIterator() {
|
|
430
|
+
for (let i = this._offset; i < this.elements.length; i++) yield this.elements[i];
|
|
431
|
+
}
|
|
432
|
+
*_getReverseIterator() {
|
|
433
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
434
|
+
const cur = this.at(i);
|
|
435
|
+
if (cur !== void 0) yield cur;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
_createInstance(options) {
|
|
439
|
+
const Ctor = this.constructor;
|
|
440
|
+
return new Ctor([], options);
|
|
441
|
+
}
|
|
442
|
+
_createLike(elements = [], options) {
|
|
443
|
+
const Ctor = this.constructor;
|
|
444
|
+
return new Ctor(elements, options);
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
var IterableEntryBase = class {
|
|
448
|
+
static {
|
|
449
|
+
__name(this, "IterableEntryBase");
|
|
450
|
+
}
|
|
451
|
+
*[Symbol.iterator](...args) {
|
|
452
|
+
yield* this._getIterator(...args);
|
|
453
|
+
}
|
|
454
|
+
*entries() {
|
|
455
|
+
for (const item of this) {
|
|
456
|
+
yield item;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
*keys() {
|
|
460
|
+
for (const item of this) {
|
|
461
|
+
yield item[0];
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
*values() {
|
|
465
|
+
for (const item of this) {
|
|
466
|
+
yield item[1];
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
every(predicate, thisArg) {
|
|
470
|
+
let index = 0;
|
|
471
|
+
for (const item of this) {
|
|
472
|
+
if (!predicate.call(thisArg, item[1], item[0], index++, this)) {
|
|
473
|
+
return false;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
return true;
|
|
477
|
+
}
|
|
478
|
+
some(predicate, thisArg) {
|
|
479
|
+
let index = 0;
|
|
480
|
+
for (const item of this) {
|
|
481
|
+
if (predicate.call(thisArg, item[1], item[0], index++, this)) {
|
|
482
|
+
return true;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
forEach(callbackfn, thisArg) {
|
|
488
|
+
let index = 0;
|
|
489
|
+
for (const item of this) {
|
|
490
|
+
const [key, value] = item;
|
|
491
|
+
callbackfn.call(thisArg, value, key, index++, this);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
find(callbackfn, thisArg) {
|
|
495
|
+
let index = 0;
|
|
496
|
+
for (const item of this) {
|
|
497
|
+
const [key, value] = item;
|
|
498
|
+
if (callbackfn.call(thisArg, value, key, index++, this)) return item;
|
|
499
|
+
}
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
has(key) {
|
|
503
|
+
for (const item of this) {
|
|
504
|
+
const [itemKey] = item;
|
|
505
|
+
if (itemKey === key) return true;
|
|
506
|
+
}
|
|
507
|
+
return false;
|
|
508
|
+
}
|
|
509
|
+
hasValue(value) {
|
|
510
|
+
for (const [, elementValue] of this) {
|
|
511
|
+
if (elementValue === value) return true;
|
|
512
|
+
}
|
|
513
|
+
return false;
|
|
514
|
+
}
|
|
515
|
+
get(key) {
|
|
516
|
+
for (const item of this) {
|
|
517
|
+
const [itemKey, value] = item;
|
|
518
|
+
if (itemKey === key) return value;
|
|
519
|
+
}
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
reduce(callbackfn, initialValue) {
|
|
523
|
+
let accumulator = initialValue;
|
|
524
|
+
let index = 0;
|
|
525
|
+
for (const item of this) {
|
|
526
|
+
const [key, value] = item;
|
|
527
|
+
accumulator = callbackfn(accumulator, value, key, index++, this);
|
|
528
|
+
}
|
|
529
|
+
return accumulator;
|
|
530
|
+
}
|
|
531
|
+
toArray() {
|
|
532
|
+
return [...this];
|
|
533
|
+
}
|
|
534
|
+
toVisual() {
|
|
535
|
+
return [...this];
|
|
536
|
+
}
|
|
537
|
+
print() {
|
|
538
|
+
console.log(this.toVisual());
|
|
539
|
+
}
|
|
540
|
+
};
|
|
541
|
+
var Range = class {
|
|
542
|
+
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
543
|
+
this.low = low;
|
|
544
|
+
this.high = high;
|
|
545
|
+
this.includeLow = includeLow;
|
|
546
|
+
this.includeHigh = includeHigh;
|
|
547
|
+
}
|
|
548
|
+
static {
|
|
549
|
+
__name(this, "Range");
|
|
550
|
+
}
|
|
551
|
+
isInRange(key, comparator) {
|
|
552
|
+
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
553
|
+
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
554
|
+
return lowCheck && highCheck;
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
var BinaryTreeNode = class {
|
|
558
|
+
static {
|
|
559
|
+
__name(this, "BinaryTreeNode");
|
|
560
|
+
}
|
|
561
|
+
key;
|
|
562
|
+
value;
|
|
563
|
+
parent = void 0;
|
|
564
|
+
constructor(key, value) {
|
|
565
|
+
this.key = key;
|
|
566
|
+
this.value = value;
|
|
567
|
+
}
|
|
568
|
+
_left = void 0;
|
|
569
|
+
get left() {
|
|
570
|
+
return this._left;
|
|
571
|
+
}
|
|
572
|
+
set left(v) {
|
|
573
|
+
if (v) {
|
|
574
|
+
v.parent = this;
|
|
575
|
+
}
|
|
576
|
+
this._left = v;
|
|
577
|
+
}
|
|
578
|
+
_right = void 0;
|
|
579
|
+
get right() {
|
|
580
|
+
return this._right;
|
|
581
|
+
}
|
|
582
|
+
set right(v) {
|
|
583
|
+
if (v) {
|
|
584
|
+
v.parent = this;
|
|
585
|
+
}
|
|
586
|
+
this._right = v;
|
|
587
|
+
}
|
|
588
|
+
_height = 0;
|
|
589
|
+
get height() {
|
|
590
|
+
return this._height;
|
|
591
|
+
}
|
|
592
|
+
set height(value) {
|
|
593
|
+
this._height = value;
|
|
594
|
+
}
|
|
595
|
+
_color = "BLACK";
|
|
596
|
+
get color() {
|
|
597
|
+
return this._color;
|
|
598
|
+
}
|
|
599
|
+
set color(value) {
|
|
600
|
+
this._color = value;
|
|
601
|
+
}
|
|
602
|
+
_count = 1;
|
|
603
|
+
get count() {
|
|
604
|
+
return this._count;
|
|
605
|
+
}
|
|
606
|
+
set count(value) {
|
|
607
|
+
this._count = value;
|
|
608
|
+
}
|
|
609
|
+
get familyPosition() {
|
|
610
|
+
if (!this.parent) {
|
|
611
|
+
return this.left || this.right ? "ROOT" : "ISOLATED";
|
|
612
|
+
}
|
|
613
|
+
if (this.parent.left === this) {
|
|
614
|
+
return this.left || this.right ? "ROOT_LEFT" : "LEFT";
|
|
615
|
+
} else if (this.parent.right === this) {
|
|
616
|
+
return this.left || this.right ? "ROOT_RIGHT" : "RIGHT";
|
|
617
|
+
}
|
|
618
|
+
return "MAL_NODE";
|
|
619
|
+
}
|
|
620
|
+
};
|
|
621
|
+
var BinaryTree = class extends IterableEntryBase {
|
|
622
|
+
static {
|
|
623
|
+
__name(this, "BinaryTree");
|
|
624
|
+
}
|
|
625
|
+
iterationType = "ITERATIVE";
|
|
626
|
+
constructor(keysNodesEntriesOrRaws = [], options) {
|
|
627
|
+
super();
|
|
628
|
+
if (options) {
|
|
629
|
+
const { iterationType, toEntryFn, isMapMode, isDuplicate } = options;
|
|
630
|
+
if (iterationType) this.iterationType = iterationType;
|
|
631
|
+
if (isMapMode !== void 0) this._isMapMode = isMapMode;
|
|
632
|
+
if (isDuplicate !== void 0) this._isDuplicate = isDuplicate;
|
|
633
|
+
if (typeof toEntryFn === "function") this._toEntryFn = toEntryFn;
|
|
634
|
+
else if (toEntryFn) throw TypeError("toEntryFn must be a function type");
|
|
635
|
+
}
|
|
636
|
+
if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
|
|
637
|
+
}
|
|
638
|
+
_isMapMode = true;
|
|
639
|
+
get isMapMode() {
|
|
640
|
+
return this._isMapMode;
|
|
641
|
+
}
|
|
642
|
+
_isDuplicate = false;
|
|
643
|
+
get isDuplicate() {
|
|
644
|
+
return this._isDuplicate;
|
|
645
|
+
}
|
|
646
|
+
_store = new Map();
|
|
647
|
+
get store() {
|
|
648
|
+
return this._store;
|
|
649
|
+
}
|
|
650
|
+
_root;
|
|
651
|
+
get root() {
|
|
652
|
+
return this._root;
|
|
653
|
+
}
|
|
654
|
+
_size = 0;
|
|
655
|
+
get size() {
|
|
656
|
+
return this._size;
|
|
657
|
+
}
|
|
658
|
+
_NIL = new BinaryTreeNode(NaN);
|
|
659
|
+
get NIL() {
|
|
660
|
+
return this._NIL;
|
|
661
|
+
}
|
|
662
|
+
_toEntryFn;
|
|
663
|
+
get toEntryFn() {
|
|
664
|
+
return this._toEntryFn;
|
|
665
|
+
}
|
|
666
|
+
createNode(key, value) {
|
|
667
|
+
return new BinaryTreeNode(key, this._isMapMode ? void 0 : value);
|
|
668
|
+
}
|
|
669
|
+
createTree(options) {
|
|
670
|
+
return this._createInstance(options);
|
|
671
|
+
}
|
|
672
|
+
ensureNode(keyNodeOrEntry, iterationType = this.iterationType) {
|
|
673
|
+
if (keyNodeOrEntry === null) return null;
|
|
674
|
+
if (keyNodeOrEntry === void 0) return;
|
|
675
|
+
if (keyNodeOrEntry === this._NIL) return;
|
|
676
|
+
if (this.isNode(keyNodeOrEntry)) return keyNodeOrEntry;
|
|
677
|
+
if (this.isEntry(keyNodeOrEntry)) {
|
|
678
|
+
const key = keyNodeOrEntry[0];
|
|
679
|
+
if (key === null) return null;
|
|
680
|
+
if (key === void 0) return;
|
|
681
|
+
return this.getNode(key, this._root, iterationType);
|
|
682
|
+
}
|
|
683
|
+
return this.getNode(keyNodeOrEntry, this._root, iterationType);
|
|
684
|
+
}
|
|
685
|
+
isNode(keyNodeOrEntry) {
|
|
686
|
+
return keyNodeOrEntry instanceof BinaryTreeNode;
|
|
687
|
+
}
|
|
688
|
+
isRaw(keyNodeEntryOrRaw) {
|
|
689
|
+
return this._toEntryFn !== void 0 && typeof keyNodeEntryOrRaw === "object";
|
|
690
|
+
}
|
|
691
|
+
isRealNode(keyNodeOrEntry) {
|
|
692
|
+
if (keyNodeOrEntry === this._NIL || keyNodeOrEntry === null || keyNodeOrEntry === void 0) return false;
|
|
693
|
+
return this.isNode(keyNodeOrEntry);
|
|
694
|
+
}
|
|
695
|
+
isRealNodeOrNull(keyNodeOrEntry) {
|
|
696
|
+
return keyNodeOrEntry === null || this.isRealNode(keyNodeOrEntry);
|
|
697
|
+
}
|
|
698
|
+
isNIL(keyNodeOrEntry) {
|
|
699
|
+
return keyNodeOrEntry === this._NIL;
|
|
700
|
+
}
|
|
701
|
+
isRange(keyNodeEntryOrPredicate) {
|
|
702
|
+
return keyNodeEntryOrPredicate instanceof Range;
|
|
703
|
+
}
|
|
704
|
+
isLeaf(keyNodeOrEntry) {
|
|
705
|
+
keyNodeOrEntry = this.ensureNode(keyNodeOrEntry);
|
|
706
|
+
if (keyNodeOrEntry === void 0) return false;
|
|
707
|
+
if (keyNodeOrEntry === null) return true;
|
|
708
|
+
return !this.isRealNode(keyNodeOrEntry.left) && !this.isRealNode(keyNodeOrEntry.right);
|
|
709
|
+
}
|
|
710
|
+
isEntry(keyNodeOrEntry) {
|
|
711
|
+
return Array.isArray(keyNodeOrEntry) && keyNodeOrEntry.length === 2;
|
|
712
|
+
}
|
|
713
|
+
isValidKey(key) {
|
|
714
|
+
if (key === null) return true;
|
|
715
|
+
return isComparable(key);
|
|
716
|
+
}
|
|
717
|
+
add(keyNodeOrEntry) {
|
|
718
|
+
return this.set(keyNodeOrEntry);
|
|
719
|
+
}
|
|
720
|
+
set(keyNodeOrEntry, value) {
|
|
721
|
+
const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
|
|
722
|
+
if (newNode === void 0) return false;
|
|
723
|
+
if (!this._root) {
|
|
724
|
+
this._setRoot(newNode);
|
|
725
|
+
if (this._isMapMode) this._setValue(newNode?.key, newValue);
|
|
726
|
+
this._size = 1;
|
|
727
|
+
return true;
|
|
728
|
+
}
|
|
729
|
+
const queue = new Queue([this._root]);
|
|
730
|
+
let potentialParent;
|
|
731
|
+
while (queue.length > 0) {
|
|
732
|
+
const cur = queue.shift();
|
|
733
|
+
if (!cur) continue;
|
|
734
|
+
if (!this._isDuplicate) {
|
|
735
|
+
if (newNode !== null && cur.key === newNode.key) {
|
|
736
|
+
this._replaceNode(cur, newNode);
|
|
737
|
+
if (this._isMapMode) this._setValue(cur.key, newValue);
|
|
738
|
+
return true;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
if (potentialParent === void 0 && (cur.left === void 0 || cur.right === void 0)) {
|
|
742
|
+
potentialParent = cur;
|
|
743
|
+
}
|
|
744
|
+
if (cur.left !== null) {
|
|
745
|
+
if (cur.left) queue.push(cur.left);
|
|
746
|
+
}
|
|
747
|
+
if (cur.right !== null) {
|
|
748
|
+
if (cur.right) queue.push(cur.right);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
if (potentialParent) {
|
|
752
|
+
if (potentialParent.left === void 0) {
|
|
753
|
+
potentialParent.left = newNode;
|
|
754
|
+
} else if (potentialParent.right === void 0) {
|
|
755
|
+
potentialParent.right = newNode;
|
|
756
|
+
}
|
|
757
|
+
if (this._isMapMode) this._setValue(newNode?.key, newValue);
|
|
758
|
+
this._size++;
|
|
759
|
+
return true;
|
|
760
|
+
}
|
|
761
|
+
return false;
|
|
762
|
+
}
|
|
763
|
+
addMany(keysNodesEntriesOrRaws) {
|
|
764
|
+
return this.setMany(keysNodesEntriesOrRaws);
|
|
765
|
+
}
|
|
766
|
+
setMany(keysNodesEntriesOrRaws, values) {
|
|
767
|
+
const inserted = [];
|
|
768
|
+
let valuesIterator;
|
|
769
|
+
if (values) {
|
|
770
|
+
valuesIterator = values[Symbol.iterator]();
|
|
771
|
+
}
|
|
772
|
+
for (let keyNodeEntryOrRaw of keysNodesEntriesOrRaws) {
|
|
773
|
+
let value = void 0;
|
|
774
|
+
if (valuesIterator) {
|
|
775
|
+
const valueResult = valuesIterator.next();
|
|
776
|
+
if (!valueResult.done) {
|
|
777
|
+
value = valueResult.value;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
if (this.isRaw(keyNodeEntryOrRaw)) keyNodeEntryOrRaw = this._toEntryFn(keyNodeEntryOrRaw);
|
|
781
|
+
inserted.push(this.set(keyNodeEntryOrRaw, value));
|
|
782
|
+
}
|
|
783
|
+
return inserted;
|
|
784
|
+
}
|
|
785
|
+
merge(anotherTree) {
|
|
786
|
+
this.setMany(anotherTree, []);
|
|
787
|
+
}
|
|
788
|
+
refill(keysNodesEntriesOrRaws, values) {
|
|
789
|
+
this.clear();
|
|
790
|
+
this.setMany(keysNodesEntriesOrRaws, values);
|
|
791
|
+
}
|
|
792
|
+
delete(keyNodeOrEntry) {
|
|
793
|
+
const deletedResult = [];
|
|
794
|
+
if (!this._root) return deletedResult;
|
|
795
|
+
const curr = this.getNode(keyNodeOrEntry);
|
|
796
|
+
if (!curr) return deletedResult;
|
|
797
|
+
const parent = curr?.parent;
|
|
798
|
+
let needBalanced;
|
|
799
|
+
let orgCurrent = curr;
|
|
800
|
+
if (!curr.left && !curr.right && !parent) {
|
|
801
|
+
this._setRoot(void 0);
|
|
802
|
+
} else if (curr.left) {
|
|
803
|
+
const leftSubTreeRightMost = this.getRightMost((node) => node, curr.left);
|
|
804
|
+
if (leftSubTreeRightMost) {
|
|
805
|
+
const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
|
|
806
|
+
orgCurrent = this._swapProperties(curr, leftSubTreeRightMost);
|
|
807
|
+
if (parentOfLeftSubTreeMax) {
|
|
808
|
+
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
|
|
809
|
+
parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
|
|
810
|
+
else parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left;
|
|
811
|
+
needBalanced = parentOfLeftSubTreeMax;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
} else if (parent) {
|
|
815
|
+
const { familyPosition: fp } = curr;
|
|
816
|
+
if (fp === "LEFT" || fp === "ROOT_LEFT") {
|
|
817
|
+
parent.left = curr.right;
|
|
818
|
+
} else if (fp === "RIGHT" || fp === "ROOT_RIGHT") {
|
|
819
|
+
parent.right = curr.right;
|
|
820
|
+
}
|
|
821
|
+
needBalanced = parent;
|
|
822
|
+
} else {
|
|
823
|
+
this._setRoot(curr.right);
|
|
824
|
+
curr.right = void 0;
|
|
825
|
+
}
|
|
826
|
+
this._size = this._size - 1;
|
|
827
|
+
deletedResult.push({ deleted: orgCurrent, needBalanced });
|
|
828
|
+
if (this._isMapMode && orgCurrent) this._store.delete(orgCurrent.key);
|
|
829
|
+
return deletedResult;
|
|
830
|
+
}
|
|
831
|
+
search(keyNodeEntryOrPredicate, onlyOne = false, callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType) {
|
|
832
|
+
if (keyNodeEntryOrPredicate === void 0) return [];
|
|
833
|
+
if (keyNodeEntryOrPredicate === null) return [];
|
|
834
|
+
startNode = this.ensureNode(startNode);
|
|
835
|
+
if (!startNode) return [];
|
|
836
|
+
const predicate = this._ensurePredicate(keyNodeEntryOrPredicate);
|
|
837
|
+
const ans = [];
|
|
838
|
+
if (iterationType === "RECURSIVE") {
|
|
839
|
+
const dfs = __name((cur) => {
|
|
840
|
+
if (predicate(cur)) {
|
|
841
|
+
ans.push(callback(cur));
|
|
842
|
+
if (onlyOne) return;
|
|
843
|
+
}
|
|
844
|
+
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
|
|
845
|
+
if (this.isRealNode(cur.left)) dfs(cur.left);
|
|
846
|
+
if (this.isRealNode(cur.right)) dfs(cur.right);
|
|
847
|
+
}, "dfs");
|
|
848
|
+
dfs(startNode);
|
|
849
|
+
} else {
|
|
850
|
+
const stack = [startNode];
|
|
851
|
+
while (stack.length > 0) {
|
|
852
|
+
const cur = stack.pop();
|
|
853
|
+
if (this.isRealNode(cur)) {
|
|
854
|
+
if (predicate(cur)) {
|
|
855
|
+
ans.push(callback(cur));
|
|
856
|
+
if (onlyOne) return ans;
|
|
857
|
+
}
|
|
858
|
+
if (this.isRealNode(cur.left)) stack.push(cur.left);
|
|
859
|
+
if (this.isRealNode(cur.right)) stack.push(cur.right);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
return ans;
|
|
864
|
+
}
|
|
865
|
+
getNodes(keyNodeEntryOrPredicate, onlyOne = false, startNode = this._root, iterationType = this.iterationType) {
|
|
866
|
+
return this.search(keyNodeEntryOrPredicate, onlyOne, (node) => node, startNode, iterationType);
|
|
867
|
+
}
|
|
868
|
+
getNode(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
869
|
+
return this.search(keyNodeEntryOrPredicate, true, (node) => node, startNode, iterationType)[0];
|
|
870
|
+
}
|
|
871
|
+
get(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
872
|
+
if (this._isMapMode) {
|
|
873
|
+
const key = this._extractKey(keyNodeEntryOrPredicate);
|
|
874
|
+
if (key === null || key === void 0) return;
|
|
875
|
+
return this._store.get(key);
|
|
876
|
+
}
|
|
877
|
+
return this.getNode(keyNodeEntryOrPredicate, startNode, iterationType)?.value;
|
|
878
|
+
}
|
|
879
|
+
has(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
880
|
+
return this.search(keyNodeEntryOrPredicate, true, (node) => node, startNode, iterationType).length > 0;
|
|
881
|
+
}
|
|
882
|
+
clear() {
|
|
883
|
+
this._clearNodes();
|
|
884
|
+
if (this._isMapMode) this._clearValues();
|
|
885
|
+
}
|
|
886
|
+
isEmpty() {
|
|
887
|
+
return this._size === 0;
|
|
888
|
+
}
|
|
889
|
+
isPerfectlyBalanced(startNode = this._root) {
|
|
890
|
+
return this.getMinHeight(startNode) + 1 >= this.getHeight(startNode);
|
|
891
|
+
}
|
|
892
|
+
isBST(startNode = this._root, iterationType = this.iterationType) {
|
|
893
|
+
const startNodeSired = this.ensureNode(startNode);
|
|
894
|
+
if (!startNodeSired) return true;
|
|
895
|
+
if (iterationType === "RECURSIVE") {
|
|
896
|
+
const dfs = __name((cur, min, max) => {
|
|
897
|
+
if (!this.isRealNode(cur)) return true;
|
|
898
|
+
const numKey = Number(cur.key);
|
|
899
|
+
if (numKey <= min || numKey >= max) return false;
|
|
900
|
+
return dfs(cur.left, min, numKey) && dfs(cur.right, numKey, max);
|
|
901
|
+
}, "dfs");
|
|
902
|
+
const isStandardBST = dfs(startNodeSired, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
|
|
903
|
+
const isInverseBST = dfs(startNodeSired, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER);
|
|
904
|
+
return isStandardBST || isInverseBST;
|
|
905
|
+
} else {
|
|
906
|
+
const checkBST = __name((checkMax = false) => {
|
|
907
|
+
const stack = [];
|
|
908
|
+
let prev = checkMax ? Number.MAX_SAFE_INTEGER : Number.MIN_SAFE_INTEGER;
|
|
909
|
+
let curr = startNodeSired;
|
|
910
|
+
while (this.isRealNode(curr) || stack.length > 0) {
|
|
911
|
+
while (this.isRealNode(curr)) {
|
|
912
|
+
stack.push(curr);
|
|
913
|
+
curr = curr.left;
|
|
914
|
+
}
|
|
915
|
+
curr = stack.pop();
|
|
916
|
+
const numKey = Number(curr.key);
|
|
917
|
+
if (!this.isRealNode(curr) || !checkMax && prev >= numKey || checkMax && prev <= numKey) return false;
|
|
918
|
+
prev = numKey;
|
|
919
|
+
curr = curr.right;
|
|
920
|
+
}
|
|
921
|
+
return true;
|
|
922
|
+
}, "checkBST");
|
|
923
|
+
const isStandardBST = checkBST(false);
|
|
924
|
+
const isInverseBST = checkBST(true);
|
|
925
|
+
return isStandardBST || isInverseBST;
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
getDepth(dist, startNode = this._root) {
|
|
929
|
+
let distEnsured = this.ensureNode(dist);
|
|
930
|
+
const beginRootEnsured = this.ensureNode(startNode);
|
|
931
|
+
let depth = 0;
|
|
932
|
+
while (distEnsured?.parent) {
|
|
933
|
+
if (distEnsured === beginRootEnsured) {
|
|
934
|
+
return depth;
|
|
935
|
+
}
|
|
936
|
+
depth++;
|
|
937
|
+
distEnsured = distEnsured.parent;
|
|
938
|
+
}
|
|
939
|
+
return depth;
|
|
940
|
+
}
|
|
941
|
+
getHeight(startNode = this._root, iterationType = this.iterationType) {
|
|
942
|
+
startNode = this.ensureNode(startNode);
|
|
943
|
+
if (!this.isRealNode(startNode)) return -1;
|
|
944
|
+
if (iterationType === "RECURSIVE") {
|
|
945
|
+
const _getMaxHeight = __name((cur) => {
|
|
946
|
+
if (!this.isRealNode(cur)) return -1;
|
|
947
|
+
const leftHeight = _getMaxHeight(cur.left);
|
|
948
|
+
const rightHeight = _getMaxHeight(cur.right);
|
|
949
|
+
return Math.max(leftHeight, rightHeight) + 1;
|
|
950
|
+
}, "_getMaxHeight");
|
|
951
|
+
return _getMaxHeight(startNode);
|
|
952
|
+
} else {
|
|
953
|
+
const stack = [{ node: startNode, depth: 0 }];
|
|
954
|
+
let maxHeight = 0;
|
|
955
|
+
while (stack.length > 0) {
|
|
956
|
+
const { node, depth } = stack.pop();
|
|
957
|
+
if (this.isRealNode(node.left)) stack.push({ node: node.left, depth: depth + 1 });
|
|
958
|
+
if (this.isRealNode(node.right)) stack.push({ node: node.right, depth: depth + 1 });
|
|
959
|
+
maxHeight = Math.max(maxHeight, depth);
|
|
960
|
+
}
|
|
961
|
+
return maxHeight;
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
getMinHeight(startNode = this._root, iterationType = this.iterationType) {
|
|
965
|
+
startNode = this.ensureNode(startNode);
|
|
966
|
+
if (!startNode) return -1;
|
|
967
|
+
if (iterationType === "RECURSIVE") {
|
|
968
|
+
const _getMinHeight = __name((cur) => {
|
|
969
|
+
if (!this.isRealNode(cur)) return 0;
|
|
970
|
+
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return 0;
|
|
971
|
+
const leftMinHeight = _getMinHeight(cur.left);
|
|
972
|
+
const rightMinHeight = _getMinHeight(cur.right);
|
|
973
|
+
return Math.min(leftMinHeight, rightMinHeight) + 1;
|
|
974
|
+
}, "_getMinHeight");
|
|
975
|
+
return _getMinHeight(startNode);
|
|
976
|
+
} else {
|
|
977
|
+
const stack = [];
|
|
978
|
+
let node = startNode, last = null;
|
|
979
|
+
const depths = new Map();
|
|
980
|
+
while (stack.length > 0 || node) {
|
|
981
|
+
if (this.isRealNode(node)) {
|
|
982
|
+
stack.push(node);
|
|
983
|
+
node = node.left;
|
|
984
|
+
} else {
|
|
985
|
+
node = stack[stack.length - 1];
|
|
986
|
+
if (!this.isRealNode(node.right) || last === node.right) {
|
|
987
|
+
node = stack.pop();
|
|
988
|
+
if (this.isRealNode(node)) {
|
|
989
|
+
const leftMinHeight = this.isRealNode(node.left) ? depths.get(node.left) : -1;
|
|
990
|
+
const rightMinHeight = this.isRealNode(node.right) ? depths.get(node.right) : -1;
|
|
991
|
+
depths.set(node, 1 + Math.min(leftMinHeight, rightMinHeight));
|
|
992
|
+
last = node;
|
|
993
|
+
node = null;
|
|
994
|
+
}
|
|
995
|
+
} else node = node.right;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
return depths.get(startNode);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
getPathToRoot(beginNode, callback = this._DEFAULT_NODE_CALLBACK, isReverse = false) {
|
|
1002
|
+
const result = [];
|
|
1003
|
+
let beginNodeEnsured = this.ensureNode(beginNode);
|
|
1004
|
+
if (!beginNodeEnsured) return result;
|
|
1005
|
+
while (beginNodeEnsured.parent) {
|
|
1006
|
+
result.push(callback(beginNodeEnsured));
|
|
1007
|
+
beginNodeEnsured = beginNodeEnsured.parent;
|
|
1008
|
+
}
|
|
1009
|
+
result.push(callback(beginNodeEnsured));
|
|
1010
|
+
return isReverse ? result.reverse() : result;
|
|
1011
|
+
}
|
|
1012
|
+
getLeftMost(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType) {
|
|
1013
|
+
if (this.isNIL(startNode)) return callback(void 0);
|
|
1014
|
+
const ensuredStartNode = this.ensureNode(startNode);
|
|
1015
|
+
if (!this.isRealNode(ensuredStartNode)) return callback(void 0);
|
|
1016
|
+
if (iterationType === "RECURSIVE") {
|
|
1017
|
+
const dfs = __name((cur) => {
|
|
1018
|
+
const { left } = cur;
|
|
1019
|
+
if (!this.isRealNode(left)) return cur;
|
|
1020
|
+
return dfs(left);
|
|
1021
|
+
}, "dfs");
|
|
1022
|
+
return callback(dfs(ensuredStartNode));
|
|
1023
|
+
} else {
|
|
1024
|
+
const dfs = makeTrampoline((cur) => {
|
|
1025
|
+
const { left } = cur;
|
|
1026
|
+
if (!this.isRealNode(left)) return cur;
|
|
1027
|
+
return makeTrampolineThunk(() => dfs(left));
|
|
1028
|
+
});
|
|
1029
|
+
return callback(dfs(ensuredStartNode));
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
getRightMost(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType) {
|
|
1033
|
+
if (this.isNIL(startNode)) return callback(void 0);
|
|
1034
|
+
startNode = this.ensureNode(startNode);
|
|
1035
|
+
if (!startNode) return callback(void 0);
|
|
1036
|
+
if (iterationType === "RECURSIVE") {
|
|
1037
|
+
const dfs = __name((cur) => {
|
|
1038
|
+
const { right } = cur;
|
|
1039
|
+
if (!this.isRealNode(right)) return cur;
|
|
1040
|
+
return dfs(right);
|
|
1041
|
+
}, "dfs");
|
|
1042
|
+
return callback(dfs(startNode));
|
|
1043
|
+
} else {
|
|
1044
|
+
const dfs = makeTrampoline((cur) => {
|
|
1045
|
+
const { right } = cur;
|
|
1046
|
+
if (!this.isRealNode(right)) return cur;
|
|
1047
|
+
return makeTrampolineThunk(() => dfs(right));
|
|
1048
|
+
});
|
|
1049
|
+
return callback(dfs(startNode));
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
getPredecessor(node) {
|
|
1053
|
+
if (this.isRealNode(node.left)) {
|
|
1054
|
+
let predecessor = node.left;
|
|
1055
|
+
while (!this.isRealNode(predecessor) || this.isRealNode(predecessor.right) && predecessor.right !== node) {
|
|
1056
|
+
if (this.isRealNode(predecessor)) {
|
|
1057
|
+
predecessor = predecessor.right;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
return predecessor;
|
|
1061
|
+
} else {
|
|
1062
|
+
return node;
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
getSuccessor(x) {
|
|
1066
|
+
x = this.ensureNode(x);
|
|
1067
|
+
if (!this.isRealNode(x)) return void 0;
|
|
1068
|
+
if (this.isRealNode(x.right)) {
|
|
1069
|
+
return this.getLeftMost((node) => node, x.right);
|
|
1070
|
+
}
|
|
1071
|
+
let y = x.parent;
|
|
1072
|
+
while (this.isRealNode(y) && x === y.right) {
|
|
1073
|
+
x = y;
|
|
1074
|
+
y = y.parent;
|
|
1075
|
+
}
|
|
1076
|
+
return y;
|
|
1077
|
+
}
|
|
1078
|
+
dfs(callback = this._DEFAULT_NODE_CALLBACK, pattern = "IN", onlyOne = false, startNode = this._root, iterationType = this.iterationType, includeNull = false) {
|
|
1079
|
+
startNode = this.ensureNode(startNode);
|
|
1080
|
+
if (!startNode) return [];
|
|
1081
|
+
return this._dfs(callback, pattern, onlyOne, startNode, iterationType, includeNull);
|
|
1082
|
+
}
|
|
1083
|
+
bfs(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType, includeNull = false) {
|
|
1084
|
+
startNode = this.ensureNode(startNode);
|
|
1085
|
+
if (!startNode) return [];
|
|
1086
|
+
const ans = [];
|
|
1087
|
+
if (iterationType === "RECURSIVE") {
|
|
1088
|
+
const queue = new Queue([
|
|
1089
|
+
startNode
|
|
1090
|
+
]);
|
|
1091
|
+
const dfs = __name((level) => {
|
|
1092
|
+
if (queue.length === 0) return;
|
|
1093
|
+
const current = queue.shift();
|
|
1094
|
+
ans.push(callback(current));
|
|
1095
|
+
if (includeNull) {
|
|
1096
|
+
if (current && this.isRealNodeOrNull(current.left)) queue.push(current.left);
|
|
1097
|
+
if (current && this.isRealNodeOrNull(current.right)) queue.push(current.right);
|
|
1098
|
+
} else {
|
|
1099
|
+
if (this.isRealNode(current.left)) queue.push(current.left);
|
|
1100
|
+
if (this.isRealNode(current.right)) queue.push(current.right);
|
|
1101
|
+
}
|
|
1102
|
+
dfs(level + 1);
|
|
1103
|
+
}, "dfs");
|
|
1104
|
+
dfs(0);
|
|
1105
|
+
} else {
|
|
1106
|
+
const queue = new Queue([startNode]);
|
|
1107
|
+
while (queue.length > 0) {
|
|
1108
|
+
const levelSize = queue.length;
|
|
1109
|
+
for (let i = 0; i < levelSize; i++) {
|
|
1110
|
+
const current = queue.shift();
|
|
1111
|
+
ans.push(callback(current));
|
|
1112
|
+
if (includeNull) {
|
|
1113
|
+
if (current && this.isRealNodeOrNull(current.left)) queue.push(current.left);
|
|
1114
|
+
if (current && this.isRealNodeOrNull(current.right)) queue.push(current.right);
|
|
1115
|
+
} else {
|
|
1116
|
+
if (this.isRealNode(current.left)) queue.push(current.left);
|
|
1117
|
+
if (this.isRealNode(current.right)) queue.push(current.right);
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
return ans;
|
|
1123
|
+
}
|
|
1124
|
+
leaves(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType) {
|
|
1125
|
+
startNode = this.ensureNode(startNode);
|
|
1126
|
+
const leaves = [];
|
|
1127
|
+
if (!this.isRealNode(startNode)) return [];
|
|
1128
|
+
if (iterationType === "RECURSIVE") {
|
|
1129
|
+
const dfs = __name((cur) => {
|
|
1130
|
+
if (this.isLeaf(cur)) {
|
|
1131
|
+
leaves.push(callback(cur));
|
|
1132
|
+
}
|
|
1133
|
+
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
|
|
1134
|
+
if (this.isRealNode(cur.left)) dfs(cur.left);
|
|
1135
|
+
if (this.isRealNode(cur.right)) dfs(cur.right);
|
|
1136
|
+
}, "dfs");
|
|
1137
|
+
dfs(startNode);
|
|
1138
|
+
} else {
|
|
1139
|
+
const queue = new Queue([startNode]);
|
|
1140
|
+
while (queue.length > 0) {
|
|
1141
|
+
const cur = queue.shift();
|
|
1142
|
+
if (this.isRealNode(cur)) {
|
|
1143
|
+
if (this.isLeaf(cur)) {
|
|
1144
|
+
leaves.push(callback(cur));
|
|
1145
|
+
}
|
|
1146
|
+
if (this.isRealNode(cur.left)) queue.push(cur.left);
|
|
1147
|
+
if (this.isRealNode(cur.right)) queue.push(cur.right);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
return leaves;
|
|
1152
|
+
}
|
|
1153
|
+
listLevels(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType, includeNull = false) {
|
|
1154
|
+
startNode = this.ensureNode(startNode);
|
|
1155
|
+
const levelsNodes = [];
|
|
1156
|
+
if (!startNode) return levelsNodes;
|
|
1157
|
+
if (iterationType === "RECURSIVE") {
|
|
1158
|
+
const _recursive = __name((node, level) => {
|
|
1159
|
+
if (!levelsNodes[level]) levelsNodes[level] = [];
|
|
1160
|
+
levelsNodes[level].push(callback(node));
|
|
1161
|
+
if (includeNull) {
|
|
1162
|
+
if (node && this.isRealNodeOrNull(node.left)) _recursive(node.left, level + 1);
|
|
1163
|
+
if (node && this.isRealNodeOrNull(node.right)) _recursive(node.right, level + 1);
|
|
1164
|
+
} else {
|
|
1165
|
+
if (node && node.left) _recursive(node.left, level + 1);
|
|
1166
|
+
if (node && node.right) _recursive(node.right, level + 1);
|
|
1167
|
+
}
|
|
1168
|
+
}, "_recursive");
|
|
1169
|
+
_recursive(startNode, 0);
|
|
1170
|
+
} else {
|
|
1171
|
+
const stack = [[startNode, 0]];
|
|
1172
|
+
while (stack.length > 0) {
|
|
1173
|
+
const head = stack.pop();
|
|
1174
|
+
const [node, level] = head;
|
|
1175
|
+
if (!levelsNodes[level]) levelsNodes[level] = [];
|
|
1176
|
+
levelsNodes[level].push(callback(node));
|
|
1177
|
+
if (includeNull) {
|
|
1178
|
+
if (node && this.isRealNodeOrNull(node.right)) stack.push([node.right, level + 1]);
|
|
1179
|
+
if (node && this.isRealNodeOrNull(node.left)) stack.push([node.left, level + 1]);
|
|
1180
|
+
} else {
|
|
1181
|
+
if (node && node.right) stack.push([node.right, level + 1]);
|
|
1182
|
+
if (node && node.left) stack.push([node.left, level + 1]);
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
return levelsNodes;
|
|
1187
|
+
}
|
|
1188
|
+
morris(callback = this._DEFAULT_NODE_CALLBACK, pattern = "IN", startNode = this._root) {
|
|
1189
|
+
startNode = this.ensureNode(startNode);
|
|
1190
|
+
if (!startNode) return [];
|
|
1191
|
+
const ans = [];
|
|
1192
|
+
let cur = startNode;
|
|
1193
|
+
const _reverseEdge = __name((node) => {
|
|
1194
|
+
let pre = null;
|
|
1195
|
+
let next = null;
|
|
1196
|
+
while (node) {
|
|
1197
|
+
next = node.right;
|
|
1198
|
+
node.right = pre;
|
|
1199
|
+
pre = node;
|
|
1200
|
+
node = next;
|
|
1201
|
+
}
|
|
1202
|
+
return pre;
|
|
1203
|
+
}, "_reverseEdge");
|
|
1204
|
+
const _printEdge = __name((node) => {
|
|
1205
|
+
const tail = _reverseEdge(node);
|
|
1206
|
+
let cur2 = tail;
|
|
1207
|
+
while (cur2) {
|
|
1208
|
+
ans.push(callback(cur2));
|
|
1209
|
+
cur2 = cur2.right;
|
|
1210
|
+
}
|
|
1211
|
+
_reverseEdge(tail);
|
|
1212
|
+
}, "_printEdge");
|
|
1213
|
+
switch (pattern) {
|
|
1214
|
+
case "IN":
|
|
1215
|
+
while (cur) {
|
|
1216
|
+
if (cur.left) {
|
|
1217
|
+
const predecessor = this.getPredecessor(cur);
|
|
1218
|
+
if (!predecessor.right) {
|
|
1219
|
+
predecessor.right = cur;
|
|
1220
|
+
cur = cur.left;
|
|
1221
|
+
continue;
|
|
1222
|
+
} else {
|
|
1223
|
+
predecessor.right = null;
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
ans.push(callback(cur));
|
|
1227
|
+
cur = cur.right;
|
|
1228
|
+
}
|
|
1229
|
+
break;
|
|
1230
|
+
case "PRE":
|
|
1231
|
+
while (cur) {
|
|
1232
|
+
if (cur.left) {
|
|
1233
|
+
const predecessor = this.getPredecessor(cur);
|
|
1234
|
+
if (!predecessor.right) {
|
|
1235
|
+
predecessor.right = cur;
|
|
1236
|
+
ans.push(callback(cur));
|
|
1237
|
+
cur = cur.left;
|
|
1238
|
+
continue;
|
|
1239
|
+
} else {
|
|
1240
|
+
predecessor.right = null;
|
|
1241
|
+
}
|
|
1242
|
+
} else {
|
|
1243
|
+
ans.push(callback(cur));
|
|
1244
|
+
}
|
|
1245
|
+
cur = cur.right;
|
|
1246
|
+
}
|
|
1247
|
+
break;
|
|
1248
|
+
case "POST":
|
|
1249
|
+
while (cur) {
|
|
1250
|
+
if (cur.left) {
|
|
1251
|
+
const predecessor = this.getPredecessor(cur);
|
|
1252
|
+
if (predecessor.right === null) {
|
|
1253
|
+
predecessor.right = cur;
|
|
1254
|
+
cur = cur.left;
|
|
1255
|
+
continue;
|
|
1256
|
+
} else {
|
|
1257
|
+
predecessor.right = null;
|
|
1258
|
+
_printEdge(cur.left);
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
cur = cur.right;
|
|
1262
|
+
}
|
|
1263
|
+
_printEdge(startNode);
|
|
1264
|
+
break;
|
|
1265
|
+
}
|
|
1266
|
+
return ans;
|
|
1267
|
+
}
|
|
1268
|
+
clone() {
|
|
1269
|
+
const out = this._createInstance();
|
|
1270
|
+
this._clone(out);
|
|
1271
|
+
return out;
|
|
1272
|
+
}
|
|
1273
|
+
filter(predicate, thisArg) {
|
|
1274
|
+
const out = this._createInstance();
|
|
1275
|
+
let i = 0;
|
|
1276
|
+
for (const [k, v] of this) if (predicate.call(thisArg, v, k, i++, this)) out.set([k, v]);
|
|
1277
|
+
return out;
|
|
1278
|
+
}
|
|
1279
|
+
map(cb, options, thisArg) {
|
|
1280
|
+
const out = this._createLike([], options);
|
|
1281
|
+
let i = 0;
|
|
1282
|
+
for (const [k, v] of this) out.set(cb.call(thisArg, v, k, i++, this));
|
|
1283
|
+
return out;
|
|
1284
|
+
}
|
|
1285
|
+
toVisual(startNode = this._root, options) {
|
|
1286
|
+
const opts = { isShowUndefined: false, isShowNull: true, isShowRedBlackNIL: false, ...options };
|
|
1287
|
+
startNode = this.ensureNode(startNode);
|
|
1288
|
+
let output = "";
|
|
1289
|
+
if (!startNode) return output;
|
|
1290
|
+
if (opts.isShowUndefined) output += `U for undefined
|
|
1291
|
+
`;
|
|
1292
|
+
if (opts.isShowNull) output += `N for null
|
|
1293
|
+
`;
|
|
1294
|
+
if (opts.isShowRedBlackNIL) output += `S for Sentinel Node(NIL)
|
|
1295
|
+
`;
|
|
1296
|
+
const display = __name((root) => {
|
|
1297
|
+
const [lines] = this._displayAux(root, opts);
|
|
1298
|
+
let paragraph = "";
|
|
1299
|
+
for (const line of lines) {
|
|
1300
|
+
paragraph += line + "\n";
|
|
1301
|
+
}
|
|
1302
|
+
output += paragraph;
|
|
1303
|
+
}, "display");
|
|
1304
|
+
display(startNode);
|
|
1305
|
+
return output;
|
|
1306
|
+
}
|
|
1307
|
+
print(options, startNode = this._root) {
|
|
1308
|
+
console.log(this.toVisual(startNode, options));
|
|
1309
|
+
}
|
|
1310
|
+
_dfs(callback = this._DEFAULT_NODE_CALLBACK, pattern = "IN", onlyOne = false, startNode = this._root, iterationType = this.iterationType, includeNull = false, shouldVisitLeft = (node) => !!node, shouldVisitRight = (node) => !!node, shouldVisitRoot = (node) => {
|
|
1311
|
+
if (includeNull) return this.isRealNodeOrNull(node);
|
|
1312
|
+
return this.isRealNode(node);
|
|
1313
|
+
}, shouldProcessRoot = (node) => this.isRealNodeOrNull(node)) {
|
|
1314
|
+
startNode = this.ensureNode(startNode);
|
|
1315
|
+
if (!startNode) return [];
|
|
1316
|
+
const ans = [];
|
|
1317
|
+
if (iterationType === "RECURSIVE") {
|
|
1318
|
+
const dfs = __name((node) => {
|
|
1319
|
+
if (!shouldVisitRoot(node)) return;
|
|
1320
|
+
const visitLeft = __name(() => {
|
|
1321
|
+
if (shouldVisitLeft(node) && node?.left !== void 0) dfs(node?.left);
|
|
1322
|
+
}, "visitLeft");
|
|
1323
|
+
const visitRight = __name(() => {
|
|
1324
|
+
if (shouldVisitRight(node) && node?.right !== void 0) dfs(node?.right);
|
|
1325
|
+
}, "visitRight");
|
|
1326
|
+
switch (pattern) {
|
|
1327
|
+
case "IN":
|
|
1328
|
+
visitLeft();
|
|
1329
|
+
if (shouldProcessRoot(node)) {
|
|
1330
|
+
ans.push(callback(node));
|
|
1331
|
+
if (onlyOne) return;
|
|
1332
|
+
}
|
|
1333
|
+
visitRight();
|
|
1334
|
+
break;
|
|
1335
|
+
case "PRE":
|
|
1336
|
+
if (shouldProcessRoot(node)) {
|
|
1337
|
+
ans.push(callback(node));
|
|
1338
|
+
if (onlyOne) return;
|
|
1339
|
+
}
|
|
1340
|
+
visitLeft();
|
|
1341
|
+
visitRight();
|
|
1342
|
+
break;
|
|
1343
|
+
case "POST":
|
|
1344
|
+
visitLeft();
|
|
1345
|
+
visitRight();
|
|
1346
|
+
if (shouldProcessRoot(node)) {
|
|
1347
|
+
ans.push(callback(node));
|
|
1348
|
+
if (onlyOne) return;
|
|
1349
|
+
}
|
|
1350
|
+
break;
|
|
1351
|
+
}
|
|
1352
|
+
}, "dfs");
|
|
1353
|
+
dfs(startNode);
|
|
1354
|
+
} else {
|
|
1355
|
+
const stack = [{ opt: 0 , node: startNode }];
|
|
1356
|
+
const pushLeft = __name((cur) => {
|
|
1357
|
+
if (shouldVisitLeft(cur.node)) stack.push({ opt: 0 , node: cur.node?.left });
|
|
1358
|
+
}, "pushLeft");
|
|
1359
|
+
const pushRight = __name((cur) => {
|
|
1360
|
+
if (shouldVisitRight(cur.node)) stack.push({ opt: 0 , node: cur.node?.right });
|
|
1361
|
+
}, "pushRight");
|
|
1362
|
+
const pushRoot = __name((cur) => {
|
|
1363
|
+
if (shouldVisitRoot(cur.node)) stack.push({ opt: 1 , node: cur.node });
|
|
1364
|
+
}, "pushRoot");
|
|
1365
|
+
while (stack.length > 0) {
|
|
1366
|
+
const cur = stack.pop();
|
|
1367
|
+
if (cur === void 0) continue;
|
|
1368
|
+
if (!shouldVisitRoot(cur.node)) continue;
|
|
1369
|
+
if (cur.opt === 1 ) {
|
|
1370
|
+
if (shouldProcessRoot(cur.node) && cur.node !== void 0) {
|
|
1371
|
+
ans.push(callback(cur.node));
|
|
1372
|
+
if (onlyOne) return ans;
|
|
1373
|
+
}
|
|
1374
|
+
} else {
|
|
1375
|
+
switch (pattern) {
|
|
1376
|
+
case "IN":
|
|
1377
|
+
pushRight(cur);
|
|
1378
|
+
pushRoot(cur);
|
|
1379
|
+
pushLeft(cur);
|
|
1380
|
+
break;
|
|
1381
|
+
case "PRE":
|
|
1382
|
+
pushRight(cur);
|
|
1383
|
+
pushLeft(cur);
|
|
1384
|
+
pushRoot(cur);
|
|
1385
|
+
break;
|
|
1386
|
+
case "POST":
|
|
1387
|
+
pushRoot(cur);
|
|
1388
|
+
pushRight(cur);
|
|
1389
|
+
pushLeft(cur);
|
|
1390
|
+
break;
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
return ans;
|
|
1396
|
+
}
|
|
1397
|
+
*_getIterator(node = this._root) {
|
|
1398
|
+
if (!node) return;
|
|
1399
|
+
if (this.iterationType === "ITERATIVE") {
|
|
1400
|
+
const stack = [];
|
|
1401
|
+
let current = node;
|
|
1402
|
+
while (current || stack.length > 0) {
|
|
1403
|
+
while (this.isRealNode(current)) {
|
|
1404
|
+
stack.push(current);
|
|
1405
|
+
current = current.left;
|
|
1406
|
+
}
|
|
1407
|
+
current = stack.pop();
|
|
1408
|
+
if (this.isRealNode(current)) {
|
|
1409
|
+
if (this._isMapMode) yield [current.key, this._store.get(current.key)];
|
|
1410
|
+
else yield [current.key, current.value];
|
|
1411
|
+
current = current.right;
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
} else {
|
|
1415
|
+
if (node.left && this.isRealNode(node)) {
|
|
1416
|
+
yield* this[Symbol.iterator](node.left);
|
|
1417
|
+
}
|
|
1418
|
+
if (this._isMapMode) yield [node.key, this._store.get(node.key)];
|
|
1419
|
+
else yield [node.key, node.value];
|
|
1420
|
+
if (node.right && this.isRealNode(node)) {
|
|
1421
|
+
yield* this[Symbol.iterator](node.right);
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
_DEFAULT_NODE_CALLBACK = __name((node) => node ? node.key : void 0, "_DEFAULT_NODE_CALLBACK");
|
|
1426
|
+
_snapshotOptions() {
|
|
1427
|
+
return {
|
|
1428
|
+
iterationType: this.iterationType,
|
|
1429
|
+
toEntryFn: this.toEntryFn,
|
|
1430
|
+
isMapMode: this.isMapMode,
|
|
1431
|
+
isDuplicate: this.isDuplicate
|
|
1432
|
+
};
|
|
1433
|
+
}
|
|
1434
|
+
_createInstance(options) {
|
|
1435
|
+
const Ctor = this.constructor;
|
|
1436
|
+
return new Ctor([], { ...this._snapshotOptions(), ...options ?? {} });
|
|
1437
|
+
}
|
|
1438
|
+
_createLike(iter = [], options) {
|
|
1439
|
+
const Ctor = this.constructor;
|
|
1440
|
+
return new Ctor(iter, { ...this._snapshotOptions(), ...options ?? {} });
|
|
1441
|
+
}
|
|
1442
|
+
_keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value) {
|
|
1443
|
+
if (keyNodeOrEntry === void 0) return [void 0, void 0];
|
|
1444
|
+
if (keyNodeOrEntry === null) return [null, void 0];
|
|
1445
|
+
if (this.isNode(keyNodeOrEntry)) return [keyNodeOrEntry, value];
|
|
1446
|
+
if (this.isEntry(keyNodeOrEntry)) {
|
|
1447
|
+
const [key, entryValue] = keyNodeOrEntry;
|
|
1448
|
+
if (key === void 0) return [void 0, void 0];
|
|
1449
|
+
else if (key === null) return [null, void 0];
|
|
1450
|
+
const finalValue = value ?? entryValue;
|
|
1451
|
+
return [this.createNode(key, finalValue), finalValue];
|
|
1452
|
+
}
|
|
1453
|
+
return [this.createNode(keyNodeOrEntry, value), value];
|
|
1454
|
+
}
|
|
1455
|
+
_clone(cloned) {
|
|
1456
|
+
this.bfs(
|
|
1457
|
+
(node) => {
|
|
1458
|
+
if (node === null) cloned.set(null);
|
|
1459
|
+
else {
|
|
1460
|
+
if (this._isMapMode) cloned.set([node.key, this._store.get(node.key)]);
|
|
1461
|
+
else cloned.set([node.key, node.value]);
|
|
1462
|
+
}
|
|
1463
|
+
},
|
|
1464
|
+
this._root,
|
|
1465
|
+
this.iterationType,
|
|
1466
|
+
true
|
|
1467
|
+
);
|
|
1468
|
+
if (this._isMapMode) cloned._store = this._store;
|
|
1469
|
+
}
|
|
1470
|
+
_displayAux(node, options) {
|
|
1471
|
+
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
1472
|
+
const emptyDisplayLayout = [["\u2500"], 1, 0, 0];
|
|
1473
|
+
if (node === null && !isShowNull) {
|
|
1474
|
+
return emptyDisplayLayout;
|
|
1475
|
+
} else if (node === void 0 && !isShowUndefined) {
|
|
1476
|
+
return emptyDisplayLayout;
|
|
1477
|
+
} else if (this.isNIL(node) && !isShowRedBlackNIL) {
|
|
1478
|
+
return emptyDisplayLayout;
|
|
1479
|
+
} else if (node !== null && node !== void 0) {
|
|
1480
|
+
const key = node.key, line = this.isNIL(node) ? "S" : String(key), width = line.length;
|
|
1481
|
+
return _buildNodeDisplay(
|
|
1482
|
+
line,
|
|
1483
|
+
width,
|
|
1484
|
+
this._displayAux(node.left, options),
|
|
1485
|
+
this._displayAux(node.right, options)
|
|
1486
|
+
);
|
|
1487
|
+
} else {
|
|
1488
|
+
const line = node === void 0 ? "U" : "N", width = line.length;
|
|
1489
|
+
return _buildNodeDisplay(line, width, [[""], 1, 0, 0], [[""], 1, 0, 0]);
|
|
1490
|
+
}
|
|
1491
|
+
function _buildNodeDisplay(line, width, left, right) {
|
|
1492
|
+
const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
|
|
1493
|
+
const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
|
|
1494
|
+
const firstLine = " ".repeat(Math.max(0, leftMiddle + 1)) + "_".repeat(Math.max(0, leftWidth - leftMiddle - 1)) + line + "_".repeat(Math.max(0, rightMiddle)) + " ".repeat(Math.max(0, rightWidth - rightMiddle));
|
|
1495
|
+
const secondLine = (leftHeight > 0 ? " ".repeat(leftMiddle) + "/" + " ".repeat(leftWidth - leftMiddle - 1) : " ".repeat(leftWidth)) + " ".repeat(width) + (rightHeight > 0 ? " ".repeat(rightMiddle) + "\\" + " ".repeat(rightWidth - rightMiddle - 1) : " ".repeat(rightWidth));
|
|
1496
|
+
const mergedLines = [firstLine, secondLine];
|
|
1497
|
+
for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
|
|
1498
|
+
const leftLine = i < leftHeight ? leftLines[i] : " ".repeat(leftWidth);
|
|
1499
|
+
const rightLine = i < rightHeight ? rightLines[i] : " ".repeat(rightWidth);
|
|
1500
|
+
mergedLines.push(leftLine + " ".repeat(width) + rightLine);
|
|
1501
|
+
}
|
|
1502
|
+
return [
|
|
1503
|
+
mergedLines,
|
|
1504
|
+
leftWidth + width + rightWidth,
|
|
1505
|
+
Math.max(leftHeight, rightHeight) + 2,
|
|
1506
|
+
leftWidth + Math.floor(width / 2)
|
|
1507
|
+
];
|
|
1508
|
+
}
|
|
1509
|
+
__name(_buildNodeDisplay, "_buildNodeDisplay");
|
|
1510
|
+
}
|
|
1511
|
+
_swapProperties(srcNode, destNode) {
|
|
1512
|
+
srcNode = this.ensureNode(srcNode);
|
|
1513
|
+
destNode = this.ensureNode(destNode);
|
|
1514
|
+
if (srcNode && destNode) {
|
|
1515
|
+
const { key, value } = destNode;
|
|
1516
|
+
const tempNode = this.createNode(key, value);
|
|
1517
|
+
if (tempNode) {
|
|
1518
|
+
destNode.key = srcNode.key;
|
|
1519
|
+
if (!this._isMapMode) destNode.value = srcNode.value;
|
|
1520
|
+
srcNode.key = tempNode.key;
|
|
1521
|
+
if (!this._isMapMode) srcNode.value = tempNode.value;
|
|
1522
|
+
}
|
|
1523
|
+
return destNode;
|
|
1524
|
+
}
|
|
1525
|
+
return void 0;
|
|
1526
|
+
}
|
|
1527
|
+
_replaceNode(oldNode, newNode) {
|
|
1528
|
+
if (oldNode.parent) {
|
|
1529
|
+
if (oldNode.parent.left === oldNode) {
|
|
1530
|
+
oldNode.parent.left = newNode;
|
|
1531
|
+
} else if (oldNode.parent.right === oldNode) {
|
|
1532
|
+
oldNode.parent.right = newNode;
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
newNode.left = oldNode.left;
|
|
1536
|
+
newNode.right = oldNode.right;
|
|
1537
|
+
newNode.parent = oldNode.parent;
|
|
1538
|
+
if (this._root === oldNode) {
|
|
1539
|
+
this._setRoot(newNode);
|
|
1540
|
+
}
|
|
1541
|
+
return newNode;
|
|
1542
|
+
}
|
|
1543
|
+
_setRoot(v) {
|
|
1544
|
+
if (v) {
|
|
1545
|
+
v.parent = void 0;
|
|
1546
|
+
}
|
|
1547
|
+
this._root = v;
|
|
1548
|
+
}
|
|
1549
|
+
_ensurePredicate(keyNodeEntryOrPredicate) {
|
|
1550
|
+
if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === void 0)
|
|
1551
|
+
return (node) => node ? false : false;
|
|
1552
|
+
if (this._isPredicate(keyNodeEntryOrPredicate)) return keyNodeEntryOrPredicate;
|
|
1553
|
+
if (this.isRealNode(keyNodeEntryOrPredicate))
|
|
1554
|
+
return (node) => node === keyNodeEntryOrPredicate;
|
|
1555
|
+
if (this.isEntry(keyNodeEntryOrPredicate)) {
|
|
1556
|
+
const [key] = keyNodeEntryOrPredicate;
|
|
1557
|
+
return (node) => {
|
|
1558
|
+
if (!node) return false;
|
|
1559
|
+
return node.key === key;
|
|
1560
|
+
};
|
|
1561
|
+
}
|
|
1562
|
+
return (node) => {
|
|
1563
|
+
if (!node) return false;
|
|
1564
|
+
return node.key === keyNodeEntryOrPredicate;
|
|
1565
|
+
};
|
|
1566
|
+
}
|
|
1567
|
+
_isPredicate(p) {
|
|
1568
|
+
return typeof p === "function";
|
|
1569
|
+
}
|
|
1570
|
+
_extractKey(keyNodeOrEntry) {
|
|
1571
|
+
if (keyNodeOrEntry === null) return null;
|
|
1572
|
+
if (keyNodeOrEntry === void 0) return;
|
|
1573
|
+
if (keyNodeOrEntry === this._NIL) return;
|
|
1574
|
+
if (this.isNode(keyNodeOrEntry)) return keyNodeOrEntry.key;
|
|
1575
|
+
if (this.isEntry(keyNodeOrEntry)) return keyNodeOrEntry[0];
|
|
1576
|
+
return keyNodeOrEntry;
|
|
1577
|
+
}
|
|
1578
|
+
_setValue(key, value) {
|
|
1579
|
+
if (key === null || key === void 0) return false;
|
|
1580
|
+
if (value === void 0) return false;
|
|
1581
|
+
return this._store.set(key, value);
|
|
1582
|
+
}
|
|
1583
|
+
_clearNodes() {
|
|
1584
|
+
this._setRoot(void 0);
|
|
1585
|
+
this._size = 0;
|
|
1586
|
+
}
|
|
1587
|
+
_clearValues() {
|
|
1588
|
+
this._store.clear();
|
|
1589
|
+
}
|
|
1590
|
+
};
|
|
1591
|
+
var BSTNode = class {
|
|
1592
|
+
static {
|
|
1593
|
+
__name(this, "BSTNode");
|
|
1594
|
+
}
|
|
1595
|
+
key;
|
|
1596
|
+
value;
|
|
1597
|
+
parent = void 0;
|
|
1598
|
+
constructor(key, value) {
|
|
1599
|
+
this.key = key;
|
|
1600
|
+
this.value = value;
|
|
1601
|
+
}
|
|
1602
|
+
_left = void 0;
|
|
1603
|
+
get left() {
|
|
1604
|
+
return this._left;
|
|
1605
|
+
}
|
|
1606
|
+
set left(v) {
|
|
1607
|
+
if (v) v.parent = this;
|
|
1608
|
+
this._left = v;
|
|
1609
|
+
}
|
|
1610
|
+
_right = void 0;
|
|
1611
|
+
get right() {
|
|
1612
|
+
return this._right;
|
|
1613
|
+
}
|
|
1614
|
+
set right(v) {
|
|
1615
|
+
if (v) v.parent = this;
|
|
1616
|
+
this._right = v;
|
|
1617
|
+
}
|
|
1618
|
+
_height = 0;
|
|
1619
|
+
get height() {
|
|
1620
|
+
return this._height;
|
|
1621
|
+
}
|
|
1622
|
+
set height(value) {
|
|
1623
|
+
this._height = value;
|
|
1624
|
+
}
|
|
1625
|
+
_color = "BLACK";
|
|
1626
|
+
get color() {
|
|
1627
|
+
return this._color;
|
|
1628
|
+
}
|
|
1629
|
+
set color(value) {
|
|
1630
|
+
this._color = value;
|
|
1631
|
+
}
|
|
1632
|
+
_count = 1;
|
|
1633
|
+
get count() {
|
|
1634
|
+
return this._count;
|
|
1635
|
+
}
|
|
1636
|
+
set count(value) {
|
|
1637
|
+
this._count = value;
|
|
1638
|
+
}
|
|
1639
|
+
get familyPosition() {
|
|
1640
|
+
if (!this.parent) {
|
|
1641
|
+
return this.left || this.right ? "ROOT" : "ISOLATED";
|
|
1642
|
+
}
|
|
1643
|
+
if (this.parent.left === this) {
|
|
1644
|
+
return this.left || this.right ? "ROOT_LEFT" : "LEFT";
|
|
1645
|
+
} else if (this.parent.right === this) {
|
|
1646
|
+
return this.left || this.right ? "ROOT_RIGHT" : "RIGHT";
|
|
1647
|
+
}
|
|
1648
|
+
return "MAL_NODE";
|
|
1649
|
+
}
|
|
1650
|
+
};
|
|
1651
|
+
var BST = class extends BinaryTree {
|
|
1652
|
+
static {
|
|
1653
|
+
__name(this, "BST");
|
|
1654
|
+
}
|
|
1655
|
+
constructor(keysNodesEntriesOrRaws = [], options) {
|
|
1656
|
+
super([], options);
|
|
1657
|
+
if (options) {
|
|
1658
|
+
if ("comparator" in options && options.comparator !== void 0) {
|
|
1659
|
+
this._comparator = options.comparator;
|
|
1660
|
+
} else {
|
|
1661
|
+
this._comparator = this._createDefaultComparator();
|
|
1662
|
+
}
|
|
1663
|
+
} else {
|
|
1664
|
+
this._comparator = this._createDefaultComparator();
|
|
1665
|
+
}
|
|
1666
|
+
if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
|
|
1667
|
+
}
|
|
1668
|
+
_root = void 0;
|
|
1669
|
+
get root() {
|
|
1670
|
+
return this._root;
|
|
1671
|
+
}
|
|
1672
|
+
_comparator;
|
|
1673
|
+
get comparator() {
|
|
1674
|
+
return this._comparator;
|
|
1675
|
+
}
|
|
1676
|
+
createNode(key, value) {
|
|
1677
|
+
return new BSTNode(key, this._isMapMode ? void 0 : value);
|
|
1678
|
+
}
|
|
1679
|
+
ensureNode(keyNodeOrEntry, iterationType = this.iterationType) {
|
|
1680
|
+
return super.ensureNode(keyNodeOrEntry, iterationType) ?? void 0;
|
|
1681
|
+
}
|
|
1682
|
+
isNode(keyNodeOrEntry) {
|
|
1683
|
+
return keyNodeOrEntry instanceof BSTNode;
|
|
1684
|
+
}
|
|
1685
|
+
isValidKey(key) {
|
|
1686
|
+
return isComparable(key);
|
|
1687
|
+
}
|
|
1688
|
+
dfs(callback = this._DEFAULT_NODE_CALLBACK, pattern = "IN", onlyOne = false, startNode = this._root, iterationType = this.iterationType) {
|
|
1689
|
+
return super.dfs(callback, pattern, onlyOne, startNode, iterationType);
|
|
1690
|
+
}
|
|
1691
|
+
bfs(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType) {
|
|
1692
|
+
return super.bfs(callback, startNode, iterationType, false);
|
|
1693
|
+
}
|
|
1694
|
+
listLevels(callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType) {
|
|
1695
|
+
return super.listLevels(callback, startNode, iterationType, false);
|
|
1696
|
+
}
|
|
1697
|
+
getNode(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
1698
|
+
return this.getNodes(keyNodeEntryOrPredicate, true, startNode, iterationType)[0] ?? void 0;
|
|
1699
|
+
}
|
|
1700
|
+
search(keyNodeEntryOrPredicate, onlyOne = false, callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType) {
|
|
1701
|
+
if (keyNodeEntryOrPredicate === void 0) return [];
|
|
1702
|
+
if (keyNodeEntryOrPredicate === null) return [];
|
|
1703
|
+
startNode = this.ensureNode(startNode);
|
|
1704
|
+
if (!startNode) return [];
|
|
1705
|
+
let predicate;
|
|
1706
|
+
const isRange = this.isRange(keyNodeEntryOrPredicate);
|
|
1707
|
+
if (isRange) {
|
|
1708
|
+
predicate = __name((node) => {
|
|
1709
|
+
if (!node) return false;
|
|
1710
|
+
return keyNodeEntryOrPredicate.isInRange(node.key, this._comparator);
|
|
1711
|
+
}, "predicate");
|
|
1712
|
+
} else {
|
|
1713
|
+
predicate = this._ensurePredicate(keyNodeEntryOrPredicate);
|
|
1714
|
+
}
|
|
1715
|
+
const shouldVisitLeft = __name((cur) => {
|
|
1716
|
+
if (!cur) return false;
|
|
1717
|
+
if (!this.isRealNode(cur.left)) return false;
|
|
1718
|
+
if (isRange) {
|
|
1719
|
+
const range = keyNodeEntryOrPredicate;
|
|
1720
|
+
const leftS = range.low;
|
|
1721
|
+
const leftI = range.includeLow;
|
|
1722
|
+
return leftI && this._compare(cur.key, leftS) >= 0 || !leftI && this._compare(cur.key, leftS) > 0;
|
|
1723
|
+
}
|
|
1724
|
+
if (!isRange && !this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
1725
|
+
const benchmarkKey = this._extractKey(keyNodeEntryOrPredicate);
|
|
1726
|
+
return benchmarkKey !== null && benchmarkKey !== void 0 && this._compare(cur.key, benchmarkKey) > 0;
|
|
1727
|
+
}
|
|
1728
|
+
return true;
|
|
1729
|
+
}, "shouldVisitLeft");
|
|
1730
|
+
const shouldVisitRight = __name((cur) => {
|
|
1731
|
+
if (!cur) return false;
|
|
1732
|
+
if (!this.isRealNode(cur.right)) return false;
|
|
1733
|
+
if (isRange) {
|
|
1734
|
+
const range = keyNodeEntryOrPredicate;
|
|
1735
|
+
const rightS = range.high;
|
|
1736
|
+
const rightI = range.includeHigh;
|
|
1737
|
+
return rightI && this._compare(cur.key, rightS) <= 0 || !rightI && this._compare(cur.key, rightS) < 0;
|
|
1738
|
+
}
|
|
1739
|
+
if (!isRange && !this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
1740
|
+
const benchmarkKey = this._extractKey(keyNodeEntryOrPredicate);
|
|
1741
|
+
return benchmarkKey !== null && benchmarkKey !== void 0 && this._compare(cur.key, benchmarkKey) < 0;
|
|
1742
|
+
}
|
|
1743
|
+
return true;
|
|
1744
|
+
}, "shouldVisitRight");
|
|
1745
|
+
return super._dfs(
|
|
1746
|
+
callback,
|
|
1747
|
+
"IN",
|
|
1748
|
+
onlyOne,
|
|
1749
|
+
startNode,
|
|
1750
|
+
iterationType,
|
|
1751
|
+
false,
|
|
1752
|
+
shouldVisitLeft,
|
|
1753
|
+
shouldVisitRight,
|
|
1754
|
+
() => true,
|
|
1755
|
+
(cur) => !!cur && predicate(cur)
|
|
1756
|
+
);
|
|
1757
|
+
}
|
|
1758
|
+
rangeSearch(range, callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType) {
|
|
1759
|
+
const searchRange = range instanceof Range ? range : new Range(range[0], range[1]);
|
|
1760
|
+
return this.search(searchRange, false, callback, startNode, iterationType);
|
|
1761
|
+
}
|
|
1762
|
+
set(keyNodeOrEntry, value) {
|
|
1763
|
+
const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
|
|
1764
|
+
if (newNode === void 0) return false;
|
|
1765
|
+
if (this._root === void 0) {
|
|
1766
|
+
this._setRoot(newNode);
|
|
1767
|
+
if (this._isMapMode) this._setValue(newNode?.key, newValue);
|
|
1768
|
+
this._size++;
|
|
1769
|
+
return true;
|
|
1770
|
+
}
|
|
1771
|
+
let current = this._root;
|
|
1772
|
+
while (current !== void 0) {
|
|
1773
|
+
if (this._compare(current.key, newNode.key) === 0) {
|
|
1774
|
+
this._replaceNode(current, newNode);
|
|
1775
|
+
if (this._isMapMode) this._setValue(current.key, newValue);
|
|
1776
|
+
return true;
|
|
1777
|
+
} else if (this._compare(current.key, newNode.key) > 0) {
|
|
1778
|
+
if (current.left === void 0) {
|
|
1779
|
+
current.left = newNode;
|
|
1780
|
+
if (this._isMapMode) this._setValue(newNode?.key, newValue);
|
|
1781
|
+
this._size++;
|
|
1782
|
+
return true;
|
|
1783
|
+
}
|
|
1784
|
+
if (current.left !== null) current = current.left;
|
|
1785
|
+
} else {
|
|
1786
|
+
if (current.right === void 0) {
|
|
1787
|
+
current.right = newNode;
|
|
1788
|
+
if (this._isMapMode) this._setValue(newNode?.key, newValue);
|
|
1789
|
+
this._size++;
|
|
1790
|
+
return true;
|
|
1791
|
+
}
|
|
1792
|
+
if (current.right !== null) current = current.right;
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
return false;
|
|
1796
|
+
}
|
|
1797
|
+
setMany(keysNodesEntriesOrRaws, values, isBalanceAdd = true, iterationType = this.iterationType) {
|
|
1798
|
+
const inserted = [];
|
|
1799
|
+
const valuesIterator = values?.[Symbol.iterator]();
|
|
1800
|
+
if (!isBalanceAdd) {
|
|
1801
|
+
for (let kve of keysNodesEntriesOrRaws) {
|
|
1802
|
+
const val = valuesIterator?.next().value;
|
|
1803
|
+
if (this.isRaw(kve)) kve = this._toEntryFn(kve);
|
|
1804
|
+
inserted.push(this.set(kve, val));
|
|
1805
|
+
}
|
|
1806
|
+
return inserted;
|
|
1807
|
+
}
|
|
1808
|
+
const realBTNExemplars = [];
|
|
1809
|
+
let i = 0;
|
|
1810
|
+
for (const kve of keysNodesEntriesOrRaws) {
|
|
1811
|
+
realBTNExemplars.push({ key: kve, value: valuesIterator?.next().value, orgIndex: i++ });
|
|
1812
|
+
}
|
|
1813
|
+
const sorted = realBTNExemplars.sort(({ key: a }, { key: b }) => {
|
|
1814
|
+
let keyA, keyB;
|
|
1815
|
+
if (this.isRaw(a)) keyA = this._toEntryFn(a)[0];
|
|
1816
|
+
else if (this.isEntry(a)) keyA = a[0];
|
|
1817
|
+
else if (this.isRealNode(a)) keyA = a.key;
|
|
1818
|
+
else keyA = a;
|
|
1819
|
+
if (this.isRaw(b)) keyB = this._toEntryFn(b)[0];
|
|
1820
|
+
else if (this.isEntry(b)) keyB = b[0];
|
|
1821
|
+
else if (this.isRealNode(b)) keyB = b.key;
|
|
1822
|
+
else keyB = b;
|
|
1823
|
+
if (keyA != null && keyB != null) return this._compare(keyA, keyB);
|
|
1824
|
+
return 0;
|
|
1825
|
+
});
|
|
1826
|
+
const _dfs = __name((arr) => {
|
|
1827
|
+
if (arr.length === 0) return;
|
|
1828
|
+
const mid = Math.floor((arr.length - 1) / 2);
|
|
1829
|
+
const { key, value, orgIndex } = arr[mid];
|
|
1830
|
+
if (this.isRaw(key)) {
|
|
1831
|
+
const entry = this._toEntryFn(key);
|
|
1832
|
+
inserted[orgIndex] = this.set(entry);
|
|
1833
|
+
} else {
|
|
1834
|
+
inserted[orgIndex] = this.set(key, value);
|
|
1835
|
+
}
|
|
1836
|
+
_dfs(arr.slice(0, mid));
|
|
1837
|
+
_dfs(arr.slice(mid + 1));
|
|
1838
|
+
}, "_dfs");
|
|
1839
|
+
const _iterate = __name(() => {
|
|
1840
|
+
const n = sorted.length;
|
|
1841
|
+
const stack = [[0, n - 1]];
|
|
1842
|
+
while (stack.length > 0) {
|
|
1843
|
+
const popped = stack.pop();
|
|
1844
|
+
if (!popped) continue;
|
|
1845
|
+
const [l, r] = popped;
|
|
1846
|
+
if (l > r) continue;
|
|
1847
|
+
const m = l + Math.floor((r - l) / 2);
|
|
1848
|
+
const { key, value, orgIndex } = sorted[m];
|
|
1849
|
+
if (this.isRaw(key)) {
|
|
1850
|
+
const entry = this._toEntryFn(key);
|
|
1851
|
+
inserted[orgIndex] = this.set(entry);
|
|
1852
|
+
} else {
|
|
1853
|
+
inserted[orgIndex] = this.set(key, value);
|
|
1854
|
+
}
|
|
1855
|
+
stack.push([m + 1, r]);
|
|
1856
|
+
stack.push([l, m - 1]);
|
|
1857
|
+
}
|
|
1858
|
+
}, "_iterate");
|
|
1859
|
+
if (iterationType === "RECURSIVE") _dfs(sorted);
|
|
1860
|
+
else _iterate();
|
|
1861
|
+
return inserted;
|
|
1862
|
+
}
|
|
1863
|
+
ceiling(keyNodeEntryOrPredicate, callback = this._DEFAULT_NODE_CALLBACK, iterationType) {
|
|
1864
|
+
let actualCallback = void 0;
|
|
1865
|
+
let actualIterationType = this.iterationType;
|
|
1866
|
+
if (typeof callback === "string") {
|
|
1867
|
+
actualIterationType = callback;
|
|
1868
|
+
} else if (callback) {
|
|
1869
|
+
actualCallback = callback;
|
|
1870
|
+
if (iterationType) {
|
|
1871
|
+
actualIterationType = iterationType;
|
|
1872
|
+
}
|
|
1873
|
+
}
|
|
1874
|
+
const node = this._bound(keyNodeEntryOrPredicate, true, actualIterationType);
|
|
1875
|
+
if (!actualCallback) {
|
|
1876
|
+
return node?.key;
|
|
1877
|
+
}
|
|
1878
|
+
return node ? actualCallback(node) : void 0;
|
|
1879
|
+
}
|
|
1880
|
+
higher(keyNodeEntryOrPredicate, callback = this._DEFAULT_NODE_CALLBACK, iterationType) {
|
|
1881
|
+
let actualCallback = void 0;
|
|
1882
|
+
let actualIterationType = this.iterationType;
|
|
1883
|
+
if (typeof callback === "string") {
|
|
1884
|
+
actualIterationType = callback;
|
|
1885
|
+
} else if (callback) {
|
|
1886
|
+
actualCallback = callback;
|
|
1887
|
+
if (iterationType) {
|
|
1888
|
+
actualIterationType = iterationType;
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
const node = this._bound(keyNodeEntryOrPredicate, false, actualIterationType);
|
|
1892
|
+
if (!actualCallback) {
|
|
1893
|
+
return node?.key;
|
|
1894
|
+
}
|
|
1895
|
+
return node ? actualCallback(node) : void 0;
|
|
1896
|
+
}
|
|
1897
|
+
floor(keyNodeEntryOrPredicate, callback = this._DEFAULT_NODE_CALLBACK, iterationType) {
|
|
1898
|
+
if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === void 0) {
|
|
1899
|
+
if (typeof callback === "string" || !callback) {
|
|
1900
|
+
return void 0;
|
|
1901
|
+
}
|
|
1902
|
+
return void 0;
|
|
1903
|
+
}
|
|
1904
|
+
let actualCallback = void 0;
|
|
1905
|
+
let actualIterationType = this.iterationType;
|
|
1906
|
+
if (typeof callback === "string") {
|
|
1907
|
+
actualIterationType = callback;
|
|
1908
|
+
} else if (callback) {
|
|
1909
|
+
actualCallback = callback;
|
|
1910
|
+
if (iterationType) {
|
|
1911
|
+
actualIterationType = iterationType;
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
if (this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
1915
|
+
const node = this._floorByPredicate(keyNodeEntryOrPredicate, actualIterationType);
|
|
1916
|
+
if (!actualCallback) {
|
|
1917
|
+
return node?.key;
|
|
1918
|
+
}
|
|
1919
|
+
return node ? actualCallback(node) : void 0;
|
|
1920
|
+
}
|
|
1921
|
+
let targetKey;
|
|
1922
|
+
if (this.isNode(keyNodeEntryOrPredicate)) {
|
|
1923
|
+
targetKey = keyNodeEntryOrPredicate.key;
|
|
1924
|
+
} else if (this.isEntry(keyNodeEntryOrPredicate)) {
|
|
1925
|
+
const key = keyNodeEntryOrPredicate[0];
|
|
1926
|
+
if (key === null || key === void 0) {
|
|
1927
|
+
if (typeof callback === "string" || !callback) {
|
|
1928
|
+
return void 0;
|
|
1929
|
+
}
|
|
1930
|
+
return void 0;
|
|
1931
|
+
}
|
|
1932
|
+
targetKey = key;
|
|
1933
|
+
} else {
|
|
1934
|
+
targetKey = keyNodeEntryOrPredicate;
|
|
1935
|
+
}
|
|
1936
|
+
if (targetKey !== void 0) {
|
|
1937
|
+
const node = this._floorByKey(targetKey, actualIterationType);
|
|
1938
|
+
if (!actualCallback) {
|
|
1939
|
+
return node?.key;
|
|
1940
|
+
}
|
|
1941
|
+
return node ? actualCallback(node) : void 0;
|
|
1942
|
+
}
|
|
1943
|
+
if (typeof callback === "string" || !callback) {
|
|
1944
|
+
return void 0;
|
|
1945
|
+
}
|
|
1946
|
+
return void 0;
|
|
1947
|
+
}
|
|
1948
|
+
lower(keyNodeEntryOrPredicate, callback, iterationType) {
|
|
1949
|
+
if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === void 0) {
|
|
1950
|
+
if (typeof callback === "string" || !callback) {
|
|
1951
|
+
return void 0;
|
|
1952
|
+
}
|
|
1953
|
+
return void 0;
|
|
1954
|
+
}
|
|
1955
|
+
let actualCallback = void 0;
|
|
1956
|
+
let actualIterationType = this.iterationType;
|
|
1957
|
+
if (typeof callback === "string") {
|
|
1958
|
+
actualIterationType = callback;
|
|
1959
|
+
} else if (callback) {
|
|
1960
|
+
actualCallback = callback;
|
|
1961
|
+
if (iterationType) {
|
|
1962
|
+
actualIterationType = iterationType;
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
if (this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
1966
|
+
const node = this._lowerByPredicate(keyNodeEntryOrPredicate, actualIterationType);
|
|
1967
|
+
if (!actualCallback) {
|
|
1968
|
+
return node?.key;
|
|
1969
|
+
}
|
|
1970
|
+
return node ? actualCallback(node) : void 0;
|
|
1971
|
+
}
|
|
1972
|
+
let targetKey;
|
|
1973
|
+
if (this.isNode(keyNodeEntryOrPredicate)) {
|
|
1974
|
+
targetKey = keyNodeEntryOrPredicate.key;
|
|
1975
|
+
} else if (this.isEntry(keyNodeEntryOrPredicate)) {
|
|
1976
|
+
const key = keyNodeEntryOrPredicate[0];
|
|
1977
|
+
if (key === null || key === void 0) {
|
|
1978
|
+
if (typeof callback === "string" || !callback) {
|
|
1979
|
+
return void 0;
|
|
1980
|
+
}
|
|
1981
|
+
return void 0;
|
|
1982
|
+
}
|
|
1983
|
+
targetKey = key;
|
|
1984
|
+
} else {
|
|
1985
|
+
targetKey = keyNodeEntryOrPredicate;
|
|
1986
|
+
}
|
|
1987
|
+
if (targetKey !== void 0) {
|
|
1988
|
+
const node = this._lowerByKey(targetKey, actualIterationType);
|
|
1989
|
+
if (!actualCallback) {
|
|
1990
|
+
return node?.key;
|
|
1991
|
+
}
|
|
1992
|
+
return node ? actualCallback(node) : void 0;
|
|
1993
|
+
}
|
|
1994
|
+
if (typeof callback === "string" || !callback) {
|
|
1995
|
+
return void 0;
|
|
1996
|
+
}
|
|
1997
|
+
return void 0;
|
|
1998
|
+
}
|
|
1999
|
+
lesserOrGreaterTraverse(callback = this._DEFAULT_NODE_CALLBACK, lesserOrGreater = -1, targetNode = this._root, iterationType = this.iterationType) {
|
|
2000
|
+
const targetNodeEnsured = this.ensureNode(targetNode);
|
|
2001
|
+
const ans = [];
|
|
2002
|
+
if (!this._root || !targetNodeEnsured) return ans;
|
|
2003
|
+
const targetKey = targetNodeEnsured.key;
|
|
2004
|
+
if (iterationType === "RECURSIVE") {
|
|
2005
|
+
const dfs = __name((cur) => {
|
|
2006
|
+
const compared = this._compare(cur.key, targetKey);
|
|
2007
|
+
if (Math.sign(compared) == lesserOrGreater) ans.push(callback(cur));
|
|
2008
|
+
if (this.isRealNode(cur.left)) dfs(cur.left);
|
|
2009
|
+
if (this.isRealNode(cur.right)) dfs(cur.right);
|
|
2010
|
+
}, "dfs");
|
|
2011
|
+
dfs(this._root);
|
|
2012
|
+
return ans;
|
|
2013
|
+
} else {
|
|
2014
|
+
const queue = new Queue([this._root]);
|
|
2015
|
+
while (queue.length > 0) {
|
|
2016
|
+
const cur = queue.shift();
|
|
2017
|
+
if (this.isRealNode(cur)) {
|
|
2018
|
+
const compared = this._compare(cur.key, targetKey);
|
|
2019
|
+
if (Math.sign(compared) == lesserOrGreater) ans.push(callback(cur));
|
|
2020
|
+
if (this.isRealNode(cur.left)) queue.push(cur.left);
|
|
2021
|
+
if (this.isRealNode(cur.right)) queue.push(cur.right);
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
return ans;
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
perfectlyBalance(iterationType = this.iterationType) {
|
|
2028
|
+
const nodes = this.dfs((node) => node, "IN", false, this._root, iterationType);
|
|
2029
|
+
const n = nodes.length;
|
|
2030
|
+
this._clearNodes();
|
|
2031
|
+
if (n === 0) return false;
|
|
2032
|
+
const build = __name((l, r, parent) => {
|
|
2033
|
+
if (l > r) return void 0;
|
|
2034
|
+
const m = l + (r - l >> 1);
|
|
2035
|
+
const root = nodes[m];
|
|
2036
|
+
const leftChild = build(l, m - 1, root);
|
|
2037
|
+
const rightChild = build(m + 1, r, root);
|
|
2038
|
+
root.left = leftChild;
|
|
2039
|
+
root.right = rightChild;
|
|
2040
|
+
root.parent = parent;
|
|
2041
|
+
return root;
|
|
2042
|
+
}, "build");
|
|
2043
|
+
const newRoot = build(0, n - 1, void 0);
|
|
2044
|
+
this._setRoot(newRoot);
|
|
2045
|
+
this._size = n;
|
|
2046
|
+
return true;
|
|
2047
|
+
}
|
|
2048
|
+
isAVLBalanced(iterationType = this.iterationType) {
|
|
2049
|
+
if (!this._root) return true;
|
|
2050
|
+
let balanced = true;
|
|
2051
|
+
if (iterationType === "RECURSIVE") {
|
|
2052
|
+
const _height = __name((cur) => {
|
|
2053
|
+
if (!cur) return 0;
|
|
2054
|
+
const leftHeight = _height(cur.left);
|
|
2055
|
+
const rightHeight = _height(cur.right);
|
|
2056
|
+
if (Math.abs(leftHeight - rightHeight) > 1) balanced = false;
|
|
2057
|
+
return Math.max(leftHeight, rightHeight) + 1;
|
|
2058
|
+
}, "_height");
|
|
2059
|
+
_height(this._root);
|
|
2060
|
+
} else {
|
|
2061
|
+
const stack = [];
|
|
2062
|
+
let node = this._root, last = void 0;
|
|
2063
|
+
const depths = new Map();
|
|
2064
|
+
while (stack.length > 0 || node) {
|
|
2065
|
+
if (node) {
|
|
2066
|
+
stack.push(node);
|
|
2067
|
+
if (node.left !== null) node = node.left;
|
|
2068
|
+
} else {
|
|
2069
|
+
node = stack[stack.length - 1];
|
|
2070
|
+
if (!node.right || last === node.right) {
|
|
2071
|
+
node = stack.pop();
|
|
2072
|
+
if (node) {
|
|
2073
|
+
const left = node.left ? depths.get(node.left) : -1;
|
|
2074
|
+
const right = node.right ? depths.get(node.right) : -1;
|
|
2075
|
+
if (Math.abs(left - right) > 1) return false;
|
|
2076
|
+
depths.set(node, 1 + Math.max(left, right));
|
|
2077
|
+
last = node;
|
|
2078
|
+
node = void 0;
|
|
2079
|
+
}
|
|
2080
|
+
} else node = node.right;
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
return balanced;
|
|
2085
|
+
}
|
|
2086
|
+
map(callback, options, thisArg) {
|
|
2087
|
+
const out = this._createLike([], options);
|
|
2088
|
+
let index = 0;
|
|
2089
|
+
for (const [key, value] of this) {
|
|
2090
|
+
out.set(callback.call(thisArg, value, key, index++, this));
|
|
2091
|
+
}
|
|
2092
|
+
return out;
|
|
2093
|
+
}
|
|
2094
|
+
deleteWhere(keyNodeEntryOrPredicate, onlyOne = false, startNode = this._root, iterationType = this.iterationType) {
|
|
2095
|
+
const toDelete = this.search(keyNodeEntryOrPredicate, onlyOne, (node) => node, startNode, iterationType);
|
|
2096
|
+
let results = [];
|
|
2097
|
+
for (const node of toDelete) {
|
|
2098
|
+
const deleteInfo = this.delete(node);
|
|
2099
|
+
results = results.concat(deleteInfo);
|
|
2100
|
+
}
|
|
2101
|
+
return results;
|
|
2102
|
+
}
|
|
2103
|
+
_createDefaultComparator() {
|
|
2104
|
+
return (a, b) => {
|
|
2105
|
+
if (isComparable(a) && isComparable(b)) {
|
|
2106
|
+
if (a > b) return 1;
|
|
2107
|
+
if (a < b) return -1;
|
|
2108
|
+
return 0;
|
|
2109
|
+
}
|
|
2110
|
+
if (typeof a === "object" || typeof b === "object") {
|
|
2111
|
+
throw TypeError(
|
|
2112
|
+
`When comparing object type keys, a custom comparator must be provided in the constructor's options!`
|
|
2113
|
+
);
|
|
2114
|
+
}
|
|
2115
|
+
return 0;
|
|
2116
|
+
};
|
|
2117
|
+
}
|
|
2118
|
+
_floorByKey(key, iterationType) {
|
|
2119
|
+
if (iterationType === "RECURSIVE") {
|
|
2120
|
+
const dfs = __name((cur) => {
|
|
2121
|
+
if (!this.isRealNode(cur)) return void 0;
|
|
2122
|
+
const cmp = this.comparator(cur.key, key);
|
|
2123
|
+
if (cmp <= 0) {
|
|
2124
|
+
const rightResult = dfs(cur.right);
|
|
2125
|
+
return rightResult ?? cur;
|
|
2126
|
+
} else {
|
|
2127
|
+
return dfs(cur.left);
|
|
2128
|
+
}
|
|
2129
|
+
}, "dfs");
|
|
2130
|
+
return dfs(this.root);
|
|
2131
|
+
} else {
|
|
2132
|
+
let current = this.root;
|
|
2133
|
+
let result = void 0;
|
|
2134
|
+
while (this.isRealNode(current)) {
|
|
2135
|
+
const cmp = this.comparator(current.key, key);
|
|
2136
|
+
if (cmp <= 0) {
|
|
2137
|
+
result = current;
|
|
2138
|
+
current = current.right ?? void 0;
|
|
2139
|
+
} else {
|
|
2140
|
+
current = current.left ?? void 0;
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
return result;
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
_floorByPredicate(predicate, iterationType) {
|
|
2147
|
+
if (iterationType === "RECURSIVE") {
|
|
2148
|
+
let result = void 0;
|
|
2149
|
+
const dfs = __name((cur) => {
|
|
2150
|
+
if (!this.isRealNode(cur)) return;
|
|
2151
|
+
if (this.isRealNode(cur.left)) dfs(cur.left);
|
|
2152
|
+
if (predicate(cur)) {
|
|
2153
|
+
result = cur;
|
|
2154
|
+
}
|
|
2155
|
+
if (this.isRealNode(cur.right)) dfs(cur.right);
|
|
2156
|
+
}, "dfs");
|
|
2157
|
+
dfs(this.root);
|
|
2158
|
+
return result;
|
|
2159
|
+
} else {
|
|
2160
|
+
const stack = [];
|
|
2161
|
+
let current = this.root;
|
|
2162
|
+
let result = void 0;
|
|
2163
|
+
while (stack.length > 0 || this.isRealNode(current)) {
|
|
2164
|
+
if (this.isRealNode(current)) {
|
|
2165
|
+
stack.push(current);
|
|
2166
|
+
current = current.left;
|
|
2167
|
+
} else {
|
|
2168
|
+
const node = stack.pop();
|
|
2169
|
+
if (!this.isRealNode(node)) break;
|
|
2170
|
+
if (predicate(node)) {
|
|
2171
|
+
result = node;
|
|
2172
|
+
}
|
|
2173
|
+
current = node.right;
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2176
|
+
return result;
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
_lowerByKey(key, iterationType) {
|
|
2180
|
+
if (iterationType === "RECURSIVE") {
|
|
2181
|
+
const dfs = __name((cur) => {
|
|
2182
|
+
if (!this.isRealNode(cur)) return void 0;
|
|
2183
|
+
const cmp = this.comparator(cur.key, key);
|
|
2184
|
+
if (cmp < 0) {
|
|
2185
|
+
const rightResult = dfs(cur.right);
|
|
2186
|
+
return rightResult ?? cur;
|
|
2187
|
+
} else {
|
|
2188
|
+
return dfs(cur.left);
|
|
2189
|
+
}
|
|
2190
|
+
}, "dfs");
|
|
2191
|
+
return dfs(this.root);
|
|
2192
|
+
} else {
|
|
2193
|
+
let current = this.root;
|
|
2194
|
+
let result = void 0;
|
|
2195
|
+
while (this.isRealNode(current)) {
|
|
2196
|
+
const cmp = this.comparator(current.key, key);
|
|
2197
|
+
if (cmp < 0) {
|
|
2198
|
+
result = current;
|
|
2199
|
+
current = current.right ?? void 0;
|
|
2200
|
+
} else {
|
|
2201
|
+
current = current.left ?? void 0;
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
return result;
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
_lowerByPredicate(predicate, iterationType) {
|
|
2208
|
+
if (iterationType === "RECURSIVE") {
|
|
2209
|
+
let result = void 0;
|
|
2210
|
+
const dfs = __name((cur) => {
|
|
2211
|
+
if (!this.isRealNode(cur)) return;
|
|
2212
|
+
if (this.isRealNode(cur.left)) dfs(cur.left);
|
|
2213
|
+
if (predicate(cur)) {
|
|
2214
|
+
result = cur;
|
|
2215
|
+
}
|
|
2216
|
+
if (this.isRealNode(cur.right)) dfs(cur.right);
|
|
2217
|
+
}, "dfs");
|
|
2218
|
+
dfs(this.root);
|
|
2219
|
+
return result;
|
|
2220
|
+
} else {
|
|
2221
|
+
const stack = [];
|
|
2222
|
+
let current = this.root;
|
|
2223
|
+
let result = void 0;
|
|
2224
|
+
while (stack.length > 0 || this.isRealNode(current)) {
|
|
2225
|
+
if (this.isRealNode(current)) {
|
|
2226
|
+
stack.push(current);
|
|
2227
|
+
current = current.left;
|
|
2228
|
+
} else {
|
|
2229
|
+
const node = stack.pop();
|
|
2230
|
+
if (!this.isRealNode(node)) break;
|
|
2231
|
+
if (predicate(node)) {
|
|
2232
|
+
result = node;
|
|
2233
|
+
}
|
|
2234
|
+
current = node.right;
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
return result;
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
_bound(keyNodeEntryOrPredicate, isLower, iterationType) {
|
|
2241
|
+
if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === void 0) {
|
|
2242
|
+
return void 0;
|
|
2243
|
+
}
|
|
2244
|
+
if (this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
2245
|
+
return this._boundByPredicate(keyNodeEntryOrPredicate, iterationType);
|
|
2246
|
+
}
|
|
2247
|
+
let targetKey;
|
|
2248
|
+
if (this.isNode(keyNodeEntryOrPredicate)) {
|
|
2249
|
+
targetKey = keyNodeEntryOrPredicate.key;
|
|
2250
|
+
} else if (this.isEntry(keyNodeEntryOrPredicate)) {
|
|
2251
|
+
const key = keyNodeEntryOrPredicate[0];
|
|
2252
|
+
if (key === null || key === void 0) {
|
|
2253
|
+
return void 0;
|
|
2254
|
+
}
|
|
2255
|
+
targetKey = key;
|
|
2256
|
+
} else {
|
|
2257
|
+
targetKey = keyNodeEntryOrPredicate;
|
|
2258
|
+
}
|
|
2259
|
+
if (targetKey !== void 0) {
|
|
2260
|
+
return this._boundByKey(targetKey, isLower, iterationType);
|
|
2261
|
+
}
|
|
2262
|
+
return void 0;
|
|
2263
|
+
}
|
|
2264
|
+
_boundByKey(key, isLower, iterationType) {
|
|
2265
|
+
if (iterationType === "RECURSIVE") {
|
|
2266
|
+
const dfs = __name((cur) => {
|
|
2267
|
+
if (!this.isRealNode(cur)) return void 0;
|
|
2268
|
+
const cmp = this.comparator(cur.key, key);
|
|
2269
|
+
const condition = isLower ? cmp >= 0 : cmp > 0;
|
|
2270
|
+
if (condition) {
|
|
2271
|
+
const leftResult = dfs(cur.left);
|
|
2272
|
+
return leftResult ?? cur;
|
|
2273
|
+
} else {
|
|
2274
|
+
return dfs(cur.right);
|
|
2275
|
+
}
|
|
2276
|
+
}, "dfs");
|
|
2277
|
+
return dfs(this.root);
|
|
2278
|
+
} else {
|
|
2279
|
+
let current = this.root;
|
|
2280
|
+
let result = void 0;
|
|
2281
|
+
while (this.isRealNode(current)) {
|
|
2282
|
+
const cmp = this.comparator(current.key, key);
|
|
2283
|
+
const condition = isLower ? cmp >= 0 : cmp > 0;
|
|
2284
|
+
if (condition) {
|
|
2285
|
+
result = current;
|
|
2286
|
+
current = current.left ?? void 0;
|
|
2287
|
+
} else {
|
|
2288
|
+
current = current.right ?? void 0;
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
return result;
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
_boundByPredicate(predicate, iterationType) {
|
|
2295
|
+
if (iterationType === "RECURSIVE") {
|
|
2296
|
+
let result = void 0;
|
|
2297
|
+
const dfs = __name((cur) => {
|
|
2298
|
+
if (result || !this.isRealNode(cur)) return;
|
|
2299
|
+
if (this.isRealNode(cur.left)) dfs(cur.left);
|
|
2300
|
+
if (!result && predicate(cur)) {
|
|
2301
|
+
result = cur;
|
|
2302
|
+
}
|
|
2303
|
+
if (!result && this.isRealNode(cur.right)) dfs(cur.right);
|
|
2304
|
+
}, "dfs");
|
|
2305
|
+
dfs(this.root);
|
|
2306
|
+
return result;
|
|
2307
|
+
} else {
|
|
2308
|
+
const stack = [];
|
|
2309
|
+
let current = this.root;
|
|
2310
|
+
while (stack.length > 0 || this.isRealNode(current)) {
|
|
2311
|
+
if (this.isRealNode(current)) {
|
|
2312
|
+
stack.push(current);
|
|
2313
|
+
current = current.left;
|
|
2314
|
+
} else {
|
|
2315
|
+
const node = stack.pop();
|
|
2316
|
+
if (!this.isRealNode(node)) break;
|
|
2317
|
+
if (predicate(node)) {
|
|
2318
|
+
return node;
|
|
2319
|
+
}
|
|
2320
|
+
current = node.right;
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
return void 0;
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
_createInstance(options) {
|
|
2327
|
+
const Ctor = this.constructor;
|
|
2328
|
+
return new Ctor([], { ...this._snapshotOptions(), ...options ?? {} });
|
|
2329
|
+
}
|
|
2330
|
+
_createLike(iter = [], options) {
|
|
2331
|
+
const Ctor = this.constructor;
|
|
2332
|
+
return new Ctor(iter, { ...this._snapshotOptions(), ...options ?? {} });
|
|
2333
|
+
}
|
|
2334
|
+
_snapshotOptions() {
|
|
2335
|
+
return {
|
|
2336
|
+
...super._snapshotOptions(),
|
|
2337
|
+
comparator: this._comparator
|
|
2338
|
+
};
|
|
2339
|
+
}
|
|
2340
|
+
_keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value) {
|
|
2341
|
+
const [node, entryValue] = super._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
|
|
2342
|
+
if (node === null) return [void 0, void 0];
|
|
2343
|
+
return [node, value ?? entryValue];
|
|
2344
|
+
}
|
|
2345
|
+
_setRoot(v) {
|
|
2346
|
+
if (v) v.parent = void 0;
|
|
2347
|
+
this._root = v;
|
|
2348
|
+
}
|
|
2349
|
+
_compare(a, b) {
|
|
2350
|
+
return this._comparator(a, b);
|
|
2351
|
+
}
|
|
2352
|
+
_deleteByKey(key) {
|
|
2353
|
+
let node = this._root;
|
|
2354
|
+
while (node) {
|
|
2355
|
+
const cmp = this._compare(node.key, key);
|
|
2356
|
+
if (cmp === 0) break;
|
|
2357
|
+
node = cmp > 0 ? node.left : node.right;
|
|
2358
|
+
}
|
|
2359
|
+
if (!node) return false;
|
|
2360
|
+
const transplant = __name((u, v) => {
|
|
2361
|
+
const p = u?.parent;
|
|
2362
|
+
if (!p) {
|
|
2363
|
+
this._setRoot(v);
|
|
2364
|
+
} else if (p.left === u) {
|
|
2365
|
+
p.left = v;
|
|
2366
|
+
} else {
|
|
2367
|
+
p.right = v;
|
|
2368
|
+
}
|
|
2369
|
+
if (v) v.parent = p;
|
|
2370
|
+
}, "transplant");
|
|
2371
|
+
const minNode = __name((x) => {
|
|
2372
|
+
if (!x) return void 0;
|
|
2373
|
+
while (x.left !== void 0 && x.left !== null) x = x.left;
|
|
2374
|
+
return x;
|
|
2375
|
+
}, "minNode");
|
|
2376
|
+
if (node.left === void 0) {
|
|
2377
|
+
transplant(node, node.right);
|
|
2378
|
+
} else if (node.right === void 0) {
|
|
2379
|
+
transplant(node, node.left);
|
|
2380
|
+
} else {
|
|
2381
|
+
const succ = minNode(node.right);
|
|
2382
|
+
if (succ.parent !== node) {
|
|
2383
|
+
transplant(succ, succ.right);
|
|
2384
|
+
succ.right = node.right;
|
|
2385
|
+
if (succ.right) succ.right.parent = succ;
|
|
2386
|
+
}
|
|
2387
|
+
transplant(node, succ);
|
|
2388
|
+
succ.left = node.left;
|
|
2389
|
+
if (succ.left) succ.left.parent = succ;
|
|
2390
|
+
}
|
|
2391
|
+
this._size = Math.max(0, (this._size ?? 0) - 1);
|
|
2392
|
+
return true;
|
|
2393
|
+
}
|
|
2394
|
+
};
|
|
2395
|
+
var AVLTreeNode = class {
|
|
2396
|
+
static {
|
|
2397
|
+
__name(this, "AVLTreeNode");
|
|
2398
|
+
}
|
|
2399
|
+
key;
|
|
2400
|
+
value;
|
|
2401
|
+
parent = void 0;
|
|
2402
|
+
constructor(key, value) {
|
|
2403
|
+
this.key = key;
|
|
2404
|
+
this.value = value;
|
|
2405
|
+
}
|
|
2406
|
+
_left = void 0;
|
|
2407
|
+
get left() {
|
|
2408
|
+
return this._left;
|
|
2409
|
+
}
|
|
2410
|
+
set left(v) {
|
|
2411
|
+
if (v) {
|
|
2412
|
+
v.parent = this;
|
|
2413
|
+
}
|
|
2414
|
+
this._left = v;
|
|
2415
|
+
}
|
|
2416
|
+
_right = void 0;
|
|
2417
|
+
get right() {
|
|
2418
|
+
return this._right;
|
|
2419
|
+
}
|
|
2420
|
+
set right(v) {
|
|
2421
|
+
if (v) {
|
|
2422
|
+
v.parent = this;
|
|
2423
|
+
}
|
|
2424
|
+
this._right = v;
|
|
2425
|
+
}
|
|
2426
|
+
_height = 0;
|
|
2427
|
+
get height() {
|
|
2428
|
+
return this._height;
|
|
2429
|
+
}
|
|
2430
|
+
set height(value) {
|
|
2431
|
+
this._height = value;
|
|
2432
|
+
}
|
|
2433
|
+
_color = "BLACK";
|
|
2434
|
+
get color() {
|
|
2435
|
+
return this._color;
|
|
2436
|
+
}
|
|
2437
|
+
set color(value) {
|
|
2438
|
+
this._color = value;
|
|
2439
|
+
}
|
|
2440
|
+
_count = 1;
|
|
2441
|
+
get count() {
|
|
2442
|
+
return this._count;
|
|
2443
|
+
}
|
|
2444
|
+
set count(value) {
|
|
2445
|
+
this._count = value;
|
|
2446
|
+
}
|
|
2447
|
+
get familyPosition() {
|
|
2448
|
+
if (!this.parent) {
|
|
2449
|
+
return this.left || this.right ? "ROOT" : "ISOLATED";
|
|
2450
|
+
}
|
|
2451
|
+
if (this.parent.left === this) {
|
|
2452
|
+
return this.left || this.right ? "ROOT_LEFT" : "LEFT";
|
|
2453
|
+
} else if (this.parent.right === this) {
|
|
2454
|
+
return this.left || this.right ? "ROOT_RIGHT" : "RIGHT";
|
|
2455
|
+
}
|
|
2456
|
+
return "MAL_NODE";
|
|
2457
|
+
}
|
|
2458
|
+
};
|
|
2459
|
+
var AVLTree = class extends BST {
|
|
2460
|
+
static {
|
|
2461
|
+
__name(this, "AVLTree");
|
|
2462
|
+
}
|
|
2463
|
+
constructor(keysNodesEntriesOrRaws = [], options) {
|
|
2464
|
+
super([], options);
|
|
2465
|
+
if (keysNodesEntriesOrRaws) super.setMany(keysNodesEntriesOrRaws);
|
|
2466
|
+
}
|
|
2467
|
+
createNode(key, value) {
|
|
2468
|
+
return new AVLTreeNode(key, this._isMapMode ? void 0 : value);
|
|
2469
|
+
}
|
|
2470
|
+
isNode(keyNodeOrEntry) {
|
|
2471
|
+
return keyNodeOrEntry instanceof AVLTreeNode;
|
|
2472
|
+
}
|
|
2473
|
+
set(keyNodeOrEntry, value) {
|
|
2474
|
+
if (keyNodeOrEntry === null) return false;
|
|
2475
|
+
const inserted = super.set(keyNodeOrEntry, value);
|
|
2476
|
+
if (inserted) this._balancePath(keyNodeOrEntry);
|
|
2477
|
+
return inserted;
|
|
2478
|
+
}
|
|
2479
|
+
delete(keyNodeOrEntry) {
|
|
2480
|
+
const deletedResults = super.delete(keyNodeOrEntry);
|
|
2481
|
+
for (const { needBalanced } of deletedResults) {
|
|
2482
|
+
if (needBalanced) {
|
|
2483
|
+
this._balancePath(needBalanced);
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
return deletedResults;
|
|
2487
|
+
}
|
|
2488
|
+
perfectlyBalance(iterationType = this.iterationType) {
|
|
2489
|
+
const nodes = this.dfs((node) => node, "IN", false, this._root, iterationType);
|
|
2490
|
+
const n = nodes.length;
|
|
2491
|
+
if (n === 0) return false;
|
|
2492
|
+
this._clearNodes();
|
|
2493
|
+
const build = __name((l, r, parent) => {
|
|
2494
|
+
if (l > r) return void 0;
|
|
2495
|
+
const m = l + (r - l >> 1);
|
|
2496
|
+
const root = nodes[m];
|
|
2497
|
+
root.left = build(l, m - 1, root);
|
|
2498
|
+
root.right = build(m + 1, r, root);
|
|
2499
|
+
root.parent = parent;
|
|
2500
|
+
const lh = root.left ? root.left.height : -1;
|
|
2501
|
+
const rh = root.right ? root.right.height : -1;
|
|
2502
|
+
root.height = Math.max(lh, rh) + 1;
|
|
2503
|
+
return root;
|
|
2504
|
+
}, "build");
|
|
2505
|
+
const newRoot = build(0, n - 1, void 0);
|
|
2506
|
+
this._setRoot(newRoot);
|
|
2507
|
+
this._size = n;
|
|
2508
|
+
return true;
|
|
2509
|
+
}
|
|
2510
|
+
map(callback, options, thisArg) {
|
|
2511
|
+
const out = this._createLike([], options);
|
|
2512
|
+
let index = 0;
|
|
2513
|
+
for (const [key, value] of this) {
|
|
2514
|
+
out.set(callback.call(thisArg, value, key, index++, this));
|
|
2515
|
+
}
|
|
2516
|
+
return out;
|
|
2517
|
+
}
|
|
2518
|
+
_createInstance(options) {
|
|
2519
|
+
const Ctor = this.constructor;
|
|
2520
|
+
return new Ctor([], { ...this._snapshotOptions(), ...options ?? {} });
|
|
2521
|
+
}
|
|
2522
|
+
_createLike(iter = [], options) {
|
|
2523
|
+
const Ctor = this.constructor;
|
|
2524
|
+
return new Ctor(iter, { ...this._snapshotOptions(), ...options ?? {} });
|
|
2525
|
+
}
|
|
2526
|
+
_swapProperties(srcNode, destNode) {
|
|
2527
|
+
const srcNodeEnsured = this.ensureNode(srcNode);
|
|
2528
|
+
const destNodeEnsured = this.ensureNode(destNode);
|
|
2529
|
+
if (srcNodeEnsured && destNodeEnsured) {
|
|
2530
|
+
const { key, value, height } = destNodeEnsured;
|
|
2531
|
+
const tempNode = this.createNode(key, value);
|
|
2532
|
+
if (tempNode) {
|
|
2533
|
+
tempNode.height = height;
|
|
2534
|
+
destNodeEnsured.key = srcNodeEnsured.key;
|
|
2535
|
+
if (!this._isMapMode) destNodeEnsured.value = srcNodeEnsured.value;
|
|
2536
|
+
destNodeEnsured.height = srcNodeEnsured.height;
|
|
2537
|
+
srcNodeEnsured.key = tempNode.key;
|
|
2538
|
+
if (!this._isMapMode) srcNodeEnsured.value = tempNode.value;
|
|
2539
|
+
srcNodeEnsured.height = tempNode.height;
|
|
2540
|
+
}
|
|
2541
|
+
return destNodeEnsured;
|
|
2542
|
+
}
|
|
2543
|
+
return void 0;
|
|
2544
|
+
}
|
|
2545
|
+
_balanceFactor(node) {
|
|
2546
|
+
const left = node.left ? node.left.height : -1;
|
|
2547
|
+
const right = node.right ? node.right.height : -1;
|
|
2548
|
+
return right - left;
|
|
2549
|
+
}
|
|
2550
|
+
_updateHeight(node) {
|
|
2551
|
+
const leftHeight = node.left ? node.left.height : -1;
|
|
2552
|
+
const rightHeight = node.right ? node.right.height : -1;
|
|
2553
|
+
node.height = 1 + Math.max(leftHeight, rightHeight);
|
|
2554
|
+
}
|
|
2555
|
+
_balanceLL(A) {
|
|
2556
|
+
const parentOfA = A.parent;
|
|
2557
|
+
const B = A.left;
|
|
2558
|
+
if (B !== null) A.parent = B;
|
|
2559
|
+
if (B && B.right) {
|
|
2560
|
+
B.right.parent = A;
|
|
2561
|
+
}
|
|
2562
|
+
if (B) B.parent = parentOfA;
|
|
2563
|
+
if (A === this.root) {
|
|
2564
|
+
if (B) this._setRoot(B);
|
|
2565
|
+
} else {
|
|
2566
|
+
if (parentOfA?.left === A) {
|
|
2567
|
+
parentOfA.left = B;
|
|
2568
|
+
} else {
|
|
2569
|
+
if (parentOfA) parentOfA.right = B;
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
if (B) {
|
|
2573
|
+
A.left = B.right;
|
|
2574
|
+
B.right = A;
|
|
2575
|
+
}
|
|
2576
|
+
this._updateHeight(A);
|
|
2577
|
+
if (B) this._updateHeight(B);
|
|
2578
|
+
}
|
|
2579
|
+
_balanceLR(A) {
|
|
2580
|
+
const parentOfA = A.parent;
|
|
2581
|
+
const B = A.left;
|
|
2582
|
+
let C = void 0;
|
|
2583
|
+
if (B) {
|
|
2584
|
+
C = B.right;
|
|
2585
|
+
}
|
|
2586
|
+
if (A && C !== null) A.parent = C;
|
|
2587
|
+
if (B && C !== null) B.parent = C;
|
|
2588
|
+
if (C) {
|
|
2589
|
+
if (C.left) {
|
|
2590
|
+
if (B !== null) C.left.parent = B;
|
|
2591
|
+
}
|
|
2592
|
+
if (C.right) {
|
|
2593
|
+
C.right.parent = A;
|
|
2594
|
+
}
|
|
2595
|
+
C.parent = parentOfA;
|
|
2596
|
+
}
|
|
2597
|
+
if (A === this.root) {
|
|
2598
|
+
if (C) this._setRoot(C);
|
|
2599
|
+
} else {
|
|
2600
|
+
if (parentOfA) {
|
|
2601
|
+
if (parentOfA.left === A) {
|
|
2602
|
+
parentOfA.left = C;
|
|
2603
|
+
} else {
|
|
2604
|
+
parentOfA.right = C;
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
}
|
|
2608
|
+
if (C) {
|
|
2609
|
+
A.left = C.right;
|
|
2610
|
+
if (B) B.right = C.left;
|
|
2611
|
+
C.left = B;
|
|
2612
|
+
C.right = A;
|
|
2613
|
+
}
|
|
2614
|
+
this._updateHeight(A);
|
|
2615
|
+
if (B) this._updateHeight(B);
|
|
2616
|
+
if (C) this._updateHeight(C);
|
|
2617
|
+
}
|
|
2618
|
+
_balanceRR(A) {
|
|
2619
|
+
const parentOfA = A.parent;
|
|
2620
|
+
const B = A.right;
|
|
2621
|
+
if (B !== null) A.parent = B;
|
|
2622
|
+
if (B) {
|
|
2623
|
+
if (B.left) {
|
|
2624
|
+
B.left.parent = A;
|
|
2625
|
+
}
|
|
2626
|
+
B.parent = parentOfA;
|
|
2627
|
+
}
|
|
2628
|
+
if (A === this.root) {
|
|
2629
|
+
if (B) this._setRoot(B);
|
|
2630
|
+
} else {
|
|
2631
|
+
if (parentOfA) {
|
|
2632
|
+
if (parentOfA.left === A) {
|
|
2633
|
+
parentOfA.left = B;
|
|
2634
|
+
} else {
|
|
2635
|
+
parentOfA.right = B;
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2639
|
+
if (B) {
|
|
2640
|
+
A.right = B.left;
|
|
2641
|
+
B.left = A;
|
|
2642
|
+
}
|
|
2643
|
+
this._updateHeight(A);
|
|
2644
|
+
if (B) this._updateHeight(B);
|
|
2645
|
+
}
|
|
2646
|
+
_balanceRL(A) {
|
|
2647
|
+
const parentOfA = A.parent;
|
|
2648
|
+
const B = A.right;
|
|
2649
|
+
let C = void 0;
|
|
2650
|
+
if (B) {
|
|
2651
|
+
C = B.left;
|
|
2652
|
+
}
|
|
2653
|
+
if (C !== null) A.parent = C;
|
|
2654
|
+
if (B && C !== null) B.parent = C;
|
|
2655
|
+
if (C) {
|
|
2656
|
+
if (C.left) {
|
|
2657
|
+
C.left.parent = A;
|
|
2658
|
+
}
|
|
2659
|
+
if (C.right) {
|
|
2660
|
+
if (B !== null) C.right.parent = B;
|
|
2661
|
+
}
|
|
2662
|
+
C.parent = parentOfA;
|
|
2663
|
+
}
|
|
2664
|
+
if (A === this.root) {
|
|
2665
|
+
if (C) this._setRoot(C);
|
|
2666
|
+
} else {
|
|
2667
|
+
if (parentOfA) {
|
|
2668
|
+
if (parentOfA.left === A) {
|
|
2669
|
+
parentOfA.left = C;
|
|
2670
|
+
} else {
|
|
2671
|
+
parentOfA.right = C;
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
}
|
|
2675
|
+
if (C) A.right = C.left;
|
|
2676
|
+
if (B && C) B.left = C.right;
|
|
2677
|
+
if (C) C.left = A;
|
|
2678
|
+
if (C) C.right = B;
|
|
2679
|
+
this._updateHeight(A);
|
|
2680
|
+
if (B) this._updateHeight(B);
|
|
2681
|
+
if (C) this._updateHeight(C);
|
|
2682
|
+
}
|
|
2683
|
+
_balancePath(node) {
|
|
2684
|
+
node = this.ensureNode(node);
|
|
2685
|
+
const path = this.getPathToRoot(node, (node2) => node2, false);
|
|
2686
|
+
for (let i = 0; i < path.length; i++) {
|
|
2687
|
+
const A = path[i];
|
|
2688
|
+
if (A) {
|
|
2689
|
+
this._updateHeight(A);
|
|
2690
|
+
switch (this._balanceFactor(A)) {
|
|
2691
|
+
case -2:
|
|
2692
|
+
if (A && A.left) {
|
|
2693
|
+
if (this._balanceFactor(A.left) <= 0) {
|
|
2694
|
+
this._balanceLL(A);
|
|
2695
|
+
} else {
|
|
2696
|
+
this._balanceLR(A);
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
break;
|
|
2700
|
+
case 2:
|
|
2701
|
+
if (A && A.right) {
|
|
2702
|
+
if (this._balanceFactor(A.right) >= 0) {
|
|
2703
|
+
this._balanceRR(A);
|
|
2704
|
+
} else {
|
|
2705
|
+
this._balanceRL(A);
|
|
2706
|
+
}
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
}
|
|
2711
|
+
}
|
|
2712
|
+
_replaceNode(oldNode, newNode) {
|
|
2713
|
+
newNode.height = oldNode.height;
|
|
2714
|
+
return super._replaceNode(oldNode, newNode);
|
|
2715
|
+
}
|
|
2716
|
+
};
|
|
2717
|
+
var AVLTreeMultiMapNode = class {
|
|
2718
|
+
static {
|
|
2719
|
+
__name(this, "AVLTreeMultiMapNode");
|
|
2720
|
+
}
|
|
2721
|
+
key;
|
|
2722
|
+
value;
|
|
2723
|
+
parent = void 0;
|
|
2724
|
+
constructor(key, value = []) {
|
|
2725
|
+
this.key = key;
|
|
2726
|
+
this.value = value;
|
|
2727
|
+
}
|
|
2728
|
+
_left = void 0;
|
|
2729
|
+
get left() {
|
|
2730
|
+
return this._left;
|
|
2731
|
+
}
|
|
2732
|
+
set left(v) {
|
|
2733
|
+
if (v) {
|
|
2734
|
+
v.parent = this;
|
|
2735
|
+
}
|
|
2736
|
+
this._left = v;
|
|
2737
|
+
}
|
|
2738
|
+
_right = void 0;
|
|
2739
|
+
get right() {
|
|
2740
|
+
return this._right;
|
|
2741
|
+
}
|
|
2742
|
+
set right(v) {
|
|
2743
|
+
if (v) {
|
|
2744
|
+
v.parent = this;
|
|
2745
|
+
}
|
|
2746
|
+
this._right = v;
|
|
2747
|
+
}
|
|
2748
|
+
_height = 0;
|
|
2749
|
+
get height() {
|
|
2750
|
+
return this._height;
|
|
2751
|
+
}
|
|
2752
|
+
set height(value) {
|
|
2753
|
+
this._height = value;
|
|
2754
|
+
}
|
|
2755
|
+
_color = "BLACK";
|
|
2756
|
+
get color() {
|
|
2757
|
+
return this._color;
|
|
2758
|
+
}
|
|
2759
|
+
set color(value) {
|
|
2760
|
+
this._color = value;
|
|
2761
|
+
}
|
|
2762
|
+
_count = 1;
|
|
2763
|
+
get count() {
|
|
2764
|
+
return this._count;
|
|
2765
|
+
}
|
|
2766
|
+
set count(value) {
|
|
2767
|
+
this._count = value;
|
|
2768
|
+
}
|
|
2769
|
+
get familyPosition() {
|
|
2770
|
+
if (!this.parent) {
|
|
2771
|
+
return this.left || this.right ? "ROOT" : "ISOLATED";
|
|
2772
|
+
}
|
|
2773
|
+
if (this.parent.left === this) {
|
|
2774
|
+
return this.left || this.right ? "ROOT_LEFT" : "LEFT";
|
|
2775
|
+
} else if (this.parent.right === this) {
|
|
2776
|
+
return this.left || this.right ? "ROOT_RIGHT" : "RIGHT";
|
|
2777
|
+
}
|
|
2778
|
+
return "MAL_NODE";
|
|
2779
|
+
}
|
|
2780
|
+
};
|
|
2781
|
+
var AVLTreeMultiMap = class extends AVLTree {
|
|
2782
|
+
static {
|
|
2783
|
+
__name(this, "AVLTreeMultiMap");
|
|
2784
|
+
}
|
|
2785
|
+
constructor(keysNodesEntriesOrRaws = [], options) {
|
|
2786
|
+
super([], { ...options, isMapMode: true });
|
|
2787
|
+
if (keysNodesEntriesOrRaws) {
|
|
2788
|
+
this.setMany(keysNodesEntriesOrRaws);
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
createNode(key, value = []) {
|
|
2792
|
+
return new AVLTreeMultiMapNode(key, this._isMapMode ? [] : value);
|
|
2793
|
+
}
|
|
2794
|
+
isNode(keyNodeOrEntry) {
|
|
2795
|
+
return keyNodeOrEntry instanceof AVLTreeMultiMapNode;
|
|
2796
|
+
}
|
|
2797
|
+
set(keyNodeOrEntry, value) {
|
|
2798
|
+
if (this.isRealNode(keyNodeOrEntry)) return super.set(keyNodeOrEntry);
|
|
2799
|
+
const _commonAdd = __name((key, values) => {
|
|
2800
|
+
if (key === void 0 || key === null) return false;
|
|
2801
|
+
const _setToValues = __name(() => {
|
|
2802
|
+
const existingValues = this.get(key);
|
|
2803
|
+
if (existingValues !== void 0 && values !== void 0) {
|
|
2804
|
+
for (const value2 of values) existingValues.push(value2);
|
|
2805
|
+
return true;
|
|
2806
|
+
}
|
|
2807
|
+
return false;
|
|
2808
|
+
}, "_setToValues");
|
|
2809
|
+
const _setByNode = __name(() => {
|
|
2810
|
+
const existingNode = this.getNode(key);
|
|
2811
|
+
if (this.isRealNode(existingNode)) {
|
|
2812
|
+
const existingValues = this.get(existingNode);
|
|
2813
|
+
if (existingValues === void 0) {
|
|
2814
|
+
super.set(key, values);
|
|
2815
|
+
return true;
|
|
2816
|
+
}
|
|
2817
|
+
if (values !== void 0) {
|
|
2818
|
+
for (const value2 of values) existingValues.push(value2);
|
|
2819
|
+
return true;
|
|
2820
|
+
} else {
|
|
2821
|
+
return false;
|
|
2822
|
+
}
|
|
2823
|
+
} else {
|
|
2824
|
+
return super.set(key, values);
|
|
2825
|
+
}
|
|
2826
|
+
}, "_setByNode");
|
|
2827
|
+
if (this._isMapMode) {
|
|
2828
|
+
return _setByNode() || _setToValues();
|
|
2829
|
+
}
|
|
2830
|
+
return _setToValues() || _setByNode();
|
|
2831
|
+
}, "_commonAdd");
|
|
2832
|
+
if (this.isEntry(keyNodeOrEntry)) {
|
|
2833
|
+
const [key, values] = keyNodeOrEntry;
|
|
2834
|
+
return _commonAdd(key, value !== void 0 ? [value] : values);
|
|
2835
|
+
}
|
|
2836
|
+
return _commonAdd(keyNodeOrEntry, value !== void 0 ? [value] : void 0);
|
|
2837
|
+
}
|
|
2838
|
+
deleteValue(keyNodeOrEntry, value) {
|
|
2839
|
+
const values = this.get(keyNodeOrEntry);
|
|
2840
|
+
if (Array.isArray(values)) {
|
|
2841
|
+
const index = values.indexOf(value);
|
|
2842
|
+
if (index === -1) return false;
|
|
2843
|
+
values.splice(index, 1);
|
|
2844
|
+
if (values.length === 0) this.delete(keyNodeOrEntry);
|
|
2845
|
+
return true;
|
|
2846
|
+
}
|
|
2847
|
+
return false;
|
|
2848
|
+
}
|
|
2849
|
+
perfectlyBalance(iterationType = this.iterationType) {
|
|
2850
|
+
const nodes = this.dfs((node) => node, "IN", false, this._root, iterationType);
|
|
2851
|
+
const n = nodes.length;
|
|
2852
|
+
if (n === 0) return false;
|
|
2853
|
+
this._clearNodes();
|
|
2854
|
+
const build = __name((l, r, parent) => {
|
|
2855
|
+
if (l > r) return void 0;
|
|
2856
|
+
const m = l + (r - l >> 1);
|
|
2857
|
+
const root = nodes[m];
|
|
2858
|
+
root.left = build(l, m - 1, root);
|
|
2859
|
+
root.right = build(m + 1, r, root);
|
|
2860
|
+
root.parent = parent;
|
|
2861
|
+
const lh = root.left ? root.left.height : -1;
|
|
2862
|
+
const rh = root.right ? root.right.height : -1;
|
|
2863
|
+
root.height = Math.max(lh, rh) + 1;
|
|
2864
|
+
return root;
|
|
2865
|
+
}, "build");
|
|
2866
|
+
const newRoot = build(0, n - 1, void 0);
|
|
2867
|
+
this._setRoot(newRoot);
|
|
2868
|
+
this._size = n;
|
|
2869
|
+
return true;
|
|
2870
|
+
}
|
|
2871
|
+
map(callback, options, thisArg) {
|
|
2872
|
+
const out = this._createLike([], options);
|
|
2873
|
+
let i = 0;
|
|
2874
|
+
for (const [k, v] of this) out.set(callback.call(thisArg, v, k, i++, this));
|
|
2875
|
+
return out;
|
|
2876
|
+
}
|
|
2877
|
+
_createInstance(options) {
|
|
2878
|
+
const Ctor = this.constructor;
|
|
2879
|
+
return new Ctor([], { ...this._snapshotOptions?.() ?? {}, ...options ?? {} });
|
|
2880
|
+
}
|
|
2881
|
+
_createLike(iter = [], options) {
|
|
2882
|
+
const Ctor = this.constructor;
|
|
2883
|
+
return new Ctor(iter, { ...this._snapshotOptions?.() ?? {}, ...options ?? {} });
|
|
2884
|
+
}
|
|
2885
|
+
};
|
|
2886
|
+
export {
|
|
2887
|
+
AVLTreeMultiMap,
|
|
2888
|
+
AVLTreeMultiMapNode
|
|
2889
|
+
};
|