Skip to content

Commit ce9e294

Browse files
authored
algorithm: kosaraju (TheAlgorithms#1215)
* kosaraju test added * Fixes: TheAlgorithms#1214 * Fixes: TheAlgorithms#1214 * Update package-lock.json * Kosaraju.js exports function kosaraju rather than class
1 parent 6f9a8e4 commit ce9e294

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

Graphs/Kosaraju.js

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/**
2+
* Author: Adrito Mukherjee
3+
* Kosaraju's Algorithm implementation in Javascript
4+
* Kosaraju's Algorithm finds all the connected components in a Directed Acyclic Graph (DAG)
5+
* It uses Stack data structure to store the Topological Sorted Order of vertices and also Graph data structure
6+
*
7+
* Wikipedia: https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm
8+
*
9+
*/
10+
11+
class Kosaraju {
12+
constructor (graph) {
13+
this.connections = {}
14+
this.reverseConnections = {}
15+
this.stronglyConnectedComponents = []
16+
for (const [i, j] of graph) {
17+
this.addEdge(i, j)
18+
}
19+
this.topoSort()
20+
return this.kosaraju()
21+
}
22+
23+
addNode (node) {
24+
// Function to add a node to the graph (connection represented by set)
25+
this.connections[node] = new Set()
26+
this.reverseConnections[node] = new Set()
27+
this.topoSorted = []
28+
}
29+
30+
addEdge (node1, node2) {
31+
// Function to add an edge (adds the node too if they are not present in the graph)
32+
if (!(node1 in this.connections) || !(node1 in this.reverseConnections)) {
33+
this.addNode(node1)
34+
}
35+
if (!(node2 in this.connections) || !(node2 in this.reverseConnections)) {
36+
this.addNode(node2)
37+
}
38+
this.connections[node1].add(node2)
39+
this.reverseConnections[node2].add(node1)
40+
}
41+
42+
dfsTopoSort (node, visited) {
43+
visited.add(node)
44+
for (const child of this.connections[node]) {
45+
if (!visited.has(child)) this.dfsTopoSort(child, visited)
46+
}
47+
this.topoSorted.push(node)
48+
}
49+
50+
topoSort () {
51+
// Function to perform topological sorting
52+
const visited = new Set()
53+
const nodes = Object.keys(this.connections).map((key) => Number(key))
54+
for (const node of nodes) {
55+
if (!visited.has(node)) this.dfsTopoSort(node, visited)
56+
}
57+
}
58+
59+
dfsKosaraju (node, visited) {
60+
visited.add(node)
61+
this.stronglyConnectedComponents[
62+
this.stronglyConnectedComponents.length - 1
63+
].push(node)
64+
for (const child of this.reverseConnections[node]) {
65+
if (!visited.has(child)) this.dfsKosaraju(child, visited)
66+
}
67+
}
68+
69+
kosaraju () {
70+
// Function to perform Kosaraju Algorithm
71+
const visited = new Set()
72+
while (this.topoSorted.length > 0) {
73+
const node = this.topoSorted.pop()
74+
if (!visited.has(node)) {
75+
this.stronglyConnectedComponents.push([])
76+
this.dfsKosaraju(node, visited)
77+
}
78+
}
79+
return this.stronglyConnectedComponents
80+
}
81+
}
82+
83+
function kosaraju (graph) {
84+
const stronglyConnectedComponents = new Kosaraju(graph)
85+
return stronglyConnectedComponents
86+
}
87+
88+
export { kosaraju }
89+
90+
// kosaraju([
91+
// [1, 2],
92+
// [2, 3],
93+
// [3, 1],
94+
// [2, 4],
95+
// [4, 5],
96+
// [5, 6],
97+
// [6, 4],
98+
// ])
99+
100+
// [ [ 1, 3, 2 ], [ 4, 6, 5 ] ]

Graphs/test/Kosaraju.test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { kosaraju } from '../Kosaraju.js'
2+
3+
test('Test Case 1', () => {
4+
const graph = [
5+
[1, 2],
6+
[2, 3],
7+
[3, 1],
8+
[2, 4],
9+
[4, 5],
10+
[5, 6],
11+
[6, 4]
12+
]
13+
const stronglyConnectedComponents = kosaraju(graph)
14+
expect(stronglyConnectedComponents).toStrictEqual([
15+
[1, 3, 2],
16+
[4, 6, 5]
17+
])
18+
})
19+
20+
test('Test Case 2', () => {
21+
const graph = [
22+
[1, 2],
23+
[2, 3],
24+
[3, 1],
25+
[2, 4],
26+
[4, 5]
27+
]
28+
const stronglyConnectedComponents = kosaraju(graph)
29+
expect(stronglyConnectedComponents).toStrictEqual([[1, 3, 2], [4], [5]])
30+
})

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy