heap-typed 2.1.1 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +1020 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/esm/index.mjs +1012 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/types/data-structures/base/index.d.ts +2 -1
- package/dist/types/data-structures/binary-tree/avl-tree-counter.d.ts +182 -2
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +135 -2
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +291 -2
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +174 -1
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +754 -29
- package/dist/types/data-structures/binary-tree/bst.d.ts +413 -12
- package/dist/types/data-structures/binary-tree/index.d.ts +3 -2
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +208 -3
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +160 -1
- package/dist/types/data-structures/binary-tree/tree-counter.d.ts +190 -2
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +270 -2
- package/dist/types/data-structures/graph/abstract-graph.d.ts +340 -14
- package/dist/types/data-structures/graph/directed-graph.d.ts +207 -1
- package/dist/types/data-structures/graph/index.d.ts +2 -1
- package/dist/types/data-structures/graph/map-graph.d.ts +78 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +188 -1
- package/dist/types/data-structures/hash/hash-map.d.ts +345 -19
- package/dist/types/data-structures/hash/index.d.ts +0 -1
- package/dist/types/data-structures/heap/heap.d.ts +503 -5
- package/dist/types/data-structures/heap/index.d.ts +2 -0
- package/dist/types/data-structures/heap/max-heap.d.ts +32 -1
- package/dist/types/data-structures/heap/min-heap.d.ts +33 -1
- package/dist/types/data-structures/index.d.ts +7 -7
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +769 -2
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +451 -2
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +27 -4
- package/dist/types/data-structures/matrix/index.d.ts +1 -1
- package/dist/types/data-structures/matrix/matrix.d.ts +168 -7
- package/dist/types/data-structures/matrix/navigator.d.ts +54 -13
- package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +27 -1
- package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +26 -1
- package/dist/types/data-structures/priority-queue/priority-queue.d.ts +15 -2
- package/dist/types/data-structures/queue/deque.d.ts +431 -4
- package/dist/types/data-structures/queue/queue.d.ts +308 -4
- package/dist/types/data-structures/stack/stack.d.ts +306 -2
- package/dist/types/data-structures/tree/tree.d.ts +62 -1
- package/dist/types/data-structures/trie/trie.d.ts +350 -4
- package/dist/types/index.d.ts +11 -2
- package/dist/{interfaces → types/interfaces}/binary-tree.d.ts +1 -1
- package/dist/types/types/data-structures/base/index.d.ts +1 -0
- package/dist/types/types/data-structures/binary-tree/avl-tree-counter.d.ts +2 -0
- package/dist/types/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +2 -0
- package/dist/types/types/data-structures/binary-tree/avl-tree.d.ts +2 -0
- package/dist/types/types/data-structures/binary-tree/binary-indexed-tree.d.ts +1 -0
- package/dist/types/types/data-structures/binary-tree/binary-tree.d.ts +29 -0
- package/dist/types/types/data-structures/binary-tree/bst.d.ts +12 -0
- package/dist/{data-structures → types/types/data-structures}/binary-tree/index.d.ts +2 -3
- package/dist/types/types/data-structures/binary-tree/red-black-tree.d.ts +3 -0
- package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -0
- package/dist/types/types/data-structures/binary-tree/tree-counter.d.ts +2 -0
- package/dist/types/types/data-structures/binary-tree/tree-multi-map.d.ts +2 -0
- package/dist/types/types/data-structures/graph/abstract-graph.d.ts +14 -0
- package/dist/types/types/data-structures/graph/directed-graph.d.ts +1 -0
- package/dist/{data-structures → types/types/data-structures}/graph/index.d.ts +1 -2
- package/dist/types/types/data-structures/graph/map-graph.d.ts +1 -0
- package/dist/types/types/data-structures/graph/undirected-graph.d.ts +1 -0
- package/dist/types/types/data-structures/hash/hash-map.d.ts +19 -0
- package/dist/types/types/data-structures/hash/index.d.ts +2 -0
- package/dist/types/types/data-structures/heap/heap.d.ts +5 -0
- package/dist/types/types/data-structures/heap/index.d.ts +1 -0
- package/dist/types/types/data-structures/heap/max-heap.d.ts +1 -0
- package/dist/types/types/data-structures/heap/min-heap.d.ts +1 -0
- package/dist/types/types/data-structures/linked-list/doubly-linked-list.d.ts +2 -0
- package/dist/types/types/data-structures/linked-list/singly-linked-list.d.ts +2 -0
- package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +4 -0
- package/dist/types/types/data-structures/matrix/matrix.d.ts +7 -0
- package/dist/types/types/data-structures/matrix/navigator.d.ts +14 -0
- package/dist/types/types/data-structures/priority-queue/max-priority-queue.d.ts +1 -0
- package/dist/types/types/data-structures/priority-queue/min-priority-queue.d.ts +1 -0
- package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +2 -0
- package/dist/types/types/data-structures/queue/deque.d.ts +4 -0
- package/dist/types/types/data-structures/queue/queue.d.ts +4 -0
- package/dist/types/types/data-structures/stack/stack.d.ts +2 -0
- package/dist/types/types/data-structures/tree/tree.d.ts +1 -0
- package/dist/types/types/data-structures/trie/trie.d.ts +4 -0
- package/dist/types/types/index.d.ts +3 -0
- package/dist/types/types/utils/index.d.ts +2 -0
- package/dist/types/types/utils/utils.d.ts +22 -0
- package/dist/types/utils/index.d.ts +1 -1
- package/dist/types/utils/utils.d.ts +209 -22
- package/dist/umd/heap-typed.js +1023 -0
- package/dist/umd/heap-typed.js.map +1 -0
- package/dist/umd/heap-typed.min.js +22 -0
- package/dist/umd/heap-typed.min.js.map +1 -0
- package/package.json +25 -5
- package/src/data-structures/binary-tree/avl-tree-counter.ts +4 -4
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +1 -1
- package/src/data-structures/binary-tree/avl-tree.ts +2 -2
- package/src/data-structures/binary-tree/binary-tree.ts +4 -4
- package/src/data-structures/binary-tree/bst.ts +1 -1
- package/src/data-structures/binary-tree/red-black-tree.ts +2 -2
- package/src/data-structures/binary-tree/tree-counter.ts +4 -4
- package/src/data-structures/binary-tree/tree-multi-map.ts +1 -1
- package/src/data-structures/heap/heap.ts +5 -5
- package/src/data-structures/linked-list/singly-linked-list.ts +2 -2
- package/src/interfaces/binary-tree.ts +1 -1
- package/tsconfig.base.json +23 -0
- package/tsconfig.json +8 -34
- package/tsconfig.test.json +8 -0
- package/tsconfig.types.json +15 -0
- package/tsup.config.js +28 -0
- package/tsup.node.config.js +37 -0
- package/dist/common/index.js +0 -28
- package/dist/constants/index.js +0 -8
- package/dist/data-structures/base/index.d.ts +0 -2
- package/dist/data-structures/base/index.js +0 -18
- package/dist/data-structures/base/iterable-element-base.js +0 -243
- package/dist/data-structures/base/iterable-entry-base.js +0 -183
- package/dist/data-structures/base/linear-base.js +0 -415
- package/dist/data-structures/binary-tree/avl-tree-counter.d.ts +0 -182
- package/dist/data-structures/binary-tree/avl-tree-counter.js +0 -374
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +0 -135
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +0 -250
- package/dist/data-structures/binary-tree/avl-tree.d.ts +0 -291
- package/dist/data-structures/binary-tree/avl-tree.js +0 -611
- package/dist/data-structures/binary-tree/binary-indexed-tree.d.ts +0 -174
- package/dist/data-structures/binary-tree/binary-indexed-tree.js +0 -294
- package/dist/data-structures/binary-tree/binary-tree.d.ts +0 -754
- package/dist/data-structures/binary-tree/binary-tree.js +0 -1925
- package/dist/data-structures/binary-tree/bst.d.ts +0 -413
- package/dist/data-structures/binary-tree/bst.js +0 -903
- package/dist/data-structures/binary-tree/index.js +0 -26
- package/dist/data-structures/binary-tree/red-black-tree.d.ts +0 -208
- package/dist/data-structures/binary-tree/red-black-tree.js +0 -546
- package/dist/data-structures/binary-tree/segment-tree.d.ts +0 -160
- package/dist/data-structures/binary-tree/segment-tree.js +0 -297
- package/dist/data-structures/binary-tree/tree-counter.d.ts +0 -190
- package/dist/data-structures/binary-tree/tree-counter.js +0 -413
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +0 -270
- package/dist/data-structures/binary-tree/tree-multi-map.js +0 -384
- package/dist/data-structures/graph/abstract-graph.d.ts +0 -340
- package/dist/data-structures/graph/abstract-graph.js +0 -896
- package/dist/data-structures/graph/directed-graph.d.ts +0 -207
- package/dist/data-structures/graph/directed-graph.js +0 -525
- package/dist/data-structures/graph/index.js +0 -20
- package/dist/data-structures/graph/map-graph.d.ts +0 -78
- package/dist/data-structures/graph/map-graph.js +0 -107
- package/dist/data-structures/graph/undirected-graph.d.ts +0 -188
- package/dist/data-structures/graph/undirected-graph.js +0 -424
- package/dist/data-structures/hash/hash-map.d.ts +0 -345
- package/dist/data-structures/hash/hash-map.js +0 -692
- package/dist/data-structures/hash/index.d.ts +0 -1
- package/dist/data-structures/hash/index.js +0 -17
- package/dist/data-structures/heap/heap.d.ts +0 -503
- package/dist/data-structures/heap/heap.js +0 -901
- package/dist/data-structures/heap/index.d.ts +0 -3
- package/dist/data-structures/heap/index.js +0 -19
- package/dist/data-structures/heap/max-heap.d.ts +0 -32
- package/dist/data-structures/heap/max-heap.js +0 -40
- package/dist/data-structures/heap/min-heap.d.ts +0 -33
- package/dist/data-structures/heap/min-heap.js +0 -31
- package/dist/data-structures/index.js +0 -28
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +0 -769
- package/dist/data-structures/linked-list/doubly-linked-list.js +0 -1111
- package/dist/data-structures/linked-list/index.js +0 -19
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +0 -451
- package/dist/data-structures/linked-list/singly-linked-list.js +0 -850
- package/dist/data-structures/linked-list/skip-linked-list.d.ts +0 -27
- package/dist/data-structures/linked-list/skip-linked-list.js +0 -144
- package/dist/data-structures/matrix/index.js +0 -18
- package/dist/data-structures/matrix/matrix.d.ts +0 -168
- package/dist/data-structures/matrix/matrix.js +0 -448
- package/dist/data-structures/matrix/navigator.d.ts +0 -55
- package/dist/data-structures/matrix/navigator.js +0 -111
- package/dist/data-structures/priority-queue/index.js +0 -19
- package/dist/data-structures/priority-queue/max-priority-queue.d.ts +0 -27
- package/dist/data-structures/priority-queue/max-priority-queue.js +0 -34
- package/dist/data-structures/priority-queue/min-priority-queue.d.ts +0 -26
- package/dist/data-structures/priority-queue/min-priority-queue.js +0 -24
- package/dist/data-structures/priority-queue/priority-queue.d.ts +0 -15
- package/dist/data-structures/priority-queue/priority-queue.js +0 -20
- package/dist/data-structures/queue/deque.d.ts +0 -431
- package/dist/data-structures/queue/deque.js +0 -879
- package/dist/data-structures/queue/index.js +0 -18
- package/dist/data-structures/queue/queue.d.ts +0 -308
- package/dist/data-structures/queue/queue.js +0 -473
- package/dist/data-structures/stack/index.js +0 -17
- package/dist/data-structures/stack/stack.d.ts +0 -306
- package/dist/data-structures/stack/stack.js +0 -401
- package/dist/data-structures/tree/index.js +0 -17
- package/dist/data-structures/tree/tree.d.ts +0 -62
- package/dist/data-structures/tree/tree.js +0 -107
- package/dist/data-structures/trie/index.js +0 -17
- package/dist/data-structures/trie/trie.d.ts +0 -350
- package/dist/data-structures/trie/trie.js +0 -610
- package/dist/index.d.ts +0 -12
- package/dist/index.js +0 -28
- package/dist/interfaces/binary-tree.js +0 -2
- package/dist/interfaces/doubly-linked-list.js +0 -2
- package/dist/interfaces/graph.js +0 -2
- package/dist/interfaces/heap.js +0 -2
- package/dist/interfaces/index.js +0 -24
- package/dist/interfaces/navigator.js +0 -2
- package/dist/interfaces/priority-queue.js +0 -2
- package/dist/interfaces/segment-tree.js +0 -2
- package/dist/interfaces/singly-linked-list.js +0 -2
- package/dist/types/common.js +0 -2
- package/dist/types/data-structures/base/base.js +0 -2
- package/dist/types/data-structures/base/index.js +0 -17
- package/dist/types/data-structures/binary-tree/avl-tree-counter.js +0 -2
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.js +0 -2
- package/dist/types/data-structures/binary-tree/avl-tree.js +0 -2
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.js +0 -2
- package/dist/types/data-structures/binary-tree/binary-tree.js +0 -2
- package/dist/types/data-structures/binary-tree/bst.js +0 -2
- package/dist/types/data-structures/binary-tree/index.js +0 -25
- package/dist/types/data-structures/binary-tree/red-black-tree.js +0 -2
- package/dist/types/data-structures/binary-tree/segment-tree.js +0 -2
- package/dist/types/data-structures/binary-tree/tree-counter.js +0 -2
- package/dist/types/data-structures/binary-tree/tree-multi-map.js +0 -2
- package/dist/types/data-structures/graph/abstract-graph.js +0 -2
- package/dist/types/data-structures/graph/directed-graph.js +0 -2
- package/dist/types/data-structures/graph/index.js +0 -19
- package/dist/types/data-structures/graph/map-graph.js +0 -2
- package/dist/types/data-structures/graph/undirected-graph.js +0 -2
- package/dist/types/data-structures/hash/hash-map.js +0 -2
- package/dist/types/data-structures/hash/index.js +0 -17
- package/dist/types/data-structures/heap/heap.js +0 -2
- package/dist/types/data-structures/heap/index.js +0 -17
- package/dist/types/data-structures/heap/max-heap.js +0 -2
- package/dist/types/data-structures/heap/min-heap.js +0 -2
- package/dist/types/data-structures/index.js +0 -28
- package/dist/types/data-structures/linked-list/doubly-linked-list.js +0 -2
- package/dist/types/data-structures/linked-list/index.js +0 -19
- package/dist/types/data-structures/linked-list/singly-linked-list.js +0 -2
- package/dist/types/data-structures/linked-list/skip-linked-list.js +0 -2
- package/dist/types/data-structures/matrix/index.js +0 -18
- package/dist/types/data-structures/matrix/matrix.js +0 -2
- package/dist/types/data-structures/matrix/navigator.js +0 -2
- package/dist/types/data-structures/priority-queue/index.js +0 -19
- package/dist/types/data-structures/priority-queue/max-priority-queue.js +0 -2
- package/dist/types/data-structures/priority-queue/min-priority-queue.js +0 -2
- package/dist/types/data-structures/priority-queue/priority-queue.js +0 -2
- package/dist/types/data-structures/queue/deque.js +0 -2
- package/dist/types/data-structures/queue/index.js +0 -18
- package/dist/types/data-structures/queue/queue.js +0 -2
- package/dist/types/data-structures/stack/index.js +0 -17
- package/dist/types/data-structures/stack/stack.js +0 -2
- package/dist/types/data-structures/tree/index.js +0 -17
- package/dist/types/data-structures/tree/tree.js +0 -2
- package/dist/types/data-structures/trie/index.js +0 -17
- package/dist/types/data-structures/trie/trie.js +0 -2
- package/dist/types/index.js +0 -19
- package/dist/types/utils/index.js +0 -18
- package/dist/types/utils/utils.js +0 -2
- package/dist/types/utils/validate-type.js +0 -2
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/index.js +0 -18
- package/dist/utils/number.js +0 -24
- package/dist/utils/utils.d.ts +0 -209
- package/dist/utils/utils.js +0 -353
- package/dist/{common → types/common}/index.d.ts +0 -0
- package/dist/{constants → types/constants}/index.d.ts +0 -0
- package/dist/{data-structures → types/data-structures}/base/iterable-element-base.d.ts +0 -0
- package/dist/{data-structures → types/data-structures}/base/iterable-entry-base.d.ts +0 -0
- package/dist/{data-structures → types/data-structures}/base/linear-base.d.ts +0 -0
- package/dist/{interfaces → types/interfaces}/doubly-linked-list.d.ts +0 -0
- package/dist/{interfaces → types/interfaces}/graph.d.ts +0 -0
- package/dist/{interfaces → types/interfaces}/heap.d.ts +0 -0
- package/dist/{interfaces → types/interfaces}/index.d.ts +0 -0
- package/dist/{interfaces → types/interfaces}/navigator.d.ts +0 -0
- package/dist/{interfaces → types/interfaces}/priority-queue.d.ts +0 -0
- package/dist/{interfaces → types/interfaces}/segment-tree.d.ts +0 -0
- package/dist/{interfaces → types/interfaces}/singly-linked-list.d.ts +0 -0
- package/dist/types/{common.d.ts → types/common.d.ts} +0 -0
- package/dist/types/{data-structures → types/data-structures}/base/base.d.ts +0 -0
- package/dist/{data-structures → types/types/data-structures}/index.d.ts +7 -7
- package/dist/{data-structures → types/types/data-structures}/linked-list/index.d.ts +0 -0
- package/dist/{data-structures → types/types/data-structures}/matrix/index.d.ts +1 -1
- /package/dist/{data-structures → types/types/data-structures}/priority-queue/index.d.ts +0 -0
- /package/dist/{data-structures → types/types/data-structures}/queue/index.d.ts +0 -0
- /package/dist/{data-structures → types/types/data-structures}/stack/index.d.ts +0 -0
- /package/dist/{data-structures → types/types/data-structures}/tree/index.d.ts +0 -0
- /package/dist/{data-structures → types/types/data-structures}/trie/index.d.ts +0 -0
- /package/dist/types/{utils → types/utils}/validate-type.d.ts +0 -0
- /package/dist/{utils → types/utils}/number.d.ts +0 -0
|
@@ -1,896 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* data-structure-typed
|
|
4
|
-
*
|
|
5
|
-
* @author Pablo Zeng
|
|
6
|
-
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
|
7
|
-
* @license MIT License
|
|
8
|
-
*/
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.AbstractGraph = exports.AbstractEdge = exports.AbstractVertex = void 0;
|
|
11
|
-
const utils_1 = require("../../utils");
|
|
12
|
-
const base_1 = require("../base");
|
|
13
|
-
const heap_1 = require("../heap");
|
|
14
|
-
const queue_1 = require("../queue");
|
|
15
|
-
class AbstractVertex {
|
|
16
|
-
constructor(key, value) {
|
|
17
|
-
this.key = key;
|
|
18
|
-
this.value = value;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
exports.AbstractVertex = AbstractVertex;
|
|
22
|
-
class AbstractEdge {
|
|
23
|
-
constructor(weight, value) {
|
|
24
|
-
this.weight = weight !== undefined ? weight : 1;
|
|
25
|
-
this.value = value;
|
|
26
|
-
this._hashCode = (0, utils_1.uuidV4)();
|
|
27
|
-
}
|
|
28
|
-
get hashCode() {
|
|
29
|
-
return this._hashCode;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
exports.AbstractEdge = AbstractEdge;
|
|
33
|
-
/**
|
|
34
|
-
* Abstract graph over vertices and edges.
|
|
35
|
-
* @template V - Vertex value type.
|
|
36
|
-
* @template E - Edge value type.
|
|
37
|
-
* @template VO - Concrete vertex subclass (extends AbstractVertex<V>).
|
|
38
|
-
* @template EO - Concrete edge subclass (extends AbstractEdge<E>).
|
|
39
|
-
* @remarks Time O(1), Space O(1)
|
|
40
|
-
* @example examples will be generated by unit test
|
|
41
|
-
*/
|
|
42
|
-
class AbstractGraph extends base_1.IterableEntryBase {
|
|
43
|
-
/**
|
|
44
|
-
* Construct a graph with runtime defaults.
|
|
45
|
-
* @param options - `GraphOptions<V>` in `options.graph` (e.g. `vertexValueInitializer`, `defaultEdgeWeight`).
|
|
46
|
-
* @remarks Time O(1), Space O(1)
|
|
47
|
-
*/
|
|
48
|
-
constructor(options) {
|
|
49
|
-
super();
|
|
50
|
-
this._options = { defaultEdgeWeight: 1 };
|
|
51
|
-
this._vertexMap = new Map();
|
|
52
|
-
const graph = options === null || options === void 0 ? void 0 : options.graph;
|
|
53
|
-
this._options = Object.assign({ defaultEdgeWeight: 1 }, (graph !== null && graph !== void 0 ? graph : {}));
|
|
54
|
-
}
|
|
55
|
-
get options() {
|
|
56
|
-
return this._options;
|
|
57
|
-
}
|
|
58
|
-
get vertexMap() {
|
|
59
|
-
return this._vertexMap;
|
|
60
|
-
}
|
|
61
|
-
set vertexMap(v) {
|
|
62
|
-
this._vertexMap = v;
|
|
63
|
-
}
|
|
64
|
-
get size() {
|
|
65
|
-
return this._vertexMap.size;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Get vertex instance by key.
|
|
69
|
-
* @param vertexKey - Vertex key.
|
|
70
|
-
* @returns Vertex instance or `undefined`.
|
|
71
|
-
* @remarks Time O(1), Space O(1)
|
|
72
|
-
*/
|
|
73
|
-
getVertex(vertexKey) {
|
|
74
|
-
return this._vertexMap.get(vertexKey) || undefined;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Whether a vertex exists.
|
|
78
|
-
* @param vertexOrKey - Vertex or key.
|
|
79
|
-
* @returns `true` if present, otherwise `false`.
|
|
80
|
-
* @remarks Time O(1) avg, Space O(1)
|
|
81
|
-
*/
|
|
82
|
-
hasVertex(vertexOrKey) {
|
|
83
|
-
return this._vertexMap.has(this._getVertexKey(vertexOrKey));
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Add a vertex by key/value or by pre-built vertex.
|
|
87
|
-
* @param keyOrVertex - Vertex key or existing vertex instance.
|
|
88
|
-
* @param value - Optional payload.
|
|
89
|
-
* @returns `true` if inserted; `false` when key already exists.
|
|
90
|
-
* @remarks Time O(1) avg, Space O(1)
|
|
91
|
-
*/
|
|
92
|
-
addVertex(keyOrVertex, value) {
|
|
93
|
-
if (keyOrVertex instanceof AbstractVertex) {
|
|
94
|
-
return this._addVertex(keyOrVertex);
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
const newVertex = this.createVertex(keyOrVertex, value);
|
|
98
|
-
return this._addVertex(newVertex);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Type guard: check if a value is a valid vertex key.
|
|
103
|
-
* @param potentialKey - Value to test.
|
|
104
|
-
* @returns `true` if string/number; else `false`.
|
|
105
|
-
* @remarks Time O(1), Space O(1)
|
|
106
|
-
*/
|
|
107
|
-
isVertexKey(potentialKey) {
|
|
108
|
-
const potentialKeyType = typeof potentialKey;
|
|
109
|
-
return potentialKeyType === 'string' || potentialKeyType === 'number';
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Delete multiple vertices.
|
|
113
|
-
* @param vertexMap - Array of vertices or keys.
|
|
114
|
-
* @returns `true` if any vertex was removed.
|
|
115
|
-
* @remarks Time O(sum(deg)), Space O(1)
|
|
116
|
-
*/
|
|
117
|
-
removeManyVertices(vertexMap) {
|
|
118
|
-
const removed = [];
|
|
119
|
-
for (const v of vertexMap) {
|
|
120
|
-
removed.push(this.deleteVertex(v));
|
|
121
|
-
}
|
|
122
|
-
return removed.length > 0;
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Whether an edge exists between two vertices.
|
|
126
|
-
* @param v1 - Endpoint A vertex or key.
|
|
127
|
-
* @param v2 - Endpoint B vertex or key.
|
|
128
|
-
* @returns `true` if present; otherwise `false`.
|
|
129
|
-
* @remarks Time O(1) avg, Space O(1)
|
|
130
|
-
*/
|
|
131
|
-
hasEdge(v1, v2) {
|
|
132
|
-
const edge = this.getEdge(v1, v2);
|
|
133
|
-
return !!edge;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Add an edge by instance or by `(src, dest, weight?, value?)`.
|
|
137
|
-
* @param srcOrEdge - Edge instance or source vertex/key.
|
|
138
|
-
* @param dest - Destination vertex/key (when adding by pair).
|
|
139
|
-
* @param weight - Edge weight.
|
|
140
|
-
* @param value - Edge payload.
|
|
141
|
-
* @returns `true` if inserted; otherwise `false`.
|
|
142
|
-
* @remarks Time O(1) avg, Space O(1)
|
|
143
|
-
*/
|
|
144
|
-
addEdge(srcOrEdge, dest, weight, value) {
|
|
145
|
-
if (srcOrEdge instanceof AbstractEdge) {
|
|
146
|
-
return this._addEdge(srcOrEdge);
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
if (dest instanceof AbstractVertex || typeof dest === 'string' || typeof dest === 'number') {
|
|
150
|
-
if (!(this.hasVertex(srcOrEdge) && this.hasVertex(dest)))
|
|
151
|
-
return false;
|
|
152
|
-
if (srcOrEdge instanceof AbstractVertex)
|
|
153
|
-
srcOrEdge = srcOrEdge.key;
|
|
154
|
-
if (dest instanceof AbstractVertex)
|
|
155
|
-
dest = dest.key;
|
|
156
|
-
const newEdge = this.createEdge(srcOrEdge, dest, weight, value);
|
|
157
|
-
return this._addEdge(newEdge);
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
throw new Error('dest must be a Vertex or vertex key while srcOrEdge is an Edge');
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Set the weight of an existing edge.
|
|
166
|
-
* @param srcOrKey - Source vertex or key.
|
|
167
|
-
* @param destOrKey - Destination vertex or key.
|
|
168
|
-
* @param weight - New weight.
|
|
169
|
-
* @returns `true` if updated; otherwise `false`.
|
|
170
|
-
* @remarks Time O(1) avg, Space O(1)
|
|
171
|
-
*/
|
|
172
|
-
setEdgeWeight(srcOrKey, destOrKey, weight) {
|
|
173
|
-
const edge = this.getEdge(srcOrKey, destOrKey);
|
|
174
|
-
if (edge) {
|
|
175
|
-
edge.weight = weight;
|
|
176
|
-
return true;
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
return false;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Enumerate simple paths up to a limit.
|
|
184
|
-
* @param v1 - Source vertex or key.
|
|
185
|
-
* @param v2 - Destination vertex or key.
|
|
186
|
-
* @param limit - Maximum number of paths to collect.
|
|
187
|
-
* @returns Array of paths (each path is an array of vertices).
|
|
188
|
-
* @remarks Time O(paths) worst-case exponential, Space O(V + paths)
|
|
189
|
-
*/
|
|
190
|
-
getAllPathsBetween(v1, v2, limit = 1000) {
|
|
191
|
-
const paths = [];
|
|
192
|
-
const vertex1 = this._getVertex(v1);
|
|
193
|
-
const vertex2 = this._getVertex(v2);
|
|
194
|
-
if (!(vertex1 && vertex2)) {
|
|
195
|
-
return [];
|
|
196
|
-
}
|
|
197
|
-
const stack = [];
|
|
198
|
-
stack.push({ vertex: vertex1, path: [vertex1] });
|
|
199
|
-
while (stack.length > 0) {
|
|
200
|
-
const { vertex, path } = stack.pop();
|
|
201
|
-
if (vertex === vertex2) {
|
|
202
|
-
paths.push(path);
|
|
203
|
-
if (paths.length >= limit)
|
|
204
|
-
return paths;
|
|
205
|
-
}
|
|
206
|
-
const neighbors = this.getNeighbors(vertex);
|
|
207
|
-
for (const neighbor of neighbors) {
|
|
208
|
-
if (!path.includes(neighbor)) {
|
|
209
|
-
const newPath = [...path, neighbor];
|
|
210
|
-
stack.push({ vertex: neighbor, path: newPath });
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
return paths;
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* Sum the weights along a vertex path.
|
|
218
|
-
* @param path - Sequence of vertices.
|
|
219
|
-
* @returns Path weight sum (0 if empty or edge missing).
|
|
220
|
-
* @remarks Time O(L), Space O(1) where L is path length
|
|
221
|
-
*/
|
|
222
|
-
getPathSumWeight(path) {
|
|
223
|
-
var _a;
|
|
224
|
-
let sum = 0;
|
|
225
|
-
for (let i = 0; i < path.length; i++) {
|
|
226
|
-
sum += ((_a = this.getEdge(path[i], path[i + 1])) === null || _a === void 0 ? void 0 : _a.weight) || 0;
|
|
227
|
-
}
|
|
228
|
-
return sum;
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Minimum hops/weight between two vertices.
|
|
232
|
-
* @param v1 - Source vertex or key.
|
|
233
|
-
* @param v2 - Destination vertex or key.
|
|
234
|
-
* @param isWeight - If `true`, compare by path weight; otherwise by hop count.
|
|
235
|
-
* @returns Minimum cost or `undefined` if missing/unreachable.
|
|
236
|
-
* @remarks Time O((V + E) log V) weighted / O(V + E) unweighted, Space O(V + E)
|
|
237
|
-
*/
|
|
238
|
-
getMinCostBetween(v1, v2, isWeight) {
|
|
239
|
-
if (isWeight === undefined)
|
|
240
|
-
isWeight = false;
|
|
241
|
-
if (isWeight) {
|
|
242
|
-
const allPaths = this.getAllPathsBetween(v1, v2);
|
|
243
|
-
let min = Number.MAX_SAFE_INTEGER;
|
|
244
|
-
for (const path of allPaths) {
|
|
245
|
-
min = Math.min(this.getPathSumWeight(path), min);
|
|
246
|
-
}
|
|
247
|
-
return min;
|
|
248
|
-
}
|
|
249
|
-
else {
|
|
250
|
-
const vertex2 = this._getVertex(v2);
|
|
251
|
-
const vertex1 = this._getVertex(v1);
|
|
252
|
-
if (!(vertex1 && vertex2)) {
|
|
253
|
-
return undefined;
|
|
254
|
-
}
|
|
255
|
-
const visited = new Map();
|
|
256
|
-
const queue = new queue_1.Queue([vertex1]);
|
|
257
|
-
visited.set(vertex1, true);
|
|
258
|
-
let cost = 0;
|
|
259
|
-
while (queue.length > 0) {
|
|
260
|
-
for (let i = 0, layerSize = queue.length; i < layerSize; i++) {
|
|
261
|
-
const cur = queue.shift();
|
|
262
|
-
if (cur === vertex2) {
|
|
263
|
-
return cost;
|
|
264
|
-
}
|
|
265
|
-
if (cur !== undefined) {
|
|
266
|
-
const neighbors = this.getNeighbors(cur);
|
|
267
|
-
for (const neighbor of neighbors) {
|
|
268
|
-
if (!visited.has(neighbor)) {
|
|
269
|
-
visited.set(neighbor, true);
|
|
270
|
-
queue.push(neighbor);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
cost++;
|
|
276
|
-
}
|
|
277
|
-
return undefined;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Minimum path (as vertex sequence) between two vertices.
|
|
282
|
-
* @param v1 - Source vertex or key.
|
|
283
|
-
* @param v2 - Destination vertex or key.
|
|
284
|
-
* @param isWeight - If `true`, compare by path weight; otherwise by hop count.
|
|
285
|
-
* @param isDFS - For weighted mode only: if `true`, brute-force all paths; if `false`, use Dijkstra.
|
|
286
|
-
* @returns Vertex sequence, or `undefined`/empty when unreachable depending on branch.
|
|
287
|
-
* @remarks Time O((V + E) log V) weighted / O(V + E) unweighted, Space O(V + E)
|
|
288
|
-
*/
|
|
289
|
-
getMinPathBetween(v1, v2, isWeight, isDFS = false) {
|
|
290
|
-
var _a, _b;
|
|
291
|
-
if (isWeight === undefined)
|
|
292
|
-
isWeight = false;
|
|
293
|
-
if (isWeight) {
|
|
294
|
-
if (isDFS) {
|
|
295
|
-
const allPaths = this.getAllPathsBetween(v1, v2, 10000);
|
|
296
|
-
let min = Number.MAX_SAFE_INTEGER;
|
|
297
|
-
let minIndex = -1;
|
|
298
|
-
let index = 0;
|
|
299
|
-
for (const path of allPaths) {
|
|
300
|
-
const pathSumWeight = this.getPathSumWeight(path);
|
|
301
|
-
if (pathSumWeight < min) {
|
|
302
|
-
min = pathSumWeight;
|
|
303
|
-
minIndex = index;
|
|
304
|
-
}
|
|
305
|
-
index++;
|
|
306
|
-
}
|
|
307
|
-
return allPaths[minIndex] || undefined;
|
|
308
|
-
}
|
|
309
|
-
else {
|
|
310
|
-
/**
|
|
311
|
-
* Dijkstra (binary-heap) shortest paths for non-negative weights.
|
|
312
|
-
* @param src - Source vertex or key.
|
|
313
|
-
* @param dest - Optional destination for early stop.
|
|
314
|
-
* @param getMinDist - If `true`, compute global minimum distance.
|
|
315
|
-
* @param genPaths - If `true`, also generate path arrays.
|
|
316
|
-
* @returns Result bag or `undefined` if source missing.
|
|
317
|
-
* @remarks Time O((V + E) log V), Space O(V + E)
|
|
318
|
-
*/
|
|
319
|
-
return (_b = (_a = this.dijkstra(v1, v2, true, true)) === null || _a === void 0 ? void 0 : _a.minPath) !== null && _b !== void 0 ? _b : [];
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
else {
|
|
323
|
-
let minPath = [];
|
|
324
|
-
const vertex1 = this._getVertex(v1);
|
|
325
|
-
const vertex2 = this._getVertex(v2);
|
|
326
|
-
if (!(vertex1 && vertex2))
|
|
327
|
-
return [];
|
|
328
|
-
const dfs = (cur, dest, visiting, path) => {
|
|
329
|
-
visiting.add(cur);
|
|
330
|
-
if (cur === dest) {
|
|
331
|
-
minPath = [vertex1, ...path];
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
const neighbors = this.getNeighbors(cur);
|
|
335
|
-
for (const neighbor of neighbors) {
|
|
336
|
-
if (!visiting.has(neighbor)) {
|
|
337
|
-
path.push(neighbor);
|
|
338
|
-
dfs(neighbor, dest, visiting, path);
|
|
339
|
-
path.pop();
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
visiting.delete(cur);
|
|
343
|
-
};
|
|
344
|
-
dfs(vertex1, vertex2, new Set(), []);
|
|
345
|
-
return minPath;
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
/**
|
|
349
|
-
* Dijkstra without heap (array-based selection).
|
|
350
|
-
* @param src - Source vertex or key.
|
|
351
|
-
* @param dest - Optional destination for early stop.
|
|
352
|
-
* @param getMinDist - If `true`, compute global minimum distance.
|
|
353
|
-
* @param genPaths - If `true`, also generate path arrays.
|
|
354
|
-
* @returns Result bag or `undefined` if source missing.
|
|
355
|
-
* @remarks Time O(V^2 + E), Space O(V + E)
|
|
356
|
-
*/
|
|
357
|
-
dijkstraWithoutHeap(src, dest = undefined, getMinDist = false, genPaths = false) {
|
|
358
|
-
let minDist = Number.MAX_SAFE_INTEGER;
|
|
359
|
-
let minDest = undefined;
|
|
360
|
-
let minPath = [];
|
|
361
|
-
const paths = [];
|
|
362
|
-
const vertexMap = this._vertexMap;
|
|
363
|
-
const distMap = new Map();
|
|
364
|
-
const seen = new Set();
|
|
365
|
-
const preMap = new Map();
|
|
366
|
-
const srcVertex = this._getVertex(src);
|
|
367
|
-
const destVertex = dest ? this._getVertex(dest) : undefined;
|
|
368
|
-
if (!srcVertex) {
|
|
369
|
-
return undefined;
|
|
370
|
-
}
|
|
371
|
-
for (const vertex of vertexMap) {
|
|
372
|
-
const vertexOrKey = vertex[1];
|
|
373
|
-
if (vertexOrKey instanceof AbstractVertex)
|
|
374
|
-
distMap.set(vertexOrKey, Number.MAX_SAFE_INTEGER);
|
|
375
|
-
}
|
|
376
|
-
distMap.set(srcVertex, 0);
|
|
377
|
-
preMap.set(srcVertex, undefined);
|
|
378
|
-
const getMinOfNoSeen = () => {
|
|
379
|
-
let min = Number.MAX_SAFE_INTEGER;
|
|
380
|
-
let minV = undefined;
|
|
381
|
-
for (const [key, value] of distMap) {
|
|
382
|
-
if (!seen.has(key)) {
|
|
383
|
-
if (value < min) {
|
|
384
|
-
min = value;
|
|
385
|
-
minV = key;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
return minV;
|
|
390
|
-
};
|
|
391
|
-
const getPaths = (minV) => {
|
|
392
|
-
for (const vertex of vertexMap) {
|
|
393
|
-
const vertexOrKey = vertex[1];
|
|
394
|
-
if (vertexOrKey instanceof AbstractVertex) {
|
|
395
|
-
const path = [vertexOrKey];
|
|
396
|
-
let parent = preMap.get(vertexOrKey);
|
|
397
|
-
while (parent) {
|
|
398
|
-
path.push(parent);
|
|
399
|
-
parent = preMap.get(parent);
|
|
400
|
-
}
|
|
401
|
-
const reversed = path.reverse();
|
|
402
|
-
if (vertex[1] === minV)
|
|
403
|
-
minPath = reversed;
|
|
404
|
-
paths.push(reversed);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
};
|
|
408
|
-
for (let i = 1; i < vertexMap.size; i++) {
|
|
409
|
-
const cur = getMinOfNoSeen();
|
|
410
|
-
if (cur) {
|
|
411
|
-
seen.add(cur);
|
|
412
|
-
if (destVertex && destVertex === cur) {
|
|
413
|
-
if (getMinDist) {
|
|
414
|
-
minDist = distMap.get(destVertex) || Number.MAX_SAFE_INTEGER;
|
|
415
|
-
}
|
|
416
|
-
if (genPaths) {
|
|
417
|
-
getPaths(destVertex);
|
|
418
|
-
}
|
|
419
|
-
return { distMap, preMap, seen, paths, minDist, minPath };
|
|
420
|
-
}
|
|
421
|
-
const neighbors = this.getNeighbors(cur);
|
|
422
|
-
for (const neighbor of neighbors) {
|
|
423
|
-
if (!seen.has(neighbor)) {
|
|
424
|
-
const edge = this.getEdge(cur, neighbor);
|
|
425
|
-
if (edge) {
|
|
426
|
-
const curFromMap = distMap.get(cur);
|
|
427
|
-
const neighborFromMap = distMap.get(neighbor);
|
|
428
|
-
if (curFromMap !== undefined && neighborFromMap !== undefined) {
|
|
429
|
-
if (edge.weight + curFromMap < neighborFromMap) {
|
|
430
|
-
distMap.set(neighbor, edge.weight + curFromMap);
|
|
431
|
-
preMap.set(neighbor, cur);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
if (getMinDist)
|
|
440
|
-
distMap.forEach((d, v) => {
|
|
441
|
-
if (v !== srcVertex) {
|
|
442
|
-
if (d < minDist) {
|
|
443
|
-
minDist = d;
|
|
444
|
-
if (genPaths)
|
|
445
|
-
minDest = v;
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
});
|
|
449
|
-
if (genPaths)
|
|
450
|
-
getPaths(minDest);
|
|
451
|
-
return { distMap, preMap, seen, paths, minDist, minPath };
|
|
452
|
-
}
|
|
453
|
-
dijkstra(src, dest = undefined, getMinDist = false, genPaths = false) {
|
|
454
|
-
var _a;
|
|
455
|
-
let minDist = Number.MAX_SAFE_INTEGER;
|
|
456
|
-
let minDest = undefined;
|
|
457
|
-
let minPath = [];
|
|
458
|
-
const paths = [];
|
|
459
|
-
const vertexMap = this._vertexMap;
|
|
460
|
-
const distMap = new Map();
|
|
461
|
-
const seen = new Set();
|
|
462
|
-
const preMap = new Map();
|
|
463
|
-
const srcVertex = this._getVertex(src);
|
|
464
|
-
const destVertex = dest ? this._getVertex(dest) : undefined;
|
|
465
|
-
if (!srcVertex)
|
|
466
|
-
return undefined;
|
|
467
|
-
for (const vertex of vertexMap) {
|
|
468
|
-
const vertexOrKey = vertex[1];
|
|
469
|
-
if (vertexOrKey instanceof AbstractVertex)
|
|
470
|
-
distMap.set(vertexOrKey, Number.MAX_SAFE_INTEGER);
|
|
471
|
-
}
|
|
472
|
-
const heap = new heap_1.Heap([], { comparator: (a, b) => a.key - b.key });
|
|
473
|
-
heap.add({ key: 0, value: srcVertex });
|
|
474
|
-
distMap.set(srcVertex, 0);
|
|
475
|
-
preMap.set(srcVertex, undefined);
|
|
476
|
-
const getPaths = (minV) => {
|
|
477
|
-
for (const vertex of vertexMap) {
|
|
478
|
-
const vertexOrKey = vertex[1];
|
|
479
|
-
if (vertexOrKey instanceof AbstractVertex) {
|
|
480
|
-
const path = [vertexOrKey];
|
|
481
|
-
let parent = preMap.get(vertexOrKey);
|
|
482
|
-
while (parent) {
|
|
483
|
-
path.push(parent);
|
|
484
|
-
parent = preMap.get(parent);
|
|
485
|
-
}
|
|
486
|
-
const reversed = path.reverse();
|
|
487
|
-
if (vertex[1] === minV)
|
|
488
|
-
minPath = reversed;
|
|
489
|
-
paths.push(reversed);
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
};
|
|
493
|
-
while (heap.size > 0) {
|
|
494
|
-
const curHeapNode = heap.poll();
|
|
495
|
-
const dist = curHeapNode === null || curHeapNode === void 0 ? void 0 : curHeapNode.key;
|
|
496
|
-
const cur = curHeapNode === null || curHeapNode === void 0 ? void 0 : curHeapNode.value;
|
|
497
|
-
if (dist !== undefined) {
|
|
498
|
-
if (cur) {
|
|
499
|
-
seen.add(cur);
|
|
500
|
-
if (destVertex && destVertex === cur) {
|
|
501
|
-
if (getMinDist) {
|
|
502
|
-
minDist = distMap.get(destVertex) || Number.MAX_SAFE_INTEGER;
|
|
503
|
-
}
|
|
504
|
-
if (genPaths) {
|
|
505
|
-
getPaths(destVertex);
|
|
506
|
-
}
|
|
507
|
-
return { distMap, preMap, seen, paths, minDist, minPath };
|
|
508
|
-
}
|
|
509
|
-
const neighbors = this.getNeighbors(cur);
|
|
510
|
-
for (const neighbor of neighbors) {
|
|
511
|
-
if (!seen.has(neighbor)) {
|
|
512
|
-
const weight = (_a = this.getEdge(cur, neighbor)) === null || _a === void 0 ? void 0 : _a.weight;
|
|
513
|
-
if (typeof weight === 'number') {
|
|
514
|
-
const distSrcToNeighbor = distMap.get(neighbor);
|
|
515
|
-
if (distSrcToNeighbor !== undefined) {
|
|
516
|
-
if (dist + weight < distSrcToNeighbor) {
|
|
517
|
-
heap.add({ key: dist + weight, value: neighbor });
|
|
518
|
-
preMap.set(neighbor, cur);
|
|
519
|
-
distMap.set(neighbor, dist + weight);
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
if (getMinDist) {
|
|
529
|
-
distMap.forEach((d, v) => {
|
|
530
|
-
if (v !== srcVertex) {
|
|
531
|
-
if (d < minDist) {
|
|
532
|
-
minDist = d;
|
|
533
|
-
if (genPaths)
|
|
534
|
-
minDest = v;
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
});
|
|
538
|
-
}
|
|
539
|
-
if (genPaths) {
|
|
540
|
-
getPaths(minDest);
|
|
541
|
-
}
|
|
542
|
-
return { distMap, preMap, seen, paths, minDist, minPath };
|
|
543
|
-
}
|
|
544
|
-
/**
|
|
545
|
-
* Bellman-Ford single-source shortest paths with option to scan negative cycles.
|
|
546
|
-
* @param src - Source vertex or key.
|
|
547
|
-
* @param scanNegativeCycle - If `true`, also detect negative cycles.
|
|
548
|
-
* @param getMin - If `true`, compute global minimum distance.
|
|
549
|
-
* @param genPath - If `true`, generate path arrays via predecessor map.
|
|
550
|
-
* @returns Result bag including distances, predecessors, and optional cycle flag.
|
|
551
|
-
* @remarks Time O(V * E), Space O(V + E)
|
|
552
|
-
*/
|
|
553
|
-
bellmanFord(src, scanNegativeCycle, getMin, genPath) {
|
|
554
|
-
if (getMin === undefined)
|
|
555
|
-
getMin = false;
|
|
556
|
-
if (genPath === undefined)
|
|
557
|
-
genPath = false;
|
|
558
|
-
const srcVertex = this._getVertex(src);
|
|
559
|
-
const paths = [];
|
|
560
|
-
const distMap = new Map();
|
|
561
|
-
const preMap = new Map();
|
|
562
|
-
let min = Number.MAX_SAFE_INTEGER;
|
|
563
|
-
let minPath = [];
|
|
564
|
-
let hasNegativeCycle;
|
|
565
|
-
if (scanNegativeCycle)
|
|
566
|
-
hasNegativeCycle = false;
|
|
567
|
-
if (!srcVertex)
|
|
568
|
-
return { hasNegativeCycle, distMap, preMap, paths, min, minPath };
|
|
569
|
-
const vertexMap = this._vertexMap;
|
|
570
|
-
const numOfVertices = vertexMap.size;
|
|
571
|
-
const edgeMap = this.edgeSet();
|
|
572
|
-
const numOfEdges = edgeMap.length;
|
|
573
|
-
this._vertexMap.forEach(vertex => {
|
|
574
|
-
distMap.set(vertex, Number.MAX_SAFE_INTEGER);
|
|
575
|
-
});
|
|
576
|
-
distMap.set(srcVertex, 0);
|
|
577
|
-
for (let i = 1; i < numOfVertices; ++i) {
|
|
578
|
-
for (let j = 0; j < numOfEdges; ++j) {
|
|
579
|
-
const ends = this.getEndsOfEdge(edgeMap[j]);
|
|
580
|
-
if (ends) {
|
|
581
|
-
const [s, d] = ends;
|
|
582
|
-
const weight = edgeMap[j].weight;
|
|
583
|
-
const sWeight = distMap.get(s);
|
|
584
|
-
const dWeight = distMap.get(d);
|
|
585
|
-
if (sWeight !== undefined && dWeight !== undefined) {
|
|
586
|
-
if (distMap.get(s) !== Number.MAX_SAFE_INTEGER && sWeight + weight < dWeight) {
|
|
587
|
-
distMap.set(d, sWeight + weight);
|
|
588
|
-
if (genPath)
|
|
589
|
-
preMap.set(d, s);
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
let minDest = undefined;
|
|
596
|
-
if (getMin) {
|
|
597
|
-
distMap.forEach((d, v) => {
|
|
598
|
-
if (v !== srcVertex) {
|
|
599
|
-
if (d < min) {
|
|
600
|
-
min = d;
|
|
601
|
-
if (genPath)
|
|
602
|
-
minDest = v;
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
});
|
|
606
|
-
}
|
|
607
|
-
if (genPath) {
|
|
608
|
-
for (const vertex of vertexMap) {
|
|
609
|
-
const vertexOrKey = vertex[1];
|
|
610
|
-
if (vertexOrKey instanceof AbstractVertex) {
|
|
611
|
-
const path = [vertexOrKey];
|
|
612
|
-
let parent = preMap.get(vertexOrKey);
|
|
613
|
-
while (parent !== undefined) {
|
|
614
|
-
path.push(parent);
|
|
615
|
-
parent = preMap.get(parent);
|
|
616
|
-
}
|
|
617
|
-
const reversed = path.reverse();
|
|
618
|
-
if (vertex[1] === minDest)
|
|
619
|
-
minPath = reversed;
|
|
620
|
-
paths.push(reversed);
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
for (let j = 0; j < numOfEdges; ++j) {
|
|
625
|
-
const ends = this.getEndsOfEdge(edgeMap[j]);
|
|
626
|
-
if (ends) {
|
|
627
|
-
const [s] = ends;
|
|
628
|
-
const weight = edgeMap[j].weight;
|
|
629
|
-
const sWeight = distMap.get(s);
|
|
630
|
-
if (sWeight) {
|
|
631
|
-
if (sWeight !== Number.MAX_SAFE_INTEGER && sWeight + weight < sWeight)
|
|
632
|
-
hasNegativeCycle = true;
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
return { hasNegativeCycle, distMap, preMap, paths, min, minPath };
|
|
637
|
-
}
|
|
638
|
-
/**
|
|
639
|
-
* Floyd–Warshall all-pairs shortest paths.
|
|
640
|
-
* @returns `{ costs, predecessor }` matrices.
|
|
641
|
-
* @remarks Time O(V^3), Space O(V^2)
|
|
642
|
-
*/
|
|
643
|
-
floydWarshall() {
|
|
644
|
-
var _a;
|
|
645
|
-
const idAndVertices = [...this._vertexMap];
|
|
646
|
-
const n = idAndVertices.length;
|
|
647
|
-
const costs = [];
|
|
648
|
-
const predecessor = [];
|
|
649
|
-
for (let i = 0; i < n; i++) {
|
|
650
|
-
costs[i] = [];
|
|
651
|
-
predecessor[i] = [];
|
|
652
|
-
for (let j = 0; j < n; j++) {
|
|
653
|
-
predecessor[i][j] = undefined;
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
for (let i = 0; i < n; i++) {
|
|
657
|
-
for (let j = 0; j < n; j++) {
|
|
658
|
-
costs[i][j] = ((_a = this.getEdge(idAndVertices[i][1], idAndVertices[j][1])) === null || _a === void 0 ? void 0 : _a.weight) || Number.MAX_SAFE_INTEGER;
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
for (let k = 0; k < n; k++) {
|
|
662
|
-
for (let i = 0; i < n; i++) {
|
|
663
|
-
for (let j = 0; j < n; j++) {
|
|
664
|
-
if (costs[i][j] > costs[i][k] + costs[k][j]) {
|
|
665
|
-
costs[i][j] = costs[i][k] + costs[k][j];
|
|
666
|
-
predecessor[i][j] = idAndVertices[k][1];
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
return { costs, predecessor };
|
|
672
|
-
}
|
|
673
|
-
/**
|
|
674
|
-
* Enumerate simple cycles (may be expensive).
|
|
675
|
-
* @param isInclude2Cycle - If `true`, include 2-cycles when graph semantics allow.
|
|
676
|
-
* @returns Array of cycles (each as array of vertex keys).
|
|
677
|
-
* @remarks Time exponential in worst-case, Space O(V + E)
|
|
678
|
-
*/
|
|
679
|
-
getCycles(isInclude2Cycle = false) {
|
|
680
|
-
const cycles = [];
|
|
681
|
-
const visited = new Set();
|
|
682
|
-
const dfs = (vertex, currentPath, visited) => {
|
|
683
|
-
if (visited.has(vertex)) {
|
|
684
|
-
if (((!isInclude2Cycle && currentPath.length > 2) || (isInclude2Cycle && currentPath.length >= 2)) &&
|
|
685
|
-
currentPath[0] === vertex.key) {
|
|
686
|
-
cycles.push([...currentPath]);
|
|
687
|
-
}
|
|
688
|
-
return;
|
|
689
|
-
}
|
|
690
|
-
visited.add(vertex);
|
|
691
|
-
currentPath.push(vertex.key);
|
|
692
|
-
for (const neighbor of this.getNeighbors(vertex)) {
|
|
693
|
-
if (neighbor)
|
|
694
|
-
dfs(neighbor, currentPath, visited);
|
|
695
|
-
}
|
|
696
|
-
visited.delete(vertex);
|
|
697
|
-
currentPath.pop();
|
|
698
|
-
};
|
|
699
|
-
for (const vertex of this.vertexMap.values()) {
|
|
700
|
-
dfs(vertex, [], visited);
|
|
701
|
-
}
|
|
702
|
-
const uniqueCycles = new Map();
|
|
703
|
-
for (const cycle of cycles) {
|
|
704
|
-
const sorted = [...cycle].sort().toString();
|
|
705
|
-
if (uniqueCycles.has(sorted))
|
|
706
|
-
continue;
|
|
707
|
-
else {
|
|
708
|
-
uniqueCycles.set(sorted, cycle);
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
/**
|
|
712
|
-
* Map entries to an array via callback.
|
|
713
|
-
* @param callback - `(key, value, index, self) => T`.
|
|
714
|
-
* @param thisArg - Optional `this` for callback.
|
|
715
|
-
* @returns Mapped results.
|
|
716
|
-
* @remarks Time O(V), Space O(V)
|
|
717
|
-
*/
|
|
718
|
-
return [...uniqueCycles].map(cycleString => cycleString[1]);
|
|
719
|
-
}
|
|
720
|
-
/**
|
|
721
|
-
* Induced-subgraph filter: keep vertices where `predicate(key, value)` is true,
|
|
722
|
-
* and only keep edges whose endpoints both survive.
|
|
723
|
-
* @param predicate - `(key, value, index, self) => boolean`.
|
|
724
|
-
* @param thisArg - Optional `this` for callback.
|
|
725
|
-
* @returns A new graph of the same concrete class (`this` type).
|
|
726
|
-
* @remarks Time O(V + E), Space O(V + E)
|
|
727
|
-
*/
|
|
728
|
-
filter(predicate, thisArg) {
|
|
729
|
-
const filtered = [];
|
|
730
|
-
let index = 0;
|
|
731
|
-
for (const [key, value] of this) {
|
|
732
|
-
if (predicate.call(thisArg, key, value, index, this)) {
|
|
733
|
-
filtered.push([key, value]);
|
|
734
|
-
}
|
|
735
|
-
index++;
|
|
736
|
-
}
|
|
737
|
-
return this._createLike(filtered, this._snapshotOptions());
|
|
738
|
-
}
|
|
739
|
-
/**
|
|
740
|
-
* Preserve the old behavior: return filtered entries as an array.
|
|
741
|
-
* @remarks Time O(V), Space O(V)
|
|
742
|
-
*/
|
|
743
|
-
filterEntries(predicate, thisArg) {
|
|
744
|
-
const filtered = [];
|
|
745
|
-
let index = 0;
|
|
746
|
-
for (const [key, value] of this) {
|
|
747
|
-
if (predicate.call(thisArg, key, value, index, this)) {
|
|
748
|
-
filtered.push([key, value]);
|
|
749
|
-
}
|
|
750
|
-
index++;
|
|
751
|
-
}
|
|
752
|
-
return filtered;
|
|
753
|
-
}
|
|
754
|
-
map(callback, thisArg) {
|
|
755
|
-
const mapped = [];
|
|
756
|
-
let index = 0;
|
|
757
|
-
for (const [key, value] of this) {
|
|
758
|
-
mapped.push(callback.call(thisArg, key, value, index, this));
|
|
759
|
-
index++;
|
|
760
|
-
}
|
|
761
|
-
return mapped;
|
|
762
|
-
}
|
|
763
|
-
/**
|
|
764
|
-
* Create a deep clone of the graph with the same species.
|
|
765
|
-
* @remarks Time O(V + E), Space O(V + E)
|
|
766
|
-
*/
|
|
767
|
-
/**
|
|
768
|
-
* Create a deep clone of the graph with the same species.
|
|
769
|
-
* @returns A new graph of the same concrete class (`this` type).
|
|
770
|
-
* @remarks Time O(V + E), Space O(V + E)
|
|
771
|
-
*/
|
|
772
|
-
clone() {
|
|
773
|
-
return this._createLike(undefined, this._snapshotOptions());
|
|
774
|
-
}
|
|
775
|
-
// ===== Same-species factory & cloning helpers =====
|
|
776
|
-
/**
|
|
777
|
-
* Internal iterator over `[key, value]` entries in insertion order.
|
|
778
|
-
* @returns Iterator of `[VertexKey, V | undefined]`.
|
|
779
|
-
* @remarks Time O(V), Space O(1)
|
|
780
|
-
*/
|
|
781
|
-
*_getIterator() {
|
|
782
|
-
for (const vertex of this._vertexMap.values()) {
|
|
783
|
-
yield [vertex.key, vertex.value];
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
/**
|
|
787
|
-
* Capture configuration needed to reproduce the current graph.
|
|
788
|
-
* Currently the graph has no runtime options, so we return an empty object.
|
|
789
|
-
*/
|
|
790
|
-
/**
|
|
791
|
-
* Capture configuration needed to reproduce the current graph.
|
|
792
|
-
* @returns Options bag (opaque to callers).
|
|
793
|
-
* @remarks Time O(1), Space O(1)
|
|
794
|
-
*/
|
|
795
|
-
_snapshotOptions() {
|
|
796
|
-
return { graph: Object.assign({}, this._options) };
|
|
797
|
-
}
|
|
798
|
-
/**
|
|
799
|
-
* Create an empty graph instance of the same concrete species (Directed/Undirected/etc).
|
|
800
|
-
* @remarks Time O(1), Space O(1)
|
|
801
|
-
*/
|
|
802
|
-
/**
|
|
803
|
-
* Create an empty graph instance of the same concrete species.
|
|
804
|
-
* @param _options - Snapshot options from `_snapshotOptions()`.
|
|
805
|
-
* @returns A new empty graph instance of `this` type.
|
|
806
|
-
* @remarks Time O(1), Space O(1)
|
|
807
|
-
*/
|
|
808
|
-
_createInstance(_options) {
|
|
809
|
-
const Ctor = this.constructor;
|
|
810
|
-
const instance = new Ctor();
|
|
811
|
-
const graph = _options === null || _options === void 0 ? void 0 : _options.graph;
|
|
812
|
-
if (graph)
|
|
813
|
-
instance._options = Object.assign(Object.assign({}, instance._options), graph);
|
|
814
|
-
else
|
|
815
|
-
instance._options = Object.assign(Object.assign({}, instance._options), this._options);
|
|
816
|
-
return instance;
|
|
817
|
-
}
|
|
818
|
-
/**
|
|
819
|
-
* Create a same-species graph populated with the given entries.
|
|
820
|
-
* Also preserves edges between kept vertices from the source graph.
|
|
821
|
-
* @remarks Time O(V + E), Space O(V + E)
|
|
822
|
-
*/
|
|
823
|
-
/**
|
|
824
|
-
* Create a same-species graph populated with entries; preserves edges among kept vertices.
|
|
825
|
-
* @param iter - Optional entries to seed the new graph.
|
|
826
|
-
* @param options - Snapshot options.
|
|
827
|
-
* @returns A new graph of `this` type.
|
|
828
|
-
* @remarks Time O(V + E), Space O(V + E)
|
|
829
|
-
*/
|
|
830
|
-
_createLike(iter, options) {
|
|
831
|
-
const g = this._createInstance(options);
|
|
832
|
-
// 1) Add vertices
|
|
833
|
-
if (iter) {
|
|
834
|
-
for (const [k, v] of iter) {
|
|
835
|
-
g.addVertex(k, v);
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
else {
|
|
839
|
-
for (const [k, v] of this) {
|
|
840
|
-
g.addVertex(k, v);
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
|
-
// 2) Add edges whose endpoints exist in the new graph
|
|
844
|
-
const edges = this.edgeSet();
|
|
845
|
-
for (const e of edges) {
|
|
846
|
-
const ends = this.getEndsOfEdge(e);
|
|
847
|
-
if (!ends)
|
|
848
|
-
continue;
|
|
849
|
-
const [va, vb] = ends;
|
|
850
|
-
const ka = va.key;
|
|
851
|
-
const kb = vb.key;
|
|
852
|
-
const hasA = g.hasVertex ? g.hasVertex(ka) : false;
|
|
853
|
-
const hasB = g.hasVertex ? g.hasVertex(kb) : false;
|
|
854
|
-
if (hasA && hasB) {
|
|
855
|
-
const w = e.weight;
|
|
856
|
-
const val = e.value;
|
|
857
|
-
const newEdge = g.createEdge(ka, kb, w, val);
|
|
858
|
-
g._addEdge(newEdge);
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
return g;
|
|
862
|
-
}
|
|
863
|
-
/**
|
|
864
|
-
* Insert a pre-built vertex into the graph.
|
|
865
|
-
* @param newVertex - Concrete vertex instance.
|
|
866
|
-
* @returns `true` if inserted; `false` if key already exists.
|
|
867
|
-
* @remarks Time O(1) avg, Space O(1)
|
|
868
|
-
*/
|
|
869
|
-
_addVertex(newVertex) {
|
|
870
|
-
if (this.hasVertex(newVertex)) {
|
|
871
|
-
return false;
|
|
872
|
-
}
|
|
873
|
-
this._vertexMap.set(newVertex.key, newVertex);
|
|
874
|
-
return true;
|
|
875
|
-
}
|
|
876
|
-
/**
|
|
877
|
-
* Resolve a vertex key or instance to the concrete vertex instance.
|
|
878
|
-
* @param vertexOrKey - Vertex key or existing vertex.
|
|
879
|
-
* @returns Vertex instance or `undefined`.
|
|
880
|
-
* @remarks Time O(1), Space O(1)
|
|
881
|
-
*/
|
|
882
|
-
_getVertex(vertexOrKey) {
|
|
883
|
-
const vertexKey = this._getVertexKey(vertexOrKey);
|
|
884
|
-
return this._vertexMap.get(vertexKey) || undefined;
|
|
885
|
-
}
|
|
886
|
-
/**
|
|
887
|
-
* Resolve a vertex key from a key or vertex instance.
|
|
888
|
-
* @param vertexOrKey - Vertex key or existing vertex.
|
|
889
|
-
* @returns The vertex key.
|
|
890
|
-
* @remarks Time O(1), Space O(1)
|
|
891
|
-
*/
|
|
892
|
-
_getVertexKey(vertexOrKey) {
|
|
893
|
-
return vertexOrKey instanceof AbstractVertex ? vertexOrKey.key : vertexOrKey;
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
exports.AbstractGraph = AbstractGraph;
|