min-heap-typed 1.50.2 → 1.50.3
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/data-structures/base/iterable-base.d.ts +6 -0
- package/dist/data-structures/binary-tree/avl-tree.d.ts +29 -1
- package/dist/data-structures/binary-tree/avl-tree.js +33 -1
- package/dist/data-structures/binary-tree/binary-indexed-tree.d.ts +22 -0
- package/dist/data-structures/binary-tree/binary-indexed-tree.js +22 -0
- package/dist/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/data-structures/binary-tree/binary-tree.js +1 -1
- package/dist/data-structures/binary-tree/bst.d.ts +46 -13
- package/dist/data-structures/binary-tree/bst.js +46 -13
- package/dist/data-structures/binary-tree/rb-tree.d.ts +54 -2
- package/dist/data-structures/binary-tree/rb-tree.js +73 -15
- package/dist/data-structures/binary-tree/segment-tree.d.ts +99 -6
- package/dist/data-structures/binary-tree/segment-tree.js +127 -10
- package/dist/data-structures/binary-tree/tree-multimap.d.ts +35 -2
- package/dist/data-structures/binary-tree/tree-multimap.js +38 -0
- package/dist/data-structures/graph/abstract-graph.d.ts +0 -78
- package/dist/data-structures/graph/abstract-graph.js +0 -189
- package/dist/data-structures/graph/directed-graph.d.ts +59 -0
- package/dist/data-structures/graph/directed-graph.js +105 -0
- package/dist/data-structures/graph/undirected-graph.d.ts +60 -7
- package/dist/data-structures/graph/undirected-graph.js +126 -18
- package/dist/data-structures/hash/hash-map.d.ts +143 -23
- package/dist/data-structures/hash/hash-map.js +196 -62
- package/dist/data-structures/heap/heap.d.ts +29 -19
- package/dist/data-structures/heap/heap.js +29 -20
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +71 -25
- package/dist/data-structures/linked-list/doubly-linked-list.js +83 -25
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +26 -3
- package/dist/data-structures/linked-list/singly-linked-list.js +34 -3
- package/dist/data-structures/linked-list/skip-linked-list.d.ts +2 -2
- package/dist/data-structures/linked-list/skip-linked-list.js +2 -2
- package/dist/data-structures/matrix/matrix.d.ts +1 -1
- package/dist/data-structures/matrix/matrix.js +1 -1
- package/dist/data-structures/priority-queue/max-priority-queue.d.ts +10 -0
- package/dist/data-structures/priority-queue/max-priority-queue.js +10 -0
- package/dist/data-structures/priority-queue/min-priority-queue.d.ts +11 -0
- package/dist/data-structures/priority-queue/min-priority-queue.js +11 -0
- package/dist/data-structures/priority-queue/priority-queue.d.ts +8 -0
- package/dist/data-structures/priority-queue/priority-queue.js +8 -0
- package/dist/data-structures/queue/deque.d.ts +95 -21
- package/dist/data-structures/queue/deque.js +100 -16
- package/dist/data-structures/queue/queue.d.ts +65 -45
- package/dist/data-structures/queue/queue.js +65 -45
- package/dist/data-structures/stack/stack.d.ts +36 -22
- package/dist/data-structures/stack/stack.js +36 -22
- package/dist/data-structures/tree/tree.d.ts +57 -3
- package/dist/data-structures/tree/tree.js +77 -11
- package/dist/data-structures/trie/trie.d.ts +100 -36
- package/dist/data-structures/trie/trie.js +115 -36
- package/package.json +2 -2
- package/src/data-structures/base/iterable-base.ts +12 -0
- package/src/data-structures/binary-tree/avl-tree.ts +37 -3
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +22 -0
- package/src/data-structures/binary-tree/binary-tree.ts +1 -1
- package/src/data-structures/binary-tree/bst.ts +46 -13
- package/src/data-structures/binary-tree/rb-tree.ts +79 -18
- package/src/data-structures/binary-tree/segment-tree.ts +145 -11
- package/src/data-structures/binary-tree/tree-multimap.ts +42 -3
- package/src/data-structures/graph/abstract-graph.ts +0 -211
- package/src/data-structures/graph/directed-graph.ts +122 -0
- package/src/data-structures/graph/undirected-graph.ts +143 -19
- package/src/data-structures/hash/hash-map.ts +228 -76
- package/src/data-structures/heap/heap.ts +31 -20
- package/src/data-structures/linked-list/doubly-linked-list.ts +96 -29
- package/src/data-structures/linked-list/singly-linked-list.ts +42 -6
- package/src/data-structures/linked-list/skip-linked-list.ts +2 -2
- package/src/data-structures/matrix/matrix.ts +1 -1
- package/src/data-structures/priority-queue/max-priority-queue.ts +10 -0
- package/src/data-structures/priority-queue/min-priority-queue.ts +11 -0
- package/src/data-structures/priority-queue/priority-queue.ts +8 -0
- package/src/data-structures/queue/deque.ts +118 -22
- package/src/data-structures/queue/queue.ts +68 -45
- package/src/data-structures/stack/stack.ts +39 -23
- package/src/data-structures/tree/tree.ts +89 -15
- package/src/data-structures/trie/trie.ts +131 -40
|
@@ -616,6 +616,23 @@ export class DirectedGraph<
|
|
|
616
616
|
return this.vertexMap.size === 0 && this.inEdgeMap.size === 0 && this.outEdgeMap.size === 0;
|
|
617
617
|
}
|
|
618
618
|
|
|
619
|
+
/**
|
|
620
|
+
* Time Complexity: O(1)
|
|
621
|
+
* Space Complexity: O(1)
|
|
622
|
+
*/
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Time Complexity: O(1)
|
|
626
|
+
* Space Complexity: O(1)
|
|
627
|
+
*
|
|
628
|
+
* The clear function resets the vertex map, in-edge map, and out-edge map.
|
|
629
|
+
*/
|
|
630
|
+
clear() {
|
|
631
|
+
this._vertexMap = new Map<VertexKey, VO>();
|
|
632
|
+
this._inEdgeMap = new Map<VO, EO[]>();
|
|
633
|
+
this._outEdgeMap = new Map<VO, EO[]>();
|
|
634
|
+
}
|
|
635
|
+
|
|
619
636
|
/**
|
|
620
637
|
* The clone function creates a new DirectedGraph object with the same vertices and edges as the original.
|
|
621
638
|
*
|
|
@@ -629,6 +646,111 @@ export class DirectedGraph<
|
|
|
629
646
|
return cloned;
|
|
630
647
|
}
|
|
631
648
|
|
|
649
|
+
/**
|
|
650
|
+
* Time Complexity: O(V + E)
|
|
651
|
+
* Space Complexity: O(V)
|
|
652
|
+
* Tarjan is an algorithm based on dfs,which is used to solve the connectivity problem of graphs.
|
|
653
|
+
* Tarjan can find the SSC(strongly connected components), articulation points, and bridges of directed graphs.
|
|
654
|
+
*/
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Time Complexity: O(V + E)
|
|
658
|
+
* Space Complexity: O(V)
|
|
659
|
+
* Tarjan is an algorithm based on dfs,which is used to solve the connectivity problem of graphs.
|
|
660
|
+
* Tarjan can find the SSC(strongly connected components), articulation points, and bridges of directed graphs.
|
|
661
|
+
*
|
|
662
|
+
* The function `tarjan` implements the Tarjan's algorithm to find strongly connected components in a
|
|
663
|
+
* graph.
|
|
664
|
+
* @returns The function `tarjan()` returns an object with three properties: `dfnMap`, `lowMap`, and
|
|
665
|
+
* `SCCs`.
|
|
666
|
+
*/
|
|
667
|
+
tarjan(): { dfnMap: Map<VO, number>; lowMap: Map<VO, number>; SCCs: Map<number, VO[]> } {
|
|
668
|
+
const dfnMap = new Map<VO, number>();
|
|
669
|
+
const lowMap = new Map<VO, number>();
|
|
670
|
+
const SCCs = new Map<number, VO[]>();
|
|
671
|
+
|
|
672
|
+
let time = 0;
|
|
673
|
+
|
|
674
|
+
const stack: VO[] = [];
|
|
675
|
+
const inStack: Set<VO> = new Set();
|
|
676
|
+
|
|
677
|
+
const dfs = (vertex: VO) => {
|
|
678
|
+
dfnMap.set(vertex, time);
|
|
679
|
+
lowMap.set(vertex, time);
|
|
680
|
+
time++;
|
|
681
|
+
|
|
682
|
+
stack.push(vertex);
|
|
683
|
+
inStack.add(vertex);
|
|
684
|
+
|
|
685
|
+
const neighbors = this.getNeighbors(vertex);
|
|
686
|
+
for (const neighbor of neighbors) {
|
|
687
|
+
if (!dfnMap.has(neighbor)) {
|
|
688
|
+
dfs(neighbor);
|
|
689
|
+
lowMap.set(vertex, Math.min(lowMap.get(vertex)!, lowMap.get(neighbor)!));
|
|
690
|
+
} else if (inStack.has(neighbor)) {
|
|
691
|
+
lowMap.set(vertex, Math.min(lowMap.get(vertex)!, dfnMap.get(neighbor)!));
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
if (dfnMap.get(vertex) === lowMap.get(vertex)) {
|
|
696
|
+
const SCC: VO[] = [];
|
|
697
|
+
let poppedVertex: VO | undefined;
|
|
698
|
+
|
|
699
|
+
do {
|
|
700
|
+
poppedVertex = stack.pop();
|
|
701
|
+
inStack.delete(poppedVertex!);
|
|
702
|
+
SCC.push(poppedVertex!);
|
|
703
|
+
} while (poppedVertex !== vertex);
|
|
704
|
+
|
|
705
|
+
SCCs.set(SCCs.size, SCC);
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
|
|
709
|
+
for (const vertex of this.vertexMap.values()) {
|
|
710
|
+
if (!dfnMap.has(vertex)) {
|
|
711
|
+
dfs(vertex);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
return { dfnMap, lowMap, SCCs };
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* Time Complexity: O(V + E) - Depends on the implementation (Tarjan's algorithm).
|
|
720
|
+
* Space Complexity: O(V) - Depends on the implementation (Tarjan's algorithm).
|
|
721
|
+
*/
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* Time Complexity: O(V + E) - Depends on the implementation (Tarjan's algorithm).
|
|
725
|
+
* Space Complexity: O(V) - Depends on the implementation (Tarjan's algorithm).
|
|
726
|
+
*
|
|
727
|
+
* The function returns a map that associates each vertex object with its corresponding depth-first
|
|
728
|
+
* number.
|
|
729
|
+
* @returns A Map object with keys of type VO and values of type number.
|
|
730
|
+
*/
|
|
731
|
+
getDFNMap(): Map<VO, number> {
|
|
732
|
+
return this.tarjan().dfnMap;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* The function returns a Map object that contains the low values of each vertex in a Tarjan
|
|
737
|
+
* algorithm.
|
|
738
|
+
* @returns The method `getLowMap()` is returning a `Map` object with keys of type `VO` and values of
|
|
739
|
+
* type `number`.
|
|
740
|
+
*/
|
|
741
|
+
getLowMap(): Map<VO, number> {
|
|
742
|
+
return this.tarjan().lowMap;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/**
|
|
746
|
+
* The function "getSCCs" returns a map of strongly connected components (SCCs) using the Tarjan
|
|
747
|
+
* algorithm.
|
|
748
|
+
* @returns a map where the keys are numbers and the values are arrays of VO objects.
|
|
749
|
+
*/
|
|
750
|
+
getSCCs(): Map<number, VO[]> {
|
|
751
|
+
return this.tarjan().SCCs;
|
|
752
|
+
}
|
|
753
|
+
|
|
632
754
|
/**
|
|
633
755
|
* Time Complexity: O(1)
|
|
634
756
|
* Space Complexity: O(1)
|
|
@@ -24,7 +24,7 @@ export class UndirectedVertex<V = any> extends AbstractVertex<V> {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export class UndirectedEdge<E = number> extends AbstractEdge<E> {
|
|
27
|
-
|
|
27
|
+
endpoints: [VertexKey, VertexKey];
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* The constructor function creates an instance of a class with two vertex IDs, an optional weight, and an optional
|
|
@@ -38,7 +38,7 @@ export class UndirectedEdge<E = number> extends AbstractEdge<E> {
|
|
|
38
38
|
*/
|
|
39
39
|
constructor(v1: VertexKey, v2: VertexKey, weight?: number, value?: E) {
|
|
40
40
|
super(weight, value);
|
|
41
|
-
this.
|
|
41
|
+
this.endpoints = [v1, v2];
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -104,7 +104,7 @@ export class UndirectedGraph<
|
|
|
104
104
|
* Time Complexity: O(|E|), where |E| is the number of edgeMap incident to the given vertex.
|
|
105
105
|
* Space Complexity: O(1)
|
|
106
106
|
*
|
|
107
|
-
* The function `getEdge` returns the first edge that connects two
|
|
107
|
+
* The function `getEdge` returns the first edge that connects two endpoints, or undefined if no such edge exists.
|
|
108
108
|
* @param {VO | VertexKey | undefined} v1 - The parameter `v1` represents a vertex or vertex ID. It can be of type `VO` (vertex
|
|
109
109
|
* object), `undefined`, or `VertexKey` (a string or number representing the ID of a vertex).
|
|
110
110
|
* @param {VO | VertexKey | undefined} v2 - The parameter `v2` represents a vertex or vertex ID. It can be of type `VO` (vertex
|
|
@@ -119,7 +119,7 @@ export class UndirectedGraph<
|
|
|
119
119
|
const vertex2: VO | undefined = this._getVertex(v2);
|
|
120
120
|
|
|
121
121
|
if (vertex1 && vertex2) {
|
|
122
|
-
edgeMap = this._edgeMap.get(vertex1)?.filter(e => e.
|
|
122
|
+
edgeMap = this._edgeMap.get(vertex1)?.filter(e => e.endpoints.includes(vertex2.key));
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
|
|
@@ -139,7 +139,7 @@ export class UndirectedGraph<
|
|
|
139
139
|
* @param {VO | VertexKey} v1 - The parameter `v1` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).
|
|
140
140
|
* @param {VO | VertexKey} v2 - VO | VertexKey - This parameter can be either a vertex object (VO) or a vertex ID
|
|
141
141
|
* (VertexKey). It represents the second vertex of the edge that needs to be removed.
|
|
142
|
-
* @returns the removed edge (EO) if it exists, or undefined if either of the
|
|
142
|
+
* @returns the removed edge (EO) if it exists, or undefined if either of the endpoints (VO) does not exist.
|
|
143
143
|
*/
|
|
144
144
|
deleteEdgeBetween(v1: VO | VertexKey, v2: VO | VertexKey): EO | undefined {
|
|
145
145
|
const vertex1: VO | undefined = this._getVertex(v1);
|
|
@@ -152,11 +152,11 @@ export class UndirectedGraph<
|
|
|
152
152
|
const v1Edges = this._edgeMap.get(vertex1);
|
|
153
153
|
let removed: EO | undefined = undefined;
|
|
154
154
|
if (v1Edges) {
|
|
155
|
-
removed = arrayRemove<EO>(v1Edges, (e: EO) => e.
|
|
155
|
+
removed = arrayRemove<EO>(v1Edges, (e: EO) => e.endpoints.includes(vertex2.key))[0] || undefined;
|
|
156
156
|
}
|
|
157
157
|
const v2Edges = this._edgeMap.get(vertex2);
|
|
158
158
|
if (v2Edges) {
|
|
159
|
-
arrayRemove<EO>(v2Edges, (e: EO) => e.
|
|
159
|
+
arrayRemove<EO>(v2Edges, (e: EO) => e.endpoints.includes(vertex1.key));
|
|
160
160
|
}
|
|
161
161
|
return removed;
|
|
162
162
|
}
|
|
@@ -170,7 +170,7 @@ export class UndirectedGraph<
|
|
|
170
170
|
* Time Complexity: O(E), where E is the number of edgeMap incident to the given vertex.
|
|
171
171
|
* Space Complexity: O(1)
|
|
172
172
|
*
|
|
173
|
-
* The function `deleteEdge` deletes an edge between two
|
|
173
|
+
* The function `deleteEdge` deletes an edge between two endpoints in a graph.
|
|
174
174
|
* @param {EO | VertexKey} edgeOrOneSideVertexKey - The parameter `edgeOrOneSideVertexKey` can be
|
|
175
175
|
* either an edge object or a vertex key.
|
|
176
176
|
* @param {VertexKey} [otherSideVertexKey] - The parameter `otherSideVertexKey` is an optional
|
|
@@ -189,8 +189,8 @@ export class UndirectedGraph<
|
|
|
189
189
|
return;
|
|
190
190
|
}
|
|
191
191
|
} else {
|
|
192
|
-
oneSide = this._getVertex(edgeOrOneSideVertexKey.
|
|
193
|
-
otherSide = this._getVertex(edgeOrOneSideVertexKey.
|
|
192
|
+
oneSide = this._getVertex(edgeOrOneSideVertexKey.endpoints[0]);
|
|
193
|
+
otherSide = this._getVertex(edgeOrOneSideVertexKey.endpoints[1]);
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
if (oneSide && otherSide) {
|
|
@@ -232,7 +232,7 @@ export class UndirectedGraph<
|
|
|
232
232
|
const neighborEdges = this._edgeMap.get(neighbor);
|
|
233
233
|
if (neighborEdges) {
|
|
234
234
|
const restEdges = neighborEdges.filter(edge => {
|
|
235
|
-
return !edge.
|
|
235
|
+
return !edge.endpoints.includes(vertexKey);
|
|
236
236
|
});
|
|
237
237
|
this._edgeMap.set(neighbor, restEdges);
|
|
238
238
|
}
|
|
@@ -321,7 +321,7 @@ export class UndirectedGraph<
|
|
|
321
321
|
* Time Complexity: O(|V| + |E|), where |V| is the number of vertexMap and |E| is the number of edgeMap.
|
|
322
322
|
* Space Complexity: O(|E|)
|
|
323
323
|
*
|
|
324
|
-
* The function "getNeighbors" returns an array of neighboring
|
|
324
|
+
* The function "getNeighbors" returns an array of neighboring endpoints for a given vertex or vertex ID.
|
|
325
325
|
* @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID
|
|
326
326
|
* (`VertexKey`).
|
|
327
327
|
* @returns an array of vertexMap (VO[]).
|
|
@@ -332,7 +332,7 @@ export class UndirectedGraph<
|
|
|
332
332
|
if (vertex) {
|
|
333
333
|
const neighborEdges = this.edgesOf(vertex);
|
|
334
334
|
for (const edge of neighborEdges) {
|
|
335
|
-
const neighbor = this._getVertex(edge.
|
|
335
|
+
const neighbor = this._getVertex(edge.endpoints.filter(e => e !== vertex.key)[0]);
|
|
336
336
|
if (neighbor) {
|
|
337
337
|
neighbors.push(neighbor);
|
|
338
338
|
}
|
|
@@ -350,18 +350,18 @@ export class UndirectedGraph<
|
|
|
350
350
|
* Time Complexity: O(1)
|
|
351
351
|
* Space Complexity: O(1)
|
|
352
352
|
*
|
|
353
|
-
* The function "getEndsOfEdge" returns the
|
|
353
|
+
* The function "getEndsOfEdge" returns the endpoints at the ends of an edge if the edge exists in the graph, otherwise
|
|
354
354
|
* it returns undefined.
|
|
355
355
|
* @param {EO} edge - The parameter "edge" is of type EO, which represents an edge in a graph.
|
|
356
|
-
* @returns The function `getEndsOfEdge` returns an array containing two
|
|
356
|
+
* @returns The function `getEndsOfEdge` returns an array containing two endpoints `[VO, VO]` if the edge exists in the
|
|
357
357
|
* graph. If the edge does not exist, it returns `undefined`.
|
|
358
358
|
*/
|
|
359
359
|
getEndsOfEdge(edge: EO): [VO, VO] | undefined {
|
|
360
|
-
if (!this.hasEdge(edge.
|
|
360
|
+
if (!this.hasEdge(edge.endpoints[0], edge.endpoints[1])) {
|
|
361
361
|
return undefined;
|
|
362
362
|
}
|
|
363
|
-
const v1 = this._getVertex(edge.
|
|
364
|
-
const v2 = this._getVertex(edge.
|
|
363
|
+
const v1 = this._getVertex(edge.endpoints[0]);
|
|
364
|
+
const v2 = this._getVertex(edge.endpoints[1]);
|
|
365
365
|
if (v1 && v2) {
|
|
366
366
|
return [v1, v2];
|
|
367
367
|
} else {
|
|
@@ -377,6 +377,22 @@ export class UndirectedGraph<
|
|
|
377
377
|
return this.vertexMap.size === 0 && this.edgeMap.size === 0;
|
|
378
378
|
}
|
|
379
379
|
|
|
380
|
+
/**
|
|
381
|
+
* Time Complexity: O(1)
|
|
382
|
+
* Space Complexity: O(1)
|
|
383
|
+
*/
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Time Complexity: O(1)
|
|
387
|
+
* Space Complexity: O(1)
|
|
388
|
+
*
|
|
389
|
+
* The clear function resets the vertex and edge maps to empty maps.
|
|
390
|
+
*/
|
|
391
|
+
clear() {
|
|
392
|
+
this._vertexMap = new Map<VertexKey, VO>();
|
|
393
|
+
this._edgeMap = new Map<VO, EO[]>();
|
|
394
|
+
}
|
|
395
|
+
|
|
380
396
|
/**
|
|
381
397
|
* The clone function creates a new UndirectedGraph object and copies the
|
|
382
398
|
* vertexMap and edgeMap from this graph to the new one. This is done by
|
|
@@ -398,6 +414,114 @@ export class UndirectedGraph<
|
|
|
398
414
|
* Space Complexity: O(1)
|
|
399
415
|
*/
|
|
400
416
|
|
|
417
|
+
/**
|
|
418
|
+
* Time Complexity: O(V + E)
|
|
419
|
+
* Space Complexity: O(V)
|
|
420
|
+
* Tarjan is an algorithm based on dfs,which is used to solve the connectivity problem of graphs.
|
|
421
|
+
* 1. Tarjan can find the articulation points and bridges(critical edgeMap) of undirected graphs in linear time
|
|
422
|
+
*
|
|
423
|
+
* The function `tarjan` implements the Tarjan's algorithm to find bridges and cut vertices in a
|
|
424
|
+
* graph.
|
|
425
|
+
* @returns The function `tarjan()` returns an object with the following properties:
|
|
426
|
+
*/
|
|
427
|
+
tarjan(): { dfnMap: Map<VO, number>; lowMap: Map<VO, number>; bridges: EO[]; cutVertices: VO[] } {
|
|
428
|
+
const dfnMap = new Map<VO, number>();
|
|
429
|
+
const lowMap = new Map<VO, number>();
|
|
430
|
+
const bridges: EO[] = [];
|
|
431
|
+
const cutVertices: VO[] = [];
|
|
432
|
+
|
|
433
|
+
let time = 0;
|
|
434
|
+
|
|
435
|
+
const dfs = (vertex: VO, parent: VO | undefined) => {
|
|
436
|
+
dfnMap.set(vertex, time);
|
|
437
|
+
lowMap.set(vertex, time);
|
|
438
|
+
time++;
|
|
439
|
+
|
|
440
|
+
const neighbors = this.getNeighbors(vertex);
|
|
441
|
+
let childCount = 0;
|
|
442
|
+
|
|
443
|
+
for (const neighbor of neighbors) {
|
|
444
|
+
if (!dfnMap.has(neighbor)) {
|
|
445
|
+
childCount++;
|
|
446
|
+
dfs(neighbor, vertex);
|
|
447
|
+
lowMap.set(vertex, Math.min(lowMap.get(vertex)!, lowMap.get(neighbor)!));
|
|
448
|
+
|
|
449
|
+
if (lowMap.get(neighbor)! > dfnMap.get(vertex)!) {
|
|
450
|
+
// Found a bridge
|
|
451
|
+
const edge = this.getEdge(vertex, neighbor);
|
|
452
|
+
if (edge) {
|
|
453
|
+
bridges.push(edge);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if (parent !== undefined && lowMap.get(neighbor)! >= dfnMap.get(vertex)!) {
|
|
458
|
+
// Found an articulation point
|
|
459
|
+
cutVertices.push(vertex);
|
|
460
|
+
}
|
|
461
|
+
} else if (neighbor !== parent) {
|
|
462
|
+
lowMap.set(vertex, Math.min(lowMap.get(vertex)!, dfnMap.get(neighbor)!));
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
if (parent === undefined && childCount > 1) {
|
|
467
|
+
// Special case for root in DFS tree
|
|
468
|
+
cutVertices.push(vertex);
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
for (const vertex of this.vertexMap.values()) {
|
|
473
|
+
if (!dfnMap.has(vertex)) {
|
|
474
|
+
dfs(vertex, undefined);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
return {
|
|
479
|
+
dfnMap,
|
|
480
|
+
lowMap,
|
|
481
|
+
bridges,
|
|
482
|
+
cutVertices
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Time Complexity: O(V + E)
|
|
488
|
+
* Space Complexity: O(V)
|
|
489
|
+
* Tarjan is an algorithm based on dfs,which is used to solve the connectivity problem of graphs.
|
|
490
|
+
* 1. Tarjan can find the articulation points and bridges(critical edgeMap) of undirected graphs in linear time
|
|
491
|
+
*/
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* The function "getBridges" returns an array of bridges in a graph using the Tarjan's algorithm.
|
|
495
|
+
* @returns The function `getBridges()` is returning the bridges found using the Tarjan's algorithm.
|
|
496
|
+
*/
|
|
497
|
+
getBridges() {
|
|
498
|
+
return this.tarjan().bridges;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* The function "getCutVertices" returns an array of cut vertices using the Tarjan's algorithm.
|
|
503
|
+
* @returns the cut vertices found using the Tarjan's algorithm.
|
|
504
|
+
*/
|
|
505
|
+
getCutVertices() {
|
|
506
|
+
return this.tarjan().cutVertices;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* The function returns the dfnMap property of the result of the tarjan() function.
|
|
511
|
+
* @returns the `dfnMap` property of the result of calling the `tarjan()` function.
|
|
512
|
+
*/
|
|
513
|
+
getDFNMap() {
|
|
514
|
+
return this.tarjan().dfnMap;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* The function returns the lowMap property of the result of the tarjan() function.
|
|
519
|
+
* @returns the lowMap property of the result of calling the tarjan() function.
|
|
520
|
+
*/
|
|
521
|
+
getLowMap() {
|
|
522
|
+
return this.tarjan().lowMap;
|
|
523
|
+
}
|
|
524
|
+
|
|
401
525
|
/**
|
|
402
526
|
* Time Complexity: O(1)
|
|
403
527
|
* Space Complexity: O(1)
|
|
@@ -407,7 +531,7 @@ export class UndirectedGraph<
|
|
|
407
531
|
* @returns a boolean value.
|
|
408
532
|
*/
|
|
409
533
|
protected _addEdge(edge: EO): boolean {
|
|
410
|
-
for (const end of edge.
|
|
534
|
+
for (const end of edge.endpoints) {
|
|
411
535
|
const endVertex = this._getVertex(end);
|
|
412
536
|
if (endVertex === undefined) return false;
|
|
413
537
|
if (endVertex) {
|