data-structure-typed 2.2.6 → 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/CONTRIBUTING.md +47 -1
- package/README.md +19 -8
- package/README_CN.md +119 -275
- package/benchmark/report.html +1 -1
- package/benchmark/report.json +20 -324
- package/dist/cjs/index.cjs +109 -107
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +109 -107
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +109 -107
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +109 -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 +105 -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.leetcode.config.js +1 -1
- package/tsup.umd.config.js +29 -0
- package/tsup.node.config.js +0 -83
|
@@ -0,0 +1,1733 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
var uuidV4 = __name(function() {
|
|
4
|
+
return "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".replace(/[x]/g, function(c) {
|
|
5
|
+
const r = Math.random() * 16 | 0, v = c == "x" ? r : r & 3 | 8;
|
|
6
|
+
return v.toString(16);
|
|
7
|
+
});
|
|
8
|
+
}, "uuidV4");
|
|
9
|
+
var arrayRemove = __name(function(array, predicate) {
|
|
10
|
+
let i = -1, len = array ? array.length : 0;
|
|
11
|
+
const result = [];
|
|
12
|
+
while (++i < len) {
|
|
13
|
+
const value = array[i];
|
|
14
|
+
if (predicate(value, i, array)) {
|
|
15
|
+
result.push(value);
|
|
16
|
+
Array.prototype.splice.call(array, i--, 1);
|
|
17
|
+
len--;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}, "arrayRemove");
|
|
22
|
+
var IterableEntryBase = class {
|
|
23
|
+
static {
|
|
24
|
+
__name(this, "IterableEntryBase");
|
|
25
|
+
}
|
|
26
|
+
*[Symbol.iterator](...args) {
|
|
27
|
+
yield* this._getIterator(...args);
|
|
28
|
+
}
|
|
29
|
+
*entries() {
|
|
30
|
+
for (const item of this) {
|
|
31
|
+
yield item;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
*keys() {
|
|
35
|
+
for (const item of this) {
|
|
36
|
+
yield item[0];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
*values() {
|
|
40
|
+
for (const item of this) {
|
|
41
|
+
yield item[1];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
every(predicate, thisArg) {
|
|
45
|
+
let index = 0;
|
|
46
|
+
for (const item of this) {
|
|
47
|
+
if (!predicate.call(thisArg, item[1], item[0], index++, this)) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
some(predicate, thisArg) {
|
|
54
|
+
let index = 0;
|
|
55
|
+
for (const item of this) {
|
|
56
|
+
if (predicate.call(thisArg, item[1], item[0], index++, this)) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
forEach(callbackfn, thisArg) {
|
|
63
|
+
let index = 0;
|
|
64
|
+
for (const item of this) {
|
|
65
|
+
const [key, value] = item;
|
|
66
|
+
callbackfn.call(thisArg, value, key, index++, this);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
find(callbackfn, thisArg) {
|
|
70
|
+
let index = 0;
|
|
71
|
+
for (const item of this) {
|
|
72
|
+
const [key, value] = item;
|
|
73
|
+
if (callbackfn.call(thisArg, value, key, index++, this)) return item;
|
|
74
|
+
}
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
has(key) {
|
|
78
|
+
for (const item of this) {
|
|
79
|
+
const [itemKey] = item;
|
|
80
|
+
if (itemKey === key) return true;
|
|
81
|
+
}
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
hasValue(value) {
|
|
85
|
+
for (const [, elementValue] of this) {
|
|
86
|
+
if (elementValue === value) return true;
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
get(key) {
|
|
91
|
+
for (const item of this) {
|
|
92
|
+
const [itemKey, value] = item;
|
|
93
|
+
if (itemKey === key) return value;
|
|
94
|
+
}
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
reduce(callbackfn, initialValue) {
|
|
98
|
+
let accumulator = initialValue;
|
|
99
|
+
let index = 0;
|
|
100
|
+
for (const item of this) {
|
|
101
|
+
const [key, value] = item;
|
|
102
|
+
accumulator = callbackfn(accumulator, value, key, index++, this);
|
|
103
|
+
}
|
|
104
|
+
return accumulator;
|
|
105
|
+
}
|
|
106
|
+
toArray() {
|
|
107
|
+
return [...this];
|
|
108
|
+
}
|
|
109
|
+
toVisual() {
|
|
110
|
+
return [...this];
|
|
111
|
+
}
|
|
112
|
+
print() {
|
|
113
|
+
console.log(this.toVisual());
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
var IterableElementBase = class {
|
|
117
|
+
static {
|
|
118
|
+
__name(this, "IterableElementBase");
|
|
119
|
+
}
|
|
120
|
+
constructor(options) {
|
|
121
|
+
if (options) {
|
|
122
|
+
const { toElementFn } = options;
|
|
123
|
+
if (typeof toElementFn === "function") this._toElementFn = toElementFn;
|
|
124
|
+
else if (toElementFn) throw new TypeError("toElementFn must be a function type");
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
_toElementFn;
|
|
128
|
+
get toElementFn() {
|
|
129
|
+
return this._toElementFn;
|
|
130
|
+
}
|
|
131
|
+
*[Symbol.iterator](...args) {
|
|
132
|
+
yield* this._getIterator(...args);
|
|
133
|
+
}
|
|
134
|
+
*values() {
|
|
135
|
+
for (const item of this) yield item;
|
|
136
|
+
}
|
|
137
|
+
every(predicate, thisArg) {
|
|
138
|
+
let index = 0;
|
|
139
|
+
for (const item of this) {
|
|
140
|
+
if (thisArg === void 0) {
|
|
141
|
+
if (!predicate(item, index++, this)) return false;
|
|
142
|
+
} else {
|
|
143
|
+
const fn = predicate;
|
|
144
|
+
if (!fn.call(thisArg, item, index++, this)) return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
some(predicate, thisArg) {
|
|
150
|
+
let index = 0;
|
|
151
|
+
for (const item of this) {
|
|
152
|
+
if (thisArg === void 0) {
|
|
153
|
+
if (predicate(item, index++, this)) return true;
|
|
154
|
+
} else {
|
|
155
|
+
const fn = predicate;
|
|
156
|
+
if (fn.call(thisArg, item, index++, this)) return true;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
forEach(callbackfn, thisArg) {
|
|
162
|
+
let index = 0;
|
|
163
|
+
for (const item of this) {
|
|
164
|
+
if (thisArg === void 0) {
|
|
165
|
+
callbackfn(item, index++, this);
|
|
166
|
+
} else {
|
|
167
|
+
const fn = callbackfn;
|
|
168
|
+
fn.call(thisArg, item, index++, this);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
find(predicate, thisArg) {
|
|
173
|
+
let index = 0;
|
|
174
|
+
for (const item of this) {
|
|
175
|
+
if (thisArg === void 0) {
|
|
176
|
+
if (predicate(item, index++, this)) return item;
|
|
177
|
+
} else {
|
|
178
|
+
const fn = predicate;
|
|
179
|
+
if (fn.call(thisArg, item, index++, this)) return item;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
has(element) {
|
|
185
|
+
for (const ele of this) if (ele === element) return true;
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
reduce(callbackfn, initialValue) {
|
|
189
|
+
let index = 0;
|
|
190
|
+
const iter = this[Symbol.iterator]();
|
|
191
|
+
let acc;
|
|
192
|
+
if (arguments.length >= 2) {
|
|
193
|
+
acc = initialValue;
|
|
194
|
+
} else {
|
|
195
|
+
const first = iter.next();
|
|
196
|
+
if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
|
|
197
|
+
acc = first.value;
|
|
198
|
+
index = 1;
|
|
199
|
+
}
|
|
200
|
+
for (const value of iter) {
|
|
201
|
+
acc = callbackfn(acc, value, index++, this);
|
|
202
|
+
}
|
|
203
|
+
return acc;
|
|
204
|
+
}
|
|
205
|
+
toArray() {
|
|
206
|
+
return [...this];
|
|
207
|
+
}
|
|
208
|
+
toVisual() {
|
|
209
|
+
return [...this];
|
|
210
|
+
}
|
|
211
|
+
print() {
|
|
212
|
+
console.log(this.toVisual());
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
var Heap = class _Heap extends IterableElementBase {
|
|
216
|
+
static {
|
|
217
|
+
__name(this, "Heap");
|
|
218
|
+
}
|
|
219
|
+
_equals = Object.is;
|
|
220
|
+
constructor(elements = [], options) {
|
|
221
|
+
super(options);
|
|
222
|
+
if (options) {
|
|
223
|
+
const { comparator } = options;
|
|
224
|
+
if (comparator) this._comparator = comparator;
|
|
225
|
+
}
|
|
226
|
+
this.addMany(elements);
|
|
227
|
+
}
|
|
228
|
+
_elements = [];
|
|
229
|
+
get elements() {
|
|
230
|
+
return this._elements;
|
|
231
|
+
}
|
|
232
|
+
get size() {
|
|
233
|
+
return this.elements.length;
|
|
234
|
+
}
|
|
235
|
+
get leaf() {
|
|
236
|
+
return this.elements[this.size - 1] ?? void 0;
|
|
237
|
+
}
|
|
238
|
+
static from(elements, options) {
|
|
239
|
+
return new this(elements, options);
|
|
240
|
+
}
|
|
241
|
+
static heapify(elements, options) {
|
|
242
|
+
return new _Heap(elements, options);
|
|
243
|
+
}
|
|
244
|
+
add(element) {
|
|
245
|
+
this._elements.push(element);
|
|
246
|
+
return this._bubbleUp(this.elements.length - 1);
|
|
247
|
+
}
|
|
248
|
+
addMany(elements) {
|
|
249
|
+
const flags = [];
|
|
250
|
+
for (const el of elements) {
|
|
251
|
+
if (this.toElementFn) {
|
|
252
|
+
const ok = this.add(this.toElementFn(el));
|
|
253
|
+
flags.push(ok);
|
|
254
|
+
} else {
|
|
255
|
+
const ok = this.add(el);
|
|
256
|
+
flags.push(ok);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return flags;
|
|
260
|
+
}
|
|
261
|
+
poll() {
|
|
262
|
+
if (this.elements.length === 0) return;
|
|
263
|
+
const value = this.elements[0];
|
|
264
|
+
const last = this.elements.pop();
|
|
265
|
+
if (this.elements.length) {
|
|
266
|
+
this.elements[0] = last;
|
|
267
|
+
this._sinkDown(0, this.elements.length >> 1);
|
|
268
|
+
}
|
|
269
|
+
return value;
|
|
270
|
+
}
|
|
271
|
+
peek() {
|
|
272
|
+
return this.elements[0];
|
|
273
|
+
}
|
|
274
|
+
isEmpty() {
|
|
275
|
+
return this.size === 0;
|
|
276
|
+
}
|
|
277
|
+
clear() {
|
|
278
|
+
this._elements = [];
|
|
279
|
+
}
|
|
280
|
+
refill(elements) {
|
|
281
|
+
this._elements = Array.from(elements);
|
|
282
|
+
return this.fix();
|
|
283
|
+
}
|
|
284
|
+
has(element) {
|
|
285
|
+
for (const el of this.elements) if (this._equals(el, element)) return true;
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
delete(element) {
|
|
289
|
+
let index = -1;
|
|
290
|
+
for (let i = 0; i < this.elements.length; i++) {
|
|
291
|
+
if (this._equals(this.elements[i], element)) {
|
|
292
|
+
index = i;
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
if (index < 0) return false;
|
|
297
|
+
if (index === 0) {
|
|
298
|
+
this.poll();
|
|
299
|
+
} else if (index === this.elements.length - 1) {
|
|
300
|
+
this.elements.pop();
|
|
301
|
+
} else {
|
|
302
|
+
this.elements.splice(index, 1, this.elements.pop());
|
|
303
|
+
this._bubbleUp(index);
|
|
304
|
+
this._sinkDown(index, this.elements.length >> 1);
|
|
305
|
+
}
|
|
306
|
+
return true;
|
|
307
|
+
}
|
|
308
|
+
deleteBy(predicate) {
|
|
309
|
+
let idx = -1;
|
|
310
|
+
for (let i = 0; i < this.elements.length; i++) {
|
|
311
|
+
if (predicate(this.elements[i], i, this)) {
|
|
312
|
+
idx = i;
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if (idx < 0) return false;
|
|
317
|
+
if (idx === 0) {
|
|
318
|
+
this.poll();
|
|
319
|
+
} else if (idx === this.elements.length - 1) {
|
|
320
|
+
this.elements.pop();
|
|
321
|
+
} else {
|
|
322
|
+
this.elements.splice(idx, 1, this.elements.pop());
|
|
323
|
+
this._bubbleUp(idx);
|
|
324
|
+
this._sinkDown(idx, this.elements.length >> 1);
|
|
325
|
+
}
|
|
326
|
+
return true;
|
|
327
|
+
}
|
|
328
|
+
setEquality(equals) {
|
|
329
|
+
this._equals = equals;
|
|
330
|
+
return this;
|
|
331
|
+
}
|
|
332
|
+
dfs(order = "PRE") {
|
|
333
|
+
const result = [];
|
|
334
|
+
const _dfs = __name((index) => {
|
|
335
|
+
const left = 2 * index + 1, right = left + 1;
|
|
336
|
+
if (index < this.size) {
|
|
337
|
+
if (order === "IN") {
|
|
338
|
+
_dfs(left);
|
|
339
|
+
result.push(this.elements[index]);
|
|
340
|
+
_dfs(right);
|
|
341
|
+
} else if (order === "PRE") {
|
|
342
|
+
result.push(this.elements[index]);
|
|
343
|
+
_dfs(left);
|
|
344
|
+
_dfs(right);
|
|
345
|
+
} else if (order === "POST") {
|
|
346
|
+
_dfs(left);
|
|
347
|
+
_dfs(right);
|
|
348
|
+
result.push(this.elements[index]);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}, "_dfs");
|
|
352
|
+
_dfs(0);
|
|
353
|
+
return result;
|
|
354
|
+
}
|
|
355
|
+
fix() {
|
|
356
|
+
const results = [];
|
|
357
|
+
for (let i = Math.floor(this.size / 2) - 1; i >= 0; i--) {
|
|
358
|
+
results.push(this._sinkDown(i, this.elements.length >> 1));
|
|
359
|
+
}
|
|
360
|
+
return results;
|
|
361
|
+
}
|
|
362
|
+
sort() {
|
|
363
|
+
const visited = [];
|
|
364
|
+
const cloned = this._createInstance();
|
|
365
|
+
for (const x of this.elements) cloned.add(x);
|
|
366
|
+
while (!cloned.isEmpty()) {
|
|
367
|
+
const top = cloned.poll();
|
|
368
|
+
if (top !== void 0) visited.push(top);
|
|
369
|
+
}
|
|
370
|
+
return visited;
|
|
371
|
+
}
|
|
372
|
+
clone() {
|
|
373
|
+
const next = this._createInstance();
|
|
374
|
+
for (const x of this.elements) next.add(x);
|
|
375
|
+
return next;
|
|
376
|
+
}
|
|
377
|
+
filter(callback, thisArg) {
|
|
378
|
+
const out = this._createInstance();
|
|
379
|
+
let i = 0;
|
|
380
|
+
for (const x of this) {
|
|
381
|
+
if (thisArg === void 0 ? callback(x, i++, this) : callback.call(thisArg, x, i++, this)) {
|
|
382
|
+
out.add(x);
|
|
383
|
+
} else {
|
|
384
|
+
i++;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return out;
|
|
388
|
+
}
|
|
389
|
+
map(callback, options, thisArg) {
|
|
390
|
+
const { comparator, toElementFn, ...rest } = options ?? {};
|
|
391
|
+
if (!comparator) throw new TypeError("Heap.map requires options.comparator for EM");
|
|
392
|
+
const out = this._createLike([], { ...rest, comparator, toElementFn });
|
|
393
|
+
let i = 0;
|
|
394
|
+
for (const x of this) {
|
|
395
|
+
const v = thisArg === void 0 ? callback(x, i++, this) : callback.call(thisArg, x, i++, this);
|
|
396
|
+
out.add(v);
|
|
397
|
+
}
|
|
398
|
+
return out;
|
|
399
|
+
}
|
|
400
|
+
mapSame(callback, thisArg) {
|
|
401
|
+
const out = this._createInstance();
|
|
402
|
+
let i = 0;
|
|
403
|
+
for (const x of this) {
|
|
404
|
+
const v = thisArg === void 0 ? callback(x, i++, this) : callback.call(thisArg, x, i++, this);
|
|
405
|
+
out.add(v);
|
|
406
|
+
}
|
|
407
|
+
return out;
|
|
408
|
+
}
|
|
409
|
+
_DEFAULT_COMPARATOR = __name((a, b) => {
|
|
410
|
+
if (typeof a === "object" || typeof b === "object") {
|
|
411
|
+
throw TypeError("When comparing object types, define a custom comparator in options.");
|
|
412
|
+
}
|
|
413
|
+
if (a > b) return 1;
|
|
414
|
+
if (a < b) return -1;
|
|
415
|
+
return 0;
|
|
416
|
+
}, "_DEFAULT_COMPARATOR");
|
|
417
|
+
_comparator = this._DEFAULT_COMPARATOR;
|
|
418
|
+
get comparator() {
|
|
419
|
+
return this._comparator;
|
|
420
|
+
}
|
|
421
|
+
*_getIterator() {
|
|
422
|
+
for (const element of this.elements) yield element;
|
|
423
|
+
}
|
|
424
|
+
_bubbleUp(index) {
|
|
425
|
+
const element = this.elements[index];
|
|
426
|
+
while (index > 0) {
|
|
427
|
+
const parent = index - 1 >> 1;
|
|
428
|
+
const parentItem = this.elements[parent];
|
|
429
|
+
if (this.comparator(parentItem, element) <= 0) break;
|
|
430
|
+
this.elements[index] = parentItem;
|
|
431
|
+
index = parent;
|
|
432
|
+
}
|
|
433
|
+
this.elements[index] = element;
|
|
434
|
+
return true;
|
|
435
|
+
}
|
|
436
|
+
_sinkDown(index, halfLength) {
|
|
437
|
+
const element = this.elements[index];
|
|
438
|
+
while (index < halfLength) {
|
|
439
|
+
let left = index << 1 | 1;
|
|
440
|
+
const right = left + 1;
|
|
441
|
+
let minItem = this.elements[left];
|
|
442
|
+
if (right < this.elements.length && this.comparator(minItem, this.elements[right]) > 0) {
|
|
443
|
+
left = right;
|
|
444
|
+
minItem = this.elements[right];
|
|
445
|
+
}
|
|
446
|
+
if (this.comparator(minItem, element) >= 0) break;
|
|
447
|
+
this.elements[index] = minItem;
|
|
448
|
+
index = left;
|
|
449
|
+
}
|
|
450
|
+
this.elements[index] = element;
|
|
451
|
+
return true;
|
|
452
|
+
}
|
|
453
|
+
_createInstance(options) {
|
|
454
|
+
const Ctor = this.constructor;
|
|
455
|
+
const next = new Ctor([], { comparator: this.comparator, toElementFn: this.toElementFn, ...options ?? {} });
|
|
456
|
+
return next;
|
|
457
|
+
}
|
|
458
|
+
_createLike(elements = [], options) {
|
|
459
|
+
const Ctor = this.constructor;
|
|
460
|
+
return new Ctor(elements, options);
|
|
461
|
+
}
|
|
462
|
+
_spawnLike(options) {
|
|
463
|
+
return this._createLike([], options);
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
var LinearBase = class _LinearBase extends IterableElementBase {
|
|
467
|
+
static {
|
|
468
|
+
__name(this, "LinearBase");
|
|
469
|
+
}
|
|
470
|
+
constructor(options) {
|
|
471
|
+
super(options);
|
|
472
|
+
if (options) {
|
|
473
|
+
const { maxLen } = options;
|
|
474
|
+
if (typeof maxLen === "number" && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
_maxLen = -1;
|
|
478
|
+
get maxLen() {
|
|
479
|
+
return this._maxLen;
|
|
480
|
+
}
|
|
481
|
+
indexOf(searchElement, fromIndex = 0) {
|
|
482
|
+
if (this.length === 0) return -1;
|
|
483
|
+
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
484
|
+
if (fromIndex < 0) fromIndex = 0;
|
|
485
|
+
for (let i = fromIndex; i < this.length; i++) {
|
|
486
|
+
const element = this.at(i);
|
|
487
|
+
if (element === searchElement) return i;
|
|
488
|
+
}
|
|
489
|
+
return -1;
|
|
490
|
+
}
|
|
491
|
+
lastIndexOf(searchElement, fromIndex = this.length - 1) {
|
|
492
|
+
if (this.length === 0) return -1;
|
|
493
|
+
if (fromIndex >= this.length) fromIndex = this.length - 1;
|
|
494
|
+
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
495
|
+
for (let i = fromIndex; i >= 0; i--) {
|
|
496
|
+
const element = this.at(i);
|
|
497
|
+
if (element === searchElement) return i;
|
|
498
|
+
}
|
|
499
|
+
return -1;
|
|
500
|
+
}
|
|
501
|
+
findIndex(predicate, thisArg) {
|
|
502
|
+
for (let i = 0; i < this.length; i++) {
|
|
503
|
+
const item = this.at(i);
|
|
504
|
+
if (item !== void 0 && predicate.call(thisArg, item, i, this)) return i;
|
|
505
|
+
}
|
|
506
|
+
return -1;
|
|
507
|
+
}
|
|
508
|
+
concat(...items) {
|
|
509
|
+
const newList = this.clone();
|
|
510
|
+
for (const item of items) {
|
|
511
|
+
if (item instanceof _LinearBase) {
|
|
512
|
+
newList.pushMany(item);
|
|
513
|
+
} else {
|
|
514
|
+
newList.push(item);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
return newList;
|
|
518
|
+
}
|
|
519
|
+
sort(compareFn) {
|
|
520
|
+
const arr = this.toArray();
|
|
521
|
+
arr.sort(compareFn);
|
|
522
|
+
this.clear();
|
|
523
|
+
for (const item of arr) this.push(item);
|
|
524
|
+
return this;
|
|
525
|
+
}
|
|
526
|
+
splice(start, deleteCount = 0, ...items) {
|
|
527
|
+
const removedList = this._createInstance();
|
|
528
|
+
start = start < 0 ? this.length + start : start;
|
|
529
|
+
start = Math.max(0, Math.min(start, this.length));
|
|
530
|
+
deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
|
|
531
|
+
for (let i = 0; i < deleteCount; i++) {
|
|
532
|
+
const removed = this.deleteAt(start);
|
|
533
|
+
if (removed !== void 0) {
|
|
534
|
+
removedList.push(removed);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
for (let i = 0; i < items.length; i++) {
|
|
538
|
+
this.addAt(start + i, items[i]);
|
|
539
|
+
}
|
|
540
|
+
return removedList;
|
|
541
|
+
}
|
|
542
|
+
join(separator = ",") {
|
|
543
|
+
return this.toArray().join(separator);
|
|
544
|
+
}
|
|
545
|
+
toReversedArray() {
|
|
546
|
+
const array = [];
|
|
547
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
548
|
+
array.push(this.at(i));
|
|
549
|
+
}
|
|
550
|
+
return array;
|
|
551
|
+
}
|
|
552
|
+
reduceRight(callbackfn, initialValue) {
|
|
553
|
+
let accumulator = initialValue ?? 0;
|
|
554
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
555
|
+
accumulator = callbackfn(accumulator, this.at(i), i, this);
|
|
556
|
+
}
|
|
557
|
+
return accumulator;
|
|
558
|
+
}
|
|
559
|
+
slice(start = 0, end = this.length) {
|
|
560
|
+
start = start < 0 ? this.length + start : start;
|
|
561
|
+
end = end < 0 ? this.length + end : end;
|
|
562
|
+
const newList = this._createInstance();
|
|
563
|
+
for (let i = start; i < end; i++) {
|
|
564
|
+
newList.push(this.at(i));
|
|
565
|
+
}
|
|
566
|
+
return newList;
|
|
567
|
+
}
|
|
568
|
+
fill(value, start = 0, end = this.length) {
|
|
569
|
+
start = start < 0 ? this.length + start : start;
|
|
570
|
+
end = end < 0 ? this.length + end : end;
|
|
571
|
+
if (start < 0) start = 0;
|
|
572
|
+
if (end > this.length) end = this.length;
|
|
573
|
+
if (start >= end) return this;
|
|
574
|
+
for (let i = start; i < end; i++) {
|
|
575
|
+
this.setAt(i, value);
|
|
576
|
+
}
|
|
577
|
+
return this;
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
var Queue = class _Queue extends LinearBase {
|
|
581
|
+
static {
|
|
582
|
+
__name(this, "Queue");
|
|
583
|
+
}
|
|
584
|
+
constructor(elements = [], options) {
|
|
585
|
+
super(options);
|
|
586
|
+
if (options) {
|
|
587
|
+
const { autoCompactRatio = 0.5 } = options;
|
|
588
|
+
this._autoCompactRatio = autoCompactRatio;
|
|
589
|
+
}
|
|
590
|
+
this.pushMany(elements);
|
|
591
|
+
}
|
|
592
|
+
_elements = [];
|
|
593
|
+
get elements() {
|
|
594
|
+
return this._elements;
|
|
595
|
+
}
|
|
596
|
+
_offset = 0;
|
|
597
|
+
get offset() {
|
|
598
|
+
return this._offset;
|
|
599
|
+
}
|
|
600
|
+
_autoCompactRatio = 0.5;
|
|
601
|
+
get autoCompactRatio() {
|
|
602
|
+
return this._autoCompactRatio;
|
|
603
|
+
}
|
|
604
|
+
set autoCompactRatio(value) {
|
|
605
|
+
this._autoCompactRatio = value;
|
|
606
|
+
}
|
|
607
|
+
get length() {
|
|
608
|
+
return this.elements.length - this._offset;
|
|
609
|
+
}
|
|
610
|
+
get first() {
|
|
611
|
+
return this.length > 0 ? this.elements[this._offset] : void 0;
|
|
612
|
+
}
|
|
613
|
+
get last() {
|
|
614
|
+
return this.length > 0 ? this.elements[this.elements.length - 1] : void 0;
|
|
615
|
+
}
|
|
616
|
+
static fromArray(elements) {
|
|
617
|
+
return new _Queue(elements);
|
|
618
|
+
}
|
|
619
|
+
isEmpty() {
|
|
620
|
+
return this.length === 0;
|
|
621
|
+
}
|
|
622
|
+
push(element) {
|
|
623
|
+
this.elements.push(element);
|
|
624
|
+
if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
|
|
625
|
+
return true;
|
|
626
|
+
}
|
|
627
|
+
pushMany(elements) {
|
|
628
|
+
const ans = [];
|
|
629
|
+
for (const el of elements) {
|
|
630
|
+
if (this.toElementFn) ans.push(this.push(this.toElementFn(el)));
|
|
631
|
+
else ans.push(this.push(el));
|
|
632
|
+
}
|
|
633
|
+
return ans;
|
|
634
|
+
}
|
|
635
|
+
shift() {
|
|
636
|
+
if (this.length === 0) return void 0;
|
|
637
|
+
const first = this.first;
|
|
638
|
+
this._offset += 1;
|
|
639
|
+
if (this.elements.length > 0 && this.offset / this.elements.length > this.autoCompactRatio) this.compact();
|
|
640
|
+
return first;
|
|
641
|
+
}
|
|
642
|
+
delete(element) {
|
|
643
|
+
for (let i = this._offset; i < this.elements.length; i++) {
|
|
644
|
+
if (Object.is(this.elements[i], element)) {
|
|
645
|
+
this.elements.splice(i, 1);
|
|
646
|
+
return true;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
return false;
|
|
650
|
+
}
|
|
651
|
+
at(index) {
|
|
652
|
+
if (index < 0 || index >= this.length) return void 0;
|
|
653
|
+
return this._elements[this._offset + index];
|
|
654
|
+
}
|
|
655
|
+
deleteAt(index) {
|
|
656
|
+
if (index < 0 || index >= this.length) return void 0;
|
|
657
|
+
const gi = this._offset + index;
|
|
658
|
+
const [deleted] = this.elements.splice(gi, 1);
|
|
659
|
+
return deleted;
|
|
660
|
+
}
|
|
661
|
+
addAt(index, newElement) {
|
|
662
|
+
if (index < 0 || index > this.length) return false;
|
|
663
|
+
this._elements.splice(this._offset + index, 0, newElement);
|
|
664
|
+
return true;
|
|
665
|
+
}
|
|
666
|
+
setAt(index, newElement) {
|
|
667
|
+
if (index < 0 || index >= this.length) return false;
|
|
668
|
+
this._elements[this._offset + index] = newElement;
|
|
669
|
+
return true;
|
|
670
|
+
}
|
|
671
|
+
reverse() {
|
|
672
|
+
this._elements = this.elements.slice(this._offset).reverse();
|
|
673
|
+
this._offset = 0;
|
|
674
|
+
return this;
|
|
675
|
+
}
|
|
676
|
+
clear() {
|
|
677
|
+
this._elements = [];
|
|
678
|
+
this._offset = 0;
|
|
679
|
+
}
|
|
680
|
+
compact() {
|
|
681
|
+
this._elements = this.elements.slice(this._offset);
|
|
682
|
+
this._offset = 0;
|
|
683
|
+
return true;
|
|
684
|
+
}
|
|
685
|
+
splice(start, deleteCount = 0, ...items) {
|
|
686
|
+
start = Math.max(0, Math.min(start, this.length));
|
|
687
|
+
deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
|
|
688
|
+
const gi = this._offset + start;
|
|
689
|
+
const removedArray = this._elements.splice(gi, deleteCount, ...items);
|
|
690
|
+
if (this.elements.length > 0 && this.offset / this.elements.length > this.autoCompactRatio) this.compact();
|
|
691
|
+
const removed = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
692
|
+
removed._setAutoCompactRatio(this._autoCompactRatio);
|
|
693
|
+
removed.pushMany(removedArray);
|
|
694
|
+
return removed;
|
|
695
|
+
}
|
|
696
|
+
clone() {
|
|
697
|
+
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
698
|
+
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
699
|
+
for (let i = this._offset; i < this.elements.length; i++) out.push(this.elements[i]);
|
|
700
|
+
return out;
|
|
701
|
+
}
|
|
702
|
+
filter(predicate, thisArg) {
|
|
703
|
+
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
704
|
+
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
705
|
+
let index = 0;
|
|
706
|
+
for (const v of this) {
|
|
707
|
+
if (predicate.call(thisArg, v, index, this)) out.push(v);
|
|
708
|
+
index++;
|
|
709
|
+
}
|
|
710
|
+
return out;
|
|
711
|
+
}
|
|
712
|
+
map(callback, options, thisArg) {
|
|
713
|
+
const out = new this.constructor([], {
|
|
714
|
+
toElementFn: options?.toElementFn,
|
|
715
|
+
maxLen: options?.maxLen ?? this._maxLen,
|
|
716
|
+
autoCompactRatio: options?.autoCompactRatio ?? this._autoCompactRatio
|
|
717
|
+
});
|
|
718
|
+
let index = 0;
|
|
719
|
+
for (const v of this)
|
|
720
|
+
out.push(thisArg === void 0 ? callback(v, index++, this) : callback.call(thisArg, v, index++, this));
|
|
721
|
+
return out;
|
|
722
|
+
}
|
|
723
|
+
mapSame(callback, thisArg) {
|
|
724
|
+
const Ctor = this.constructor;
|
|
725
|
+
const out = new Ctor([], {
|
|
726
|
+
toElementFn: this.toElementFn,
|
|
727
|
+
maxLen: this._maxLen,
|
|
728
|
+
autoCompactRatio: this._autoCompactRatio
|
|
729
|
+
});
|
|
730
|
+
out._setAutoCompactRatio?.(this._autoCompactRatio);
|
|
731
|
+
let index = 0;
|
|
732
|
+
for (const v of this) {
|
|
733
|
+
const mv = thisArg === void 0 ? callback(v, index++, this) : callback.call(thisArg, v, index++, this);
|
|
734
|
+
out.push(mv);
|
|
735
|
+
}
|
|
736
|
+
return out;
|
|
737
|
+
}
|
|
738
|
+
_setAutoCompactRatio(value) {
|
|
739
|
+
this._autoCompactRatio = value;
|
|
740
|
+
}
|
|
741
|
+
*_getIterator() {
|
|
742
|
+
for (let i = this._offset; i < this.elements.length; i++) yield this.elements[i];
|
|
743
|
+
}
|
|
744
|
+
*_getReverseIterator() {
|
|
745
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
746
|
+
const cur = this.at(i);
|
|
747
|
+
if (cur !== void 0) yield cur;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
_createInstance(options) {
|
|
751
|
+
const Ctor = this.constructor;
|
|
752
|
+
return new Ctor([], options);
|
|
753
|
+
}
|
|
754
|
+
_createLike(elements = [], options) {
|
|
755
|
+
const Ctor = this.constructor;
|
|
756
|
+
return new Ctor(elements, options);
|
|
757
|
+
}
|
|
758
|
+
};
|
|
759
|
+
var AbstractVertex = class {
|
|
760
|
+
static {
|
|
761
|
+
__name(this, "AbstractVertex");
|
|
762
|
+
}
|
|
763
|
+
key;
|
|
764
|
+
value;
|
|
765
|
+
constructor(key, value) {
|
|
766
|
+
this.key = key;
|
|
767
|
+
this.value = value;
|
|
768
|
+
}
|
|
769
|
+
};
|
|
770
|
+
var AbstractEdge = class {
|
|
771
|
+
static {
|
|
772
|
+
__name(this, "AbstractEdge");
|
|
773
|
+
}
|
|
774
|
+
value;
|
|
775
|
+
weight;
|
|
776
|
+
constructor(weight, value) {
|
|
777
|
+
this.weight = weight !== void 0 ? weight : 1;
|
|
778
|
+
this.value = value;
|
|
779
|
+
this._hashCode = uuidV4();
|
|
780
|
+
}
|
|
781
|
+
_hashCode;
|
|
782
|
+
get hashCode() {
|
|
783
|
+
return this._hashCode;
|
|
784
|
+
}
|
|
785
|
+
};
|
|
786
|
+
var AbstractGraph = class extends IterableEntryBase {
|
|
787
|
+
static {
|
|
788
|
+
__name(this, "AbstractGraph");
|
|
789
|
+
}
|
|
790
|
+
constructor(options) {
|
|
791
|
+
super();
|
|
792
|
+
const graph = options?.graph;
|
|
793
|
+
this._options = { defaultEdgeWeight: 1, ...graph ?? {} };
|
|
794
|
+
}
|
|
795
|
+
_options = { defaultEdgeWeight: 1 };
|
|
796
|
+
get options() {
|
|
797
|
+
return this._options;
|
|
798
|
+
}
|
|
799
|
+
_vertexMap = new Map();
|
|
800
|
+
get vertexMap() {
|
|
801
|
+
return this._vertexMap;
|
|
802
|
+
}
|
|
803
|
+
set vertexMap(v) {
|
|
804
|
+
this._vertexMap = v;
|
|
805
|
+
}
|
|
806
|
+
get size() {
|
|
807
|
+
return this._vertexMap.size;
|
|
808
|
+
}
|
|
809
|
+
getVertex(vertexKey) {
|
|
810
|
+
return this._vertexMap.get(vertexKey) || void 0;
|
|
811
|
+
}
|
|
812
|
+
hasVertex(vertexOrKey) {
|
|
813
|
+
return this._vertexMap.has(this._getVertexKey(vertexOrKey));
|
|
814
|
+
}
|
|
815
|
+
addVertex(keyOrVertex, value) {
|
|
816
|
+
if (keyOrVertex instanceof AbstractVertex) {
|
|
817
|
+
return this._addVertex(keyOrVertex);
|
|
818
|
+
} else {
|
|
819
|
+
const newVertex = this.createVertex(keyOrVertex, value);
|
|
820
|
+
return this._addVertex(newVertex);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
isVertexKey(potentialKey) {
|
|
824
|
+
const potentialKeyType = typeof potentialKey;
|
|
825
|
+
return potentialKeyType === "string" || potentialKeyType === "number";
|
|
826
|
+
}
|
|
827
|
+
removeManyVertices(vertexMap) {
|
|
828
|
+
const removed = [];
|
|
829
|
+
for (const v of vertexMap) {
|
|
830
|
+
removed.push(this.deleteVertex(v));
|
|
831
|
+
}
|
|
832
|
+
return removed.length > 0;
|
|
833
|
+
}
|
|
834
|
+
hasEdge(v1, v2) {
|
|
835
|
+
const edge = this.getEdge(v1, v2);
|
|
836
|
+
return !!edge;
|
|
837
|
+
}
|
|
838
|
+
addEdge(srcOrEdge, dest, weight, value) {
|
|
839
|
+
if (srcOrEdge instanceof AbstractEdge) {
|
|
840
|
+
return this._addEdge(srcOrEdge);
|
|
841
|
+
} else {
|
|
842
|
+
if (dest instanceof AbstractVertex || typeof dest === "string" || typeof dest === "number") {
|
|
843
|
+
if (!(this.hasVertex(srcOrEdge) && this.hasVertex(dest))) return false;
|
|
844
|
+
if (srcOrEdge instanceof AbstractVertex) srcOrEdge = srcOrEdge.key;
|
|
845
|
+
if (dest instanceof AbstractVertex) dest = dest.key;
|
|
846
|
+
const newEdge = this.createEdge(srcOrEdge, dest, weight, value);
|
|
847
|
+
return this._addEdge(newEdge);
|
|
848
|
+
} else {
|
|
849
|
+
throw new Error("dest must be a Vertex or vertex key while srcOrEdge is an Edge");
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
setEdgeWeight(srcOrKey, destOrKey, weight) {
|
|
854
|
+
const edge = this.getEdge(srcOrKey, destOrKey);
|
|
855
|
+
if (edge) {
|
|
856
|
+
edge.weight = weight;
|
|
857
|
+
return true;
|
|
858
|
+
} else {
|
|
859
|
+
return false;
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
getAllPathsBetween(v1, v2, limit = 1e3) {
|
|
863
|
+
const paths = [];
|
|
864
|
+
const vertex1 = this._getVertex(v1);
|
|
865
|
+
const vertex2 = this._getVertex(v2);
|
|
866
|
+
if (!(vertex1 && vertex2)) {
|
|
867
|
+
return [];
|
|
868
|
+
}
|
|
869
|
+
const stack = [];
|
|
870
|
+
stack.push({ vertex: vertex1, path: [vertex1] });
|
|
871
|
+
while (stack.length > 0) {
|
|
872
|
+
const { vertex, path } = stack.pop();
|
|
873
|
+
if (vertex === vertex2) {
|
|
874
|
+
paths.push(path);
|
|
875
|
+
if (paths.length >= limit) return paths;
|
|
876
|
+
}
|
|
877
|
+
const neighbors = this.getNeighbors(vertex);
|
|
878
|
+
for (const neighbor of neighbors) {
|
|
879
|
+
if (!path.includes(neighbor)) {
|
|
880
|
+
const newPath = [...path, neighbor];
|
|
881
|
+
stack.push({ vertex: neighbor, path: newPath });
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
return paths;
|
|
886
|
+
}
|
|
887
|
+
getPathSumWeight(path) {
|
|
888
|
+
let sum = 0;
|
|
889
|
+
for (let i = 0; i < path.length; i++) {
|
|
890
|
+
sum += this.getEdge(path[i], path[i + 1])?.weight || 0;
|
|
891
|
+
}
|
|
892
|
+
return sum;
|
|
893
|
+
}
|
|
894
|
+
getMinCostBetween(v1, v2, isWeight) {
|
|
895
|
+
if (isWeight === void 0) isWeight = false;
|
|
896
|
+
if (isWeight) {
|
|
897
|
+
const allPaths = this.getAllPathsBetween(v1, v2);
|
|
898
|
+
let min = Number.MAX_SAFE_INTEGER;
|
|
899
|
+
for (const path of allPaths) {
|
|
900
|
+
min = Math.min(this.getPathSumWeight(path), min);
|
|
901
|
+
}
|
|
902
|
+
return min;
|
|
903
|
+
} else {
|
|
904
|
+
const vertex2 = this._getVertex(v2);
|
|
905
|
+
const vertex1 = this._getVertex(v1);
|
|
906
|
+
if (!(vertex1 && vertex2)) {
|
|
907
|
+
return void 0;
|
|
908
|
+
}
|
|
909
|
+
const visited = new Map();
|
|
910
|
+
const queue = new Queue([vertex1]);
|
|
911
|
+
visited.set(vertex1, true);
|
|
912
|
+
let cost = 0;
|
|
913
|
+
while (queue.length > 0) {
|
|
914
|
+
for (let i = 0, layerSize = queue.length; i < layerSize; i++) {
|
|
915
|
+
const cur = queue.shift();
|
|
916
|
+
if (cur === vertex2) {
|
|
917
|
+
return cost;
|
|
918
|
+
}
|
|
919
|
+
if (cur !== void 0) {
|
|
920
|
+
const neighbors = this.getNeighbors(cur);
|
|
921
|
+
for (const neighbor of neighbors) {
|
|
922
|
+
if (!visited.has(neighbor)) {
|
|
923
|
+
visited.set(neighbor, true);
|
|
924
|
+
queue.push(neighbor);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
cost++;
|
|
930
|
+
}
|
|
931
|
+
return void 0;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
getMinPathBetween(v1, v2, isWeight, isDFS = false) {
|
|
935
|
+
if (isWeight === void 0) isWeight = false;
|
|
936
|
+
if (isWeight) {
|
|
937
|
+
if (isDFS) {
|
|
938
|
+
const allPaths = this.getAllPathsBetween(v1, v2, 1e4);
|
|
939
|
+
let min = Number.MAX_SAFE_INTEGER;
|
|
940
|
+
let minIndex = -1;
|
|
941
|
+
let index = 0;
|
|
942
|
+
for (const path of allPaths) {
|
|
943
|
+
const pathSumWeight = this.getPathSumWeight(path);
|
|
944
|
+
if (pathSumWeight < min) {
|
|
945
|
+
min = pathSumWeight;
|
|
946
|
+
minIndex = index;
|
|
947
|
+
}
|
|
948
|
+
index++;
|
|
949
|
+
}
|
|
950
|
+
return allPaths[minIndex] || void 0;
|
|
951
|
+
} else {
|
|
952
|
+
return this.dijkstra(v1, v2, true, true)?.minPath ?? [];
|
|
953
|
+
}
|
|
954
|
+
} else {
|
|
955
|
+
let minPath = [];
|
|
956
|
+
const vertex1 = this._getVertex(v1);
|
|
957
|
+
const vertex2 = this._getVertex(v2);
|
|
958
|
+
if (!(vertex1 && vertex2)) return [];
|
|
959
|
+
const dfs = __name((cur, dest, visiting, path) => {
|
|
960
|
+
visiting.add(cur);
|
|
961
|
+
if (cur === dest) {
|
|
962
|
+
minPath = [vertex1, ...path];
|
|
963
|
+
return;
|
|
964
|
+
}
|
|
965
|
+
const neighbors = this.getNeighbors(cur);
|
|
966
|
+
for (const neighbor of neighbors) {
|
|
967
|
+
if (!visiting.has(neighbor)) {
|
|
968
|
+
path.push(neighbor);
|
|
969
|
+
dfs(neighbor, dest, visiting, path);
|
|
970
|
+
path.pop();
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
visiting.delete(cur);
|
|
974
|
+
}, "dfs");
|
|
975
|
+
dfs(vertex1, vertex2, new Set(), []);
|
|
976
|
+
return minPath;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
dijkstraWithoutHeap(src, dest = void 0, getMinDist = false, genPaths = false) {
|
|
980
|
+
let minDist = Number.MAX_SAFE_INTEGER;
|
|
981
|
+
let minDest = void 0;
|
|
982
|
+
let minPath = [];
|
|
983
|
+
const paths = [];
|
|
984
|
+
const vertexMap = this._vertexMap;
|
|
985
|
+
const distMap = new Map();
|
|
986
|
+
const seen = new Set();
|
|
987
|
+
const preMap = new Map();
|
|
988
|
+
const srcVertex = this._getVertex(src);
|
|
989
|
+
const destVertex = dest ? this._getVertex(dest) : void 0;
|
|
990
|
+
if (!srcVertex) {
|
|
991
|
+
return void 0;
|
|
992
|
+
}
|
|
993
|
+
for (const vertex of vertexMap) {
|
|
994
|
+
const vertexOrKey = vertex[1];
|
|
995
|
+
if (vertexOrKey instanceof AbstractVertex) distMap.set(vertexOrKey, Number.MAX_SAFE_INTEGER);
|
|
996
|
+
}
|
|
997
|
+
distMap.set(srcVertex, 0);
|
|
998
|
+
preMap.set(srcVertex, void 0);
|
|
999
|
+
const getMinOfNoSeen = __name(() => {
|
|
1000
|
+
let min = Number.MAX_SAFE_INTEGER;
|
|
1001
|
+
let minV = void 0;
|
|
1002
|
+
for (const [key, value] of distMap) {
|
|
1003
|
+
if (!seen.has(key)) {
|
|
1004
|
+
if (value < min) {
|
|
1005
|
+
min = value;
|
|
1006
|
+
minV = key;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
return minV;
|
|
1011
|
+
}, "getMinOfNoSeen");
|
|
1012
|
+
const getPaths = __name((minV) => {
|
|
1013
|
+
for (const vertex of vertexMap) {
|
|
1014
|
+
const vertexOrKey = vertex[1];
|
|
1015
|
+
if (vertexOrKey instanceof AbstractVertex) {
|
|
1016
|
+
const path = [vertexOrKey];
|
|
1017
|
+
let parent = preMap.get(vertexOrKey);
|
|
1018
|
+
while (parent) {
|
|
1019
|
+
path.push(parent);
|
|
1020
|
+
parent = preMap.get(parent);
|
|
1021
|
+
}
|
|
1022
|
+
const reversed = path.reverse();
|
|
1023
|
+
if (vertex[1] === minV) minPath = reversed;
|
|
1024
|
+
paths.push(reversed);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}, "getPaths");
|
|
1028
|
+
for (let i = 1; i < vertexMap.size; i++) {
|
|
1029
|
+
const cur = getMinOfNoSeen();
|
|
1030
|
+
if (cur) {
|
|
1031
|
+
seen.add(cur);
|
|
1032
|
+
if (destVertex && destVertex === cur) {
|
|
1033
|
+
if (getMinDist) {
|
|
1034
|
+
minDist = distMap.get(destVertex) || Number.MAX_SAFE_INTEGER;
|
|
1035
|
+
}
|
|
1036
|
+
if (genPaths) {
|
|
1037
|
+
getPaths(destVertex);
|
|
1038
|
+
}
|
|
1039
|
+
return { distMap, preMap, seen, paths, minDist, minPath };
|
|
1040
|
+
}
|
|
1041
|
+
const neighbors = this.getNeighbors(cur);
|
|
1042
|
+
for (const neighbor of neighbors) {
|
|
1043
|
+
if (!seen.has(neighbor)) {
|
|
1044
|
+
const edge = this.getEdge(cur, neighbor);
|
|
1045
|
+
if (edge) {
|
|
1046
|
+
const curFromMap = distMap.get(cur);
|
|
1047
|
+
const neighborFromMap = distMap.get(neighbor);
|
|
1048
|
+
if (curFromMap !== void 0 && neighborFromMap !== void 0) {
|
|
1049
|
+
if (edge.weight + curFromMap < neighborFromMap) {
|
|
1050
|
+
distMap.set(neighbor, edge.weight + curFromMap);
|
|
1051
|
+
preMap.set(neighbor, cur);
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
if (getMinDist)
|
|
1060
|
+
distMap.forEach((d, v) => {
|
|
1061
|
+
if (v !== srcVertex) {
|
|
1062
|
+
if (d < minDist) {
|
|
1063
|
+
minDist = d;
|
|
1064
|
+
if (genPaths) minDest = v;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
});
|
|
1068
|
+
if (genPaths) getPaths(minDest);
|
|
1069
|
+
return { distMap, preMap, seen, paths, minDist, minPath };
|
|
1070
|
+
}
|
|
1071
|
+
dijkstra(src, dest = void 0, getMinDist = false, genPaths = false) {
|
|
1072
|
+
let minDist = Number.MAX_SAFE_INTEGER;
|
|
1073
|
+
let minDest = void 0;
|
|
1074
|
+
let minPath = [];
|
|
1075
|
+
const paths = [];
|
|
1076
|
+
const vertexMap = this._vertexMap;
|
|
1077
|
+
const distMap = new Map();
|
|
1078
|
+
const seen = new Set();
|
|
1079
|
+
const preMap = new Map();
|
|
1080
|
+
const srcVertex = this._getVertex(src);
|
|
1081
|
+
const destVertex = dest ? this._getVertex(dest) : void 0;
|
|
1082
|
+
if (!srcVertex) return void 0;
|
|
1083
|
+
for (const vertex of vertexMap) {
|
|
1084
|
+
const vertexOrKey = vertex[1];
|
|
1085
|
+
if (vertexOrKey instanceof AbstractVertex) distMap.set(vertexOrKey, Number.MAX_SAFE_INTEGER);
|
|
1086
|
+
}
|
|
1087
|
+
const heap = new Heap([], { comparator: __name((a, b) => a.key - b.key, "comparator") });
|
|
1088
|
+
heap.add({ key: 0, value: srcVertex });
|
|
1089
|
+
distMap.set(srcVertex, 0);
|
|
1090
|
+
preMap.set(srcVertex, void 0);
|
|
1091
|
+
const getPaths = __name((minV) => {
|
|
1092
|
+
for (const vertex of vertexMap) {
|
|
1093
|
+
const vertexOrKey = vertex[1];
|
|
1094
|
+
if (vertexOrKey instanceof AbstractVertex) {
|
|
1095
|
+
const path = [vertexOrKey];
|
|
1096
|
+
let parent = preMap.get(vertexOrKey);
|
|
1097
|
+
while (parent) {
|
|
1098
|
+
path.push(parent);
|
|
1099
|
+
parent = preMap.get(parent);
|
|
1100
|
+
}
|
|
1101
|
+
const reversed = path.reverse();
|
|
1102
|
+
if (vertex[1] === minV) minPath = reversed;
|
|
1103
|
+
paths.push(reversed);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}, "getPaths");
|
|
1107
|
+
while (heap.size > 0) {
|
|
1108
|
+
const curHeapNode = heap.poll();
|
|
1109
|
+
const dist = curHeapNode?.key;
|
|
1110
|
+
const cur = curHeapNode?.value;
|
|
1111
|
+
if (dist !== void 0) {
|
|
1112
|
+
if (cur) {
|
|
1113
|
+
seen.add(cur);
|
|
1114
|
+
if (destVertex && destVertex === cur) {
|
|
1115
|
+
if (getMinDist) {
|
|
1116
|
+
minDist = distMap.get(destVertex) || Number.MAX_SAFE_INTEGER;
|
|
1117
|
+
}
|
|
1118
|
+
if (genPaths) {
|
|
1119
|
+
getPaths(destVertex);
|
|
1120
|
+
}
|
|
1121
|
+
return { distMap, preMap, seen, paths, minDist, minPath };
|
|
1122
|
+
}
|
|
1123
|
+
const neighbors = this.getNeighbors(cur);
|
|
1124
|
+
for (const neighbor of neighbors) {
|
|
1125
|
+
if (!seen.has(neighbor)) {
|
|
1126
|
+
const weight = this.getEdge(cur, neighbor)?.weight;
|
|
1127
|
+
if (typeof weight === "number") {
|
|
1128
|
+
const distSrcToNeighbor = distMap.get(neighbor);
|
|
1129
|
+
if (distSrcToNeighbor !== void 0) {
|
|
1130
|
+
if (dist + weight < distSrcToNeighbor) {
|
|
1131
|
+
heap.add({ key: dist + weight, value: neighbor });
|
|
1132
|
+
preMap.set(neighbor, cur);
|
|
1133
|
+
distMap.set(neighbor, dist + weight);
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
if (getMinDist) {
|
|
1143
|
+
distMap.forEach((d, v) => {
|
|
1144
|
+
if (v !== srcVertex) {
|
|
1145
|
+
if (d < minDist) {
|
|
1146
|
+
minDist = d;
|
|
1147
|
+
if (genPaths) minDest = v;
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
});
|
|
1151
|
+
}
|
|
1152
|
+
if (genPaths) {
|
|
1153
|
+
getPaths(minDest);
|
|
1154
|
+
}
|
|
1155
|
+
return { distMap, preMap, seen, paths, minDist, minPath };
|
|
1156
|
+
}
|
|
1157
|
+
bellmanFord(src, scanNegativeCycle, getMin, genPath) {
|
|
1158
|
+
if (getMin === void 0) getMin = false;
|
|
1159
|
+
if (genPath === void 0) genPath = false;
|
|
1160
|
+
const srcVertex = this._getVertex(src);
|
|
1161
|
+
const paths = [];
|
|
1162
|
+
const distMap = new Map();
|
|
1163
|
+
const preMap = new Map();
|
|
1164
|
+
let min = Number.MAX_SAFE_INTEGER;
|
|
1165
|
+
let minPath = [];
|
|
1166
|
+
let hasNegativeCycle;
|
|
1167
|
+
if (scanNegativeCycle) hasNegativeCycle = false;
|
|
1168
|
+
if (!srcVertex) return { hasNegativeCycle, distMap, preMap, paths, min, minPath };
|
|
1169
|
+
const vertexMap = this._vertexMap;
|
|
1170
|
+
const numOfVertices = vertexMap.size;
|
|
1171
|
+
const edgeMap = this.edgeSet();
|
|
1172
|
+
const numOfEdges = edgeMap.length;
|
|
1173
|
+
this._vertexMap.forEach((vertex) => {
|
|
1174
|
+
distMap.set(vertex, Number.MAX_SAFE_INTEGER);
|
|
1175
|
+
});
|
|
1176
|
+
distMap.set(srcVertex, 0);
|
|
1177
|
+
for (let i = 1; i < numOfVertices; ++i) {
|
|
1178
|
+
for (let j = 0; j < numOfEdges; ++j) {
|
|
1179
|
+
const ends = this.getEndsOfEdge(edgeMap[j]);
|
|
1180
|
+
if (ends) {
|
|
1181
|
+
const [s, d] = ends;
|
|
1182
|
+
const weight = edgeMap[j].weight;
|
|
1183
|
+
const sWeight = distMap.get(s);
|
|
1184
|
+
const dWeight = distMap.get(d);
|
|
1185
|
+
if (sWeight !== void 0 && dWeight !== void 0) {
|
|
1186
|
+
if (distMap.get(s) !== Number.MAX_SAFE_INTEGER && sWeight + weight < dWeight) {
|
|
1187
|
+
distMap.set(d, sWeight + weight);
|
|
1188
|
+
if (genPath) preMap.set(d, s);
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
let minDest = void 0;
|
|
1195
|
+
if (getMin) {
|
|
1196
|
+
distMap.forEach((d, v) => {
|
|
1197
|
+
if (v !== srcVertex) {
|
|
1198
|
+
if (d < min) {
|
|
1199
|
+
min = d;
|
|
1200
|
+
if (genPath) minDest = v;
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1205
|
+
if (genPath) {
|
|
1206
|
+
for (const vertex of vertexMap) {
|
|
1207
|
+
const vertexOrKey = vertex[1];
|
|
1208
|
+
if (vertexOrKey instanceof AbstractVertex) {
|
|
1209
|
+
const path = [vertexOrKey];
|
|
1210
|
+
let parent = preMap.get(vertexOrKey);
|
|
1211
|
+
while (parent !== void 0) {
|
|
1212
|
+
path.push(parent);
|
|
1213
|
+
parent = preMap.get(parent);
|
|
1214
|
+
}
|
|
1215
|
+
const reversed = path.reverse();
|
|
1216
|
+
if (vertex[1] === minDest) minPath = reversed;
|
|
1217
|
+
paths.push(reversed);
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
for (let j = 0; j < numOfEdges; ++j) {
|
|
1222
|
+
const ends = this.getEndsOfEdge(edgeMap[j]);
|
|
1223
|
+
if (ends) {
|
|
1224
|
+
const [s] = ends;
|
|
1225
|
+
const weight = edgeMap[j].weight;
|
|
1226
|
+
const sWeight = distMap.get(s);
|
|
1227
|
+
if (sWeight) {
|
|
1228
|
+
if (sWeight !== Number.MAX_SAFE_INTEGER && sWeight + weight < sWeight) hasNegativeCycle = true;
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
return { hasNegativeCycle, distMap, preMap, paths, min, minPath };
|
|
1233
|
+
}
|
|
1234
|
+
floydWarshall() {
|
|
1235
|
+
const idAndVertices = [...this._vertexMap];
|
|
1236
|
+
const n = idAndVertices.length;
|
|
1237
|
+
const costs = [];
|
|
1238
|
+
const predecessor = [];
|
|
1239
|
+
for (let i = 0; i < n; i++) {
|
|
1240
|
+
costs[i] = [];
|
|
1241
|
+
predecessor[i] = [];
|
|
1242
|
+
for (let j = 0; j < n; j++) {
|
|
1243
|
+
predecessor[i][j] = void 0;
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
for (let i = 0; i < n; i++) {
|
|
1247
|
+
for (let j = 0; j < n; j++) {
|
|
1248
|
+
costs[i][j] = this.getEdge(idAndVertices[i][1], idAndVertices[j][1])?.weight || Number.MAX_SAFE_INTEGER;
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
for (let k = 0; k < n; k++) {
|
|
1252
|
+
for (let i = 0; i < n; i++) {
|
|
1253
|
+
for (let j = 0; j < n; j++) {
|
|
1254
|
+
if (costs[i][j] > costs[i][k] + costs[k][j]) {
|
|
1255
|
+
costs[i][j] = costs[i][k] + costs[k][j];
|
|
1256
|
+
predecessor[i][j] = idAndVertices[k][1];
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
return { costs, predecessor };
|
|
1262
|
+
}
|
|
1263
|
+
getCycles(isInclude2Cycle = false) {
|
|
1264
|
+
const cycles = [];
|
|
1265
|
+
const visited = new Set();
|
|
1266
|
+
const dfs = __name((vertex, currentPath, visited2) => {
|
|
1267
|
+
if (visited2.has(vertex)) {
|
|
1268
|
+
if ((!isInclude2Cycle && currentPath.length > 2 || isInclude2Cycle && currentPath.length >= 2) && currentPath[0] === vertex.key) {
|
|
1269
|
+
cycles.push([...currentPath]);
|
|
1270
|
+
}
|
|
1271
|
+
return;
|
|
1272
|
+
}
|
|
1273
|
+
visited2.add(vertex);
|
|
1274
|
+
currentPath.push(vertex.key);
|
|
1275
|
+
for (const neighbor of this.getNeighbors(vertex)) {
|
|
1276
|
+
if (neighbor) dfs(neighbor, currentPath, visited2);
|
|
1277
|
+
}
|
|
1278
|
+
visited2.delete(vertex);
|
|
1279
|
+
currentPath.pop();
|
|
1280
|
+
}, "dfs");
|
|
1281
|
+
for (const vertex of this.vertexMap.values()) {
|
|
1282
|
+
dfs(vertex, [], visited);
|
|
1283
|
+
}
|
|
1284
|
+
const uniqueCycles = new Map();
|
|
1285
|
+
for (const cycle of cycles) {
|
|
1286
|
+
const sorted = [...cycle].sort().toString();
|
|
1287
|
+
if (uniqueCycles.has(sorted)) continue;
|
|
1288
|
+
else {
|
|
1289
|
+
uniqueCycles.set(sorted, cycle);
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
return [...uniqueCycles].map((cycleString) => cycleString[1]);
|
|
1293
|
+
}
|
|
1294
|
+
filter(predicate, thisArg) {
|
|
1295
|
+
const filtered = [];
|
|
1296
|
+
let index = 0;
|
|
1297
|
+
for (const [key, value] of this) {
|
|
1298
|
+
if (predicate.call(thisArg, value, key, index, this)) {
|
|
1299
|
+
filtered.push([key, value]);
|
|
1300
|
+
}
|
|
1301
|
+
index++;
|
|
1302
|
+
}
|
|
1303
|
+
return this._createLike(filtered, this._snapshotOptions());
|
|
1304
|
+
}
|
|
1305
|
+
filterEntries(predicate, thisArg) {
|
|
1306
|
+
const filtered = [];
|
|
1307
|
+
let index = 0;
|
|
1308
|
+
for (const [key, value] of this) {
|
|
1309
|
+
if (predicate.call(thisArg, value, key, index, this)) {
|
|
1310
|
+
filtered.push([key, value]);
|
|
1311
|
+
}
|
|
1312
|
+
index++;
|
|
1313
|
+
}
|
|
1314
|
+
return filtered;
|
|
1315
|
+
}
|
|
1316
|
+
map(callback, thisArg) {
|
|
1317
|
+
const mapped = [];
|
|
1318
|
+
let index = 0;
|
|
1319
|
+
for (const [key, value] of this) {
|
|
1320
|
+
mapped.push(callback.call(thisArg, value, key, index, this));
|
|
1321
|
+
index++;
|
|
1322
|
+
}
|
|
1323
|
+
return mapped;
|
|
1324
|
+
}
|
|
1325
|
+
clone() {
|
|
1326
|
+
return this._createLike(void 0, this._snapshotOptions());
|
|
1327
|
+
}
|
|
1328
|
+
*_getIterator() {
|
|
1329
|
+
for (const vertex of this._vertexMap.values()) {
|
|
1330
|
+
yield [vertex.key, vertex.value];
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
_snapshotOptions() {
|
|
1334
|
+
return { graph: { ...this._options } };
|
|
1335
|
+
}
|
|
1336
|
+
_createInstance(_options) {
|
|
1337
|
+
const Ctor = this.constructor;
|
|
1338
|
+
const instance = new Ctor();
|
|
1339
|
+
const graph = _options?.graph;
|
|
1340
|
+
if (graph) instance._options = { ...instance._options, ...graph };
|
|
1341
|
+
else instance._options = { ...instance._options, ...this._options };
|
|
1342
|
+
return instance;
|
|
1343
|
+
}
|
|
1344
|
+
_createLike(iter, options) {
|
|
1345
|
+
const g = this._createInstance(options);
|
|
1346
|
+
if (iter) {
|
|
1347
|
+
for (const [k, v] of iter) {
|
|
1348
|
+
g.addVertex(k, v);
|
|
1349
|
+
}
|
|
1350
|
+
} else {
|
|
1351
|
+
for (const [k, v] of this) {
|
|
1352
|
+
g.addVertex(k, v);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
const edges = this.edgeSet();
|
|
1356
|
+
for (const e of edges) {
|
|
1357
|
+
const ends = this.getEndsOfEdge(e);
|
|
1358
|
+
if (!ends) continue;
|
|
1359
|
+
const [va, vb] = ends;
|
|
1360
|
+
const ka = va.key;
|
|
1361
|
+
const kb = vb.key;
|
|
1362
|
+
const hasA = g.hasVertex ? g.hasVertex(ka) : false;
|
|
1363
|
+
const hasB = g.hasVertex ? g.hasVertex(kb) : false;
|
|
1364
|
+
if (hasA && hasB) {
|
|
1365
|
+
const w = e.weight;
|
|
1366
|
+
const val = e.value;
|
|
1367
|
+
const newEdge = g.createEdge(ka, kb, w, val);
|
|
1368
|
+
g._addEdge(newEdge);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
return g;
|
|
1372
|
+
}
|
|
1373
|
+
_addVertex(newVertex) {
|
|
1374
|
+
if (this.hasVertex(newVertex)) {
|
|
1375
|
+
return false;
|
|
1376
|
+
}
|
|
1377
|
+
this._vertexMap.set(newVertex.key, newVertex);
|
|
1378
|
+
return true;
|
|
1379
|
+
}
|
|
1380
|
+
_getVertex(vertexOrKey) {
|
|
1381
|
+
const vertexKey = this._getVertexKey(vertexOrKey);
|
|
1382
|
+
return this._vertexMap.get(vertexKey) || void 0;
|
|
1383
|
+
}
|
|
1384
|
+
_getVertexKey(vertexOrKey) {
|
|
1385
|
+
return vertexOrKey instanceof AbstractVertex ? vertexOrKey.key : vertexOrKey;
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1388
|
+
var DirectedVertex = class extends AbstractVertex {
|
|
1389
|
+
static {
|
|
1390
|
+
__name(this, "DirectedVertex");
|
|
1391
|
+
}
|
|
1392
|
+
constructor(key, value) {
|
|
1393
|
+
super(key, value);
|
|
1394
|
+
}
|
|
1395
|
+
};
|
|
1396
|
+
var DirectedEdge = class extends AbstractEdge {
|
|
1397
|
+
static {
|
|
1398
|
+
__name(this, "DirectedEdge");
|
|
1399
|
+
}
|
|
1400
|
+
src;
|
|
1401
|
+
dest;
|
|
1402
|
+
constructor(src, dest, weight, value) {
|
|
1403
|
+
super(weight, value);
|
|
1404
|
+
this.src = src;
|
|
1405
|
+
this.dest = dest;
|
|
1406
|
+
}
|
|
1407
|
+
};
|
|
1408
|
+
var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
1409
|
+
static {
|
|
1410
|
+
__name(this, "DirectedGraph");
|
|
1411
|
+
}
|
|
1412
|
+
constructor(options) {
|
|
1413
|
+
super(options);
|
|
1414
|
+
}
|
|
1415
|
+
_outEdgeMap = new Map();
|
|
1416
|
+
get outEdgeMap() {
|
|
1417
|
+
return this._outEdgeMap;
|
|
1418
|
+
}
|
|
1419
|
+
set outEdgeMap(v) {
|
|
1420
|
+
this._outEdgeMap = v;
|
|
1421
|
+
}
|
|
1422
|
+
_inEdgeMap = new Map();
|
|
1423
|
+
get inEdgeMap() {
|
|
1424
|
+
return this._inEdgeMap;
|
|
1425
|
+
}
|
|
1426
|
+
set inEdgeMap(v) {
|
|
1427
|
+
this._inEdgeMap = v;
|
|
1428
|
+
}
|
|
1429
|
+
static fromKeys(keys) {
|
|
1430
|
+
const g = new _DirectedGraph({
|
|
1431
|
+
vertexValueInitializer: __name((k) => k, "vertexValueInitializer")
|
|
1432
|
+
});
|
|
1433
|
+
for (const k of keys) g.addVertex(k);
|
|
1434
|
+
return g;
|
|
1435
|
+
}
|
|
1436
|
+
static fromEntries(entries) {
|
|
1437
|
+
const g = new _DirectedGraph();
|
|
1438
|
+
for (const [k, v] of entries) g.addVertex(k, v);
|
|
1439
|
+
return g;
|
|
1440
|
+
}
|
|
1441
|
+
createVertex(key, value) {
|
|
1442
|
+
return new DirectedVertex(key, value);
|
|
1443
|
+
}
|
|
1444
|
+
createEdge(src, dest, weight, value) {
|
|
1445
|
+
return new DirectedEdge(src, dest, weight ?? this.options.defaultEdgeWeight ?? 1, value);
|
|
1446
|
+
}
|
|
1447
|
+
getEdge(srcOrKey, destOrKey) {
|
|
1448
|
+
let edgeMap = [];
|
|
1449
|
+
if (srcOrKey !== void 0 && destOrKey !== void 0) {
|
|
1450
|
+
const src = this._getVertex(srcOrKey);
|
|
1451
|
+
const dest = this._getVertex(destOrKey);
|
|
1452
|
+
if (src && dest) {
|
|
1453
|
+
const srcOutEdges = this._outEdgeMap.get(src);
|
|
1454
|
+
if (srcOutEdges) {
|
|
1455
|
+
edgeMap = srcOutEdges.filter((edge) => edge.dest === dest.key);
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
return edgeMap[0] || void 0;
|
|
1460
|
+
}
|
|
1461
|
+
deleteEdgeSrcToDest(srcOrKey, destOrKey) {
|
|
1462
|
+
const src = this._getVertex(srcOrKey);
|
|
1463
|
+
const dest = this._getVertex(destOrKey);
|
|
1464
|
+
let removed = void 0;
|
|
1465
|
+
if (!src || !dest) {
|
|
1466
|
+
return void 0;
|
|
1467
|
+
}
|
|
1468
|
+
const srcOutEdges = this._outEdgeMap.get(src);
|
|
1469
|
+
if (srcOutEdges) {
|
|
1470
|
+
arrayRemove(srcOutEdges, (edge) => edge.dest === dest.key);
|
|
1471
|
+
}
|
|
1472
|
+
const destInEdges = this._inEdgeMap.get(dest);
|
|
1473
|
+
if (destInEdges) {
|
|
1474
|
+
removed = arrayRemove(destInEdges, (edge) => edge.src === src.key)[0] || void 0;
|
|
1475
|
+
}
|
|
1476
|
+
return removed;
|
|
1477
|
+
}
|
|
1478
|
+
deleteEdge(edgeOrSrcVertexKey, destVertexKey) {
|
|
1479
|
+
let removed = void 0;
|
|
1480
|
+
let src, dest;
|
|
1481
|
+
if (this.isVertexKey(edgeOrSrcVertexKey)) {
|
|
1482
|
+
if (this.isVertexKey(destVertexKey)) {
|
|
1483
|
+
src = this._getVertex(edgeOrSrcVertexKey);
|
|
1484
|
+
dest = this._getVertex(destVertexKey);
|
|
1485
|
+
} else {
|
|
1486
|
+
return;
|
|
1487
|
+
}
|
|
1488
|
+
} else {
|
|
1489
|
+
src = this._getVertex(edgeOrSrcVertexKey.src);
|
|
1490
|
+
dest = this._getVertex(edgeOrSrcVertexKey.dest);
|
|
1491
|
+
}
|
|
1492
|
+
if (src && dest) {
|
|
1493
|
+
const srcOutEdges = this._outEdgeMap.get(src);
|
|
1494
|
+
if (srcOutEdges && srcOutEdges.length > 0) {
|
|
1495
|
+
arrayRemove(srcOutEdges, (edge) => edge.src === src.key && edge.dest === dest?.key);
|
|
1496
|
+
}
|
|
1497
|
+
const destInEdges = this._inEdgeMap.get(dest);
|
|
1498
|
+
if (destInEdges && destInEdges.length > 0) {
|
|
1499
|
+
removed = arrayRemove(destInEdges, (edge) => edge.src === src.key && edge.dest === dest.key)[0];
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
return removed;
|
|
1503
|
+
}
|
|
1504
|
+
deleteVertex(vertexOrKey) {
|
|
1505
|
+
let vertexKey;
|
|
1506
|
+
let vertex;
|
|
1507
|
+
if (this.isVertexKey(vertexOrKey)) {
|
|
1508
|
+
vertex = this.getVertex(vertexOrKey);
|
|
1509
|
+
vertexKey = vertexOrKey;
|
|
1510
|
+
} else {
|
|
1511
|
+
vertex = vertexOrKey;
|
|
1512
|
+
vertexKey = this._getVertexKey(vertexOrKey);
|
|
1513
|
+
}
|
|
1514
|
+
if (vertex) {
|
|
1515
|
+
const neighbors = this.getNeighbors(vertex);
|
|
1516
|
+
for (const neighbor of neighbors) {
|
|
1517
|
+
this.deleteEdgeSrcToDest(vertex, neighbor);
|
|
1518
|
+
}
|
|
1519
|
+
this._outEdgeMap.delete(vertex);
|
|
1520
|
+
this._inEdgeMap.delete(vertex);
|
|
1521
|
+
}
|
|
1522
|
+
return this._vertexMap.delete(vertexKey);
|
|
1523
|
+
}
|
|
1524
|
+
deleteEdgesBetween(v1, v2) {
|
|
1525
|
+
const removed = [];
|
|
1526
|
+
if (v1 && v2) {
|
|
1527
|
+
const v1ToV2 = this.deleteEdgeSrcToDest(v1, v2);
|
|
1528
|
+
const v2ToV1 = this.deleteEdgeSrcToDest(v2, v1);
|
|
1529
|
+
if (v1ToV2) removed.push(v1ToV2);
|
|
1530
|
+
if (v2ToV1) removed.push(v2ToV1);
|
|
1531
|
+
}
|
|
1532
|
+
return removed;
|
|
1533
|
+
}
|
|
1534
|
+
incomingEdgesOf(vertexOrKey) {
|
|
1535
|
+
const target = this._getVertex(vertexOrKey);
|
|
1536
|
+
if (target) {
|
|
1537
|
+
return this.inEdgeMap.get(target) || [];
|
|
1538
|
+
}
|
|
1539
|
+
return [];
|
|
1540
|
+
}
|
|
1541
|
+
outgoingEdgesOf(vertexOrKey) {
|
|
1542
|
+
const target = this._getVertex(vertexOrKey);
|
|
1543
|
+
if (target) {
|
|
1544
|
+
return this._outEdgeMap.get(target) || [];
|
|
1545
|
+
}
|
|
1546
|
+
return [];
|
|
1547
|
+
}
|
|
1548
|
+
degreeOf(vertexOrKey) {
|
|
1549
|
+
return this.outDegreeOf(vertexOrKey) + this.inDegreeOf(vertexOrKey);
|
|
1550
|
+
}
|
|
1551
|
+
inDegreeOf(vertexOrKey) {
|
|
1552
|
+
return this.incomingEdgesOf(vertexOrKey).length;
|
|
1553
|
+
}
|
|
1554
|
+
outDegreeOf(vertexOrKey) {
|
|
1555
|
+
return this.outgoingEdgesOf(vertexOrKey).length;
|
|
1556
|
+
}
|
|
1557
|
+
edgesOf(vertexOrKey) {
|
|
1558
|
+
return [...this.outgoingEdgesOf(vertexOrKey), ...this.incomingEdgesOf(vertexOrKey)];
|
|
1559
|
+
}
|
|
1560
|
+
getEdgeSrc(e) {
|
|
1561
|
+
return this._getVertex(e.src);
|
|
1562
|
+
}
|
|
1563
|
+
getEdgeDest(e) {
|
|
1564
|
+
return this._getVertex(e.dest);
|
|
1565
|
+
}
|
|
1566
|
+
getDestinations(vertex) {
|
|
1567
|
+
if (vertex === void 0) {
|
|
1568
|
+
return [];
|
|
1569
|
+
}
|
|
1570
|
+
const destinations = [];
|
|
1571
|
+
const outgoingEdges = this.outgoingEdgesOf(vertex);
|
|
1572
|
+
for (const outEdge of outgoingEdges) {
|
|
1573
|
+
const child = this.getEdgeDest(outEdge);
|
|
1574
|
+
if (child) {
|
|
1575
|
+
destinations.push(child);
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
return destinations;
|
|
1579
|
+
}
|
|
1580
|
+
topologicalSort(propertyName) {
|
|
1581
|
+
propertyName = propertyName ?? "key";
|
|
1582
|
+
const statusMap = new Map();
|
|
1583
|
+
for (const entry of this.vertexMap) {
|
|
1584
|
+
statusMap.set(entry[1], 0);
|
|
1585
|
+
}
|
|
1586
|
+
let sorted = [];
|
|
1587
|
+
let hasCycle = false;
|
|
1588
|
+
const dfs = __name((cur) => {
|
|
1589
|
+
statusMap.set(cur, 1);
|
|
1590
|
+
const children = this.getDestinations(cur);
|
|
1591
|
+
for (const child of children) {
|
|
1592
|
+
const childStatus = statusMap.get(child);
|
|
1593
|
+
if (childStatus === 0) {
|
|
1594
|
+
dfs(child);
|
|
1595
|
+
} else if (childStatus === 1) {
|
|
1596
|
+
hasCycle = true;
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
statusMap.set(cur, 2);
|
|
1600
|
+
sorted.push(cur);
|
|
1601
|
+
}, "dfs");
|
|
1602
|
+
for (const entry of this.vertexMap) {
|
|
1603
|
+
if (statusMap.get(entry[1]) === 0) {
|
|
1604
|
+
dfs(entry[1]);
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
if (hasCycle) return void 0;
|
|
1608
|
+
if (propertyName === "key") sorted = sorted.map((vertex) => vertex instanceof DirectedVertex ? vertex.key : vertex);
|
|
1609
|
+
return sorted.reverse();
|
|
1610
|
+
}
|
|
1611
|
+
edgeSet() {
|
|
1612
|
+
let edgeMap = [];
|
|
1613
|
+
this._outEdgeMap.forEach((outEdges) => {
|
|
1614
|
+
edgeMap = [...edgeMap, ...outEdges];
|
|
1615
|
+
});
|
|
1616
|
+
return edgeMap;
|
|
1617
|
+
}
|
|
1618
|
+
getNeighbors(vertexOrKey) {
|
|
1619
|
+
const neighbors = [];
|
|
1620
|
+
const vertex = this._getVertex(vertexOrKey);
|
|
1621
|
+
if (vertex) {
|
|
1622
|
+
const outEdges = this.outgoingEdgesOf(vertex);
|
|
1623
|
+
for (const outEdge of outEdges) {
|
|
1624
|
+
const neighbor = this._getVertex(outEdge.dest);
|
|
1625
|
+
if (neighbor) {
|
|
1626
|
+
neighbors.push(neighbor);
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
return neighbors;
|
|
1631
|
+
}
|
|
1632
|
+
getEndsOfEdge(edge) {
|
|
1633
|
+
if (!this.hasEdge(edge.src, edge.dest)) {
|
|
1634
|
+
return void 0;
|
|
1635
|
+
}
|
|
1636
|
+
const v1 = this._getVertex(edge.src);
|
|
1637
|
+
const v2 = this._getVertex(edge.dest);
|
|
1638
|
+
if (v1 && v2) {
|
|
1639
|
+
return [v1, v2];
|
|
1640
|
+
} else {
|
|
1641
|
+
return void 0;
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
isEmpty() {
|
|
1645
|
+
return this.vertexMap.size === 0 && this.inEdgeMap.size === 0 && this.outEdgeMap.size === 0;
|
|
1646
|
+
}
|
|
1647
|
+
clear() {
|
|
1648
|
+
this._vertexMap = new Map();
|
|
1649
|
+
this._inEdgeMap = new Map();
|
|
1650
|
+
this._outEdgeMap = new Map();
|
|
1651
|
+
}
|
|
1652
|
+
clone() {
|
|
1653
|
+
return super.clone();
|
|
1654
|
+
}
|
|
1655
|
+
tarjan() {
|
|
1656
|
+
const dfnMap = new Map();
|
|
1657
|
+
const lowMap = new Map();
|
|
1658
|
+
const SCCs = new Map();
|
|
1659
|
+
let time = 0;
|
|
1660
|
+
const stack = [];
|
|
1661
|
+
const inStack = new Set();
|
|
1662
|
+
const dfs = __name((vertex) => {
|
|
1663
|
+
dfnMap.set(vertex, time);
|
|
1664
|
+
lowMap.set(vertex, time);
|
|
1665
|
+
time++;
|
|
1666
|
+
stack.push(vertex);
|
|
1667
|
+
inStack.add(vertex);
|
|
1668
|
+
const neighbors = this.getNeighbors(vertex);
|
|
1669
|
+
for (const neighbor of neighbors) {
|
|
1670
|
+
if (!dfnMap.has(neighbor)) {
|
|
1671
|
+
dfs(neighbor);
|
|
1672
|
+
lowMap.set(vertex, Math.min(lowMap.get(vertex), lowMap.get(neighbor)));
|
|
1673
|
+
} else if (inStack.has(neighbor)) {
|
|
1674
|
+
lowMap.set(vertex, Math.min(lowMap.get(vertex), dfnMap.get(neighbor)));
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
if (dfnMap.get(vertex) === lowMap.get(vertex)) {
|
|
1678
|
+
const SCC = [];
|
|
1679
|
+
let poppedVertex;
|
|
1680
|
+
do {
|
|
1681
|
+
poppedVertex = stack.pop();
|
|
1682
|
+
inStack.delete(poppedVertex);
|
|
1683
|
+
SCC.push(poppedVertex);
|
|
1684
|
+
} while (poppedVertex !== vertex);
|
|
1685
|
+
SCCs.set(SCCs.size, SCC);
|
|
1686
|
+
}
|
|
1687
|
+
}, "dfs");
|
|
1688
|
+
for (const vertex of this.vertexMap.values()) {
|
|
1689
|
+
if (!dfnMap.has(vertex)) {
|
|
1690
|
+
dfs(vertex);
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
return { dfnMap, lowMap, SCCs };
|
|
1694
|
+
}
|
|
1695
|
+
getDFNMap() {
|
|
1696
|
+
return this.tarjan().dfnMap;
|
|
1697
|
+
}
|
|
1698
|
+
getLowMap() {
|
|
1699
|
+
return this.tarjan().lowMap;
|
|
1700
|
+
}
|
|
1701
|
+
getSCCs() {
|
|
1702
|
+
return this.tarjan().SCCs;
|
|
1703
|
+
}
|
|
1704
|
+
_addEdge(edge) {
|
|
1705
|
+
if (!(this.hasVertex(edge.src) && this.hasVertex(edge.dest))) {
|
|
1706
|
+
return false;
|
|
1707
|
+
}
|
|
1708
|
+
const srcVertex = this._getVertex(edge.src);
|
|
1709
|
+
const destVertex = this._getVertex(edge.dest);
|
|
1710
|
+
if (srcVertex && destVertex) {
|
|
1711
|
+
const srcOutEdges = this._outEdgeMap.get(srcVertex);
|
|
1712
|
+
if (srcOutEdges) {
|
|
1713
|
+
srcOutEdges.push(edge);
|
|
1714
|
+
} else {
|
|
1715
|
+
this._outEdgeMap.set(srcVertex, [edge]);
|
|
1716
|
+
}
|
|
1717
|
+
const destInEdges = this._inEdgeMap.get(destVertex);
|
|
1718
|
+
if (destInEdges) {
|
|
1719
|
+
destInEdges.push(edge);
|
|
1720
|
+
} else {
|
|
1721
|
+
this._inEdgeMap.set(destVertex, [edge]);
|
|
1722
|
+
}
|
|
1723
|
+
return true;
|
|
1724
|
+
} else {
|
|
1725
|
+
return false;
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
};
|
|
1729
|
+
export {
|
|
1730
|
+
DirectedEdge,
|
|
1731
|
+
DirectedGraph,
|
|
1732
|
+
DirectedVertex
|
|
1733
|
+
};
|