mirror of
https://github.com/TheAlgorithms/JavaScript.git
synced 2025-07-04 15:39:42 +08:00
algorithm: kosaraju (#1215)
* kosaraju test added * Fixes: #1214 * Fixes: #1214 * Update package-lock.json * Kosaraju.js exports function kosaraju rather than class
This commit is contained in:
100
Graphs/Kosaraju.js
Normal file
100
Graphs/Kosaraju.js
Normal file
@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Author: Adrito Mukherjee
|
||||
* Kosaraju's Algorithm implementation in Javascript
|
||||
* Kosaraju's Algorithm finds all the connected components in a Directed Acyclic Graph (DAG)
|
||||
* It uses Stack data structure to store the Topological Sorted Order of vertices and also Graph data structure
|
||||
*
|
||||
* Wikipedia: https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm
|
||||
*
|
||||
*/
|
||||
|
||||
class Kosaraju {
|
||||
constructor (graph) {
|
||||
this.connections = {}
|
||||
this.reverseConnections = {}
|
||||
this.stronglyConnectedComponents = []
|
||||
for (const [i, j] of graph) {
|
||||
this.addEdge(i, j)
|
||||
}
|
||||
this.topoSort()
|
||||
return this.kosaraju()
|
||||
}
|
||||
|
||||
addNode (node) {
|
||||
// Function to add a node to the graph (connection represented by set)
|
||||
this.connections[node] = new Set()
|
||||
this.reverseConnections[node] = new Set()
|
||||
this.topoSorted = []
|
||||
}
|
||||
|
||||
addEdge (node1, node2) {
|
||||
// Function to add an edge (adds the node too if they are not present in the graph)
|
||||
if (!(node1 in this.connections) || !(node1 in this.reverseConnections)) {
|
||||
this.addNode(node1)
|
||||
}
|
||||
if (!(node2 in this.connections) || !(node2 in this.reverseConnections)) {
|
||||
this.addNode(node2)
|
||||
}
|
||||
this.connections[node1].add(node2)
|
||||
this.reverseConnections[node2].add(node1)
|
||||
}
|
||||
|
||||
dfsTopoSort (node, visited) {
|
||||
visited.add(node)
|
||||
for (const child of this.connections[node]) {
|
||||
if (!visited.has(child)) this.dfsTopoSort(child, visited)
|
||||
}
|
||||
this.topoSorted.push(node)
|
||||
}
|
||||
|
||||
topoSort () {
|
||||
// Function to perform topological sorting
|
||||
const visited = new Set()
|
||||
const nodes = Object.keys(this.connections).map((key) => Number(key))
|
||||
for (const node of nodes) {
|
||||
if (!visited.has(node)) this.dfsTopoSort(node, visited)
|
||||
}
|
||||
}
|
||||
|
||||
dfsKosaraju (node, visited) {
|
||||
visited.add(node)
|
||||
this.stronglyConnectedComponents[
|
||||
this.stronglyConnectedComponents.length - 1
|
||||
].push(node)
|
||||
for (const child of this.reverseConnections[node]) {
|
||||
if (!visited.has(child)) this.dfsKosaraju(child, visited)
|
||||
}
|
||||
}
|
||||
|
||||
kosaraju () {
|
||||
// Function to perform Kosaraju Algorithm
|
||||
const visited = new Set()
|
||||
while (this.topoSorted.length > 0) {
|
||||
const node = this.topoSorted.pop()
|
||||
if (!visited.has(node)) {
|
||||
this.stronglyConnectedComponents.push([])
|
||||
this.dfsKosaraju(node, visited)
|
||||
}
|
||||
}
|
||||
return this.stronglyConnectedComponents
|
||||
}
|
||||
}
|
||||
|
||||
function kosaraju (graph) {
|
||||
const stronglyConnectedComponents = new Kosaraju(graph)
|
||||
return stronglyConnectedComponents
|
||||
}
|
||||
|
||||
export { kosaraju }
|
||||
|
||||
// kosaraju([
|
||||
// [1, 2],
|
||||
// [2, 3],
|
||||
// [3, 1],
|
||||
// [2, 4],
|
||||
// [4, 5],
|
||||
// [5, 6],
|
||||
// [6, 4],
|
||||
// ])
|
||||
|
||||
// [ [ 1, 3, 2 ], [ 4, 6, 5 ] ]
|
30
Graphs/test/Kosaraju.test.js
Normal file
30
Graphs/test/Kosaraju.test.js
Normal file
@ -0,0 +1,30 @@
|
||||
import { kosaraju } from '../Kosaraju.js'
|
||||
|
||||
test('Test Case 1', () => {
|
||||
const graph = [
|
||||
[1, 2],
|
||||
[2, 3],
|
||||
[3, 1],
|
||||
[2, 4],
|
||||
[4, 5],
|
||||
[5, 6],
|
||||
[6, 4]
|
||||
]
|
||||
const stronglyConnectedComponents = kosaraju(graph)
|
||||
expect(stronglyConnectedComponents).toStrictEqual([
|
||||
[1, 3, 2],
|
||||
[4, 6, 5]
|
||||
])
|
||||
})
|
||||
|
||||
test('Test Case 2', () => {
|
||||
const graph = [
|
||||
[1, 2],
|
||||
[2, 3],
|
||||
[3, 1],
|
||||
[2, 4],
|
||||
[4, 5]
|
||||
]
|
||||
const stronglyConnectedComponents = kosaraju(graph)
|
||||
expect(stronglyConnectedComponents).toStrictEqual([[1, 3, 2], [4], [5]])
|
||||
})
|
Reference in New Issue
Block a user