Skip to main content

Graph Traversal

Depth First Traversal
Breadth First Traversal

package algorithmsinanutshell

import _utils.Document
import java.util.*
import kotlin.test.assertEquals


@Document("Depth First Traversal")
private fun depthFirstTraversal(graph: Graph) {

fun traverseNodeDepthFirst(vertex: Graph.Vertex) {
val stack = Stack<Graph.Vertex>()
val startNode = vertex

stack.push(startNode)
while (stack.isNotEmpty()) {
val currentVertex = stack.pop()
if (currentVertex.state != Graph.State.Undiscovered) {
continue
}
currentVertex.state = Graph.State.Processing
currentVertex.edges.forEach { edge ->
stack.push(edge.startVertex)
stack.push(edge.endVertex)
}
currentVertex.state = Graph.State.Discovered
println("Visited $currentVertex")
}
}


val startNode = graph.nodes.firstOrNull() ?: return
traverseNodeDepthFirst(startNode)
// Process dis-connected graph
graph.getUnvisited().forEach(::traverseNodeDepthFirst)
}

@Document("Breadth First Traversal")
private fun breadthFirstTraversal(graph: Graph) {
fun traverseBreadthFirst(vertex: Graph.Vertex) {
val queue = LinkedList<Graph.Vertex>()
val startNode = vertex

queue.addLast(startNode)
while (queue.isNotEmpty()) {
val currentVertex = queue.removeFirst()
if (currentVertex.state != Graph.State.Undiscovered) {
continue
}
currentVertex.state = Graph.State.Processing
currentVertex.edges.forEach { edge ->
queue.addLast(edge.startVertex)
queue.addLast(edge.endVertex)
}
currentVertex.state = Graph.State.Discovered
println("Visited $currentVertex")
}
}

val startNode = graph.nodes.firstOrNull() ?: return
traverseBreadthFirst(startNode)
// Process dis-connected graph
graph.getUnvisited().forEach(::traverseBreadthFirst)
}


fun main() {
run {
val graph = createGraph()
depthFirstTraversal(graph)
graph.getAllNodes().forEach {
assertEquals(it.state, Graph.State.Discovered)
}
}

run {
println("Breadth First Traversal")
val graph = createGraph()
breadthFirstTraversal(graph)
graph.getAllNodes().forEach {
assertEquals(it.state, Graph.State.Discovered)
}
}

}

private fun createGraph(): Graph {
val graph = Graph(Relation.UNWEIGHTED_DIRECTED)
val v1 = graph.add(1)
val v6 = graph.add(6)
val v2 = graph.add(2)
val v3 = graph.add(3)
val v4 = graph.add(4)
val v5 = graph.add(5)

val v7 = graph.add(7)
val v8 = graph.add(8)

v1.connectWith(v2)
v1.connectWith(v3)
v3.connectWith(v2)
v1.connectWith(v4)
v3.connectWith(v6)
v6.connectWith(v5)
v7.connectWith(v8)
return graph
}

Updated on 2021-06-12