8000 Address review. Add notes on topological sort. · TheAlgorithms/TypeScript@05aac7b · GitHub
[go: up one dir, main page]

Skip to content

Commit 05aac7b

Browse files
committed
8000
Address review. Add notes on topological sort.
1 parent aaf8b59 commit 05aac7b

File tree

1 file changed

+22
-23
lines changed

1 file changed

+22
-23
lines changed

graph/tarjan.ts

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
11
/**
22
* @function tarjan
3-
* @description Given a graph, find the strongly connected components(SCC). A set of nodes form a SCC if there is a path between all pairs of points within that set.
3+
* @description Given a graph, find the strongly connected components(SCC) in reverse topological order. A set of nodes form a SCC if there is a path between all pairs of points within that set.
44
* @Complexity_Analysis
55
* Time complexity: O(V + E). We perform a DFS of (V + E)
66
* Space Complexity: O(V). We hold numerous structures all of which at worst holds O(V) nodes.
77
* @param {[number, number][][]} graph - The graph in adjacency list form
8-
* @return {number[][]} - An array of SCCs, where an SCC is an array with the indices of each node within that SCC.
8+
* @return {number[][]} - An array of SCCs, where an SCC is an array with the indices of each node within that SCC. The order of SCCs in the array are in reverse topological order.
99
* @see https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
1010
*/
1111
export const tarjan = (graph: number[][]): number[][] => {
12+
if (graph.length === 0) {
13+
return [];
14+
}
15+
16+
let index = 0;
17+
// The order in which we discover nodes
18+
let discovery: number[] = Array(graph.length);
19+
// For each node, holds the furthest ancestor it can reach
20+
let low: number[] = Array(graph.length).fill(undefined);
21+
// Holds the nodes we have visited in a DFS traversal and are considering to group into a SCC
22+
let stack: number[] = [];
23+
// Holds the elements in the stack.
24+
let stackContains = Array(graph.length).fill(false);
25+
let sccs: number[][] = [];
26+
1227
const dfs = (node: number) => {
1328
discovery[node] = index;
1429
low[node] = index;
@@ -17,7 +32,7 @@ export const tarjan = (graph: number[][]): number[][] => {
1732
stackContains[node] = true;
1833

1934
for (const child of graph[node]) {
20-
if (low[child] === -1) {
35+
if (low[child] === undefined) {
2136
dfs(child);
2237
if (low[child] < low[node]) {
2338
// Child node loops back to this node's ancestor. Update the low node.
@@ -32,37 +47,21 @@ export const tarjan = (graph: number[][]): number[][] => {
3247
if (discovery[node] == low[node]) {
3348
// node is the root of a SCC. Gather the SCC's nodes from the stack.
3449
let scc: number[] = [];
35-
let i = stack.length - 1;
36-
while (stack[i] != node) {
50+
let i;
51+
for (i = stack.length - 1; stack[i] != node; --i) {
3752
scc.push(stack[i]);
3853
stackContains[stack[i]] = false;
3954
stack.pop();
40-
--i;
4155
}
4256
scc.push(stack[i]);
43-
stack.pop();
4457
stackContains[stack[i]] = false;
58+
stack.pop();
4559
sccs.push(scc);
4660
}
4761
}
4862

49-
if (graph.length === 0) {
50-
return [];
51-
}
52-
53-
let index = 0;
54-
// The order in which we discover nodes
55-
let discovery: number[] = Array(graph.length).fill(-1);
56-
// For each node, holds the furthest ancestor it can reach
57-
let low: number[] = Array(graph.length).fill(-1);
58-
// Holds the nodes we have visited in a DFS traversal and are considering to group into a SCC
59-
let stack: number[] = [];
60-
// Holds the elements in the stack.
61-
let stackContains = Array(graph.length).fill(false);
62-
let sccs: number[][] = [];
63-
6463
for (let i = 0; i < graph.length; ++i) {
65-
if (low[i] === -1) {
64+
if (low[i] === undefined) {
6665
dfs(i);
6766
}
6867
}

0 commit comments

Comments
 (0)
0