Skip to content

Commit 07c441d

Browse files
Graph traversal
1 parent 9535da4 commit 07c441d

File tree

3 files changed

+170
-0
lines changed

3 files changed

+170
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package pl.dmichalski.algorithms.data_structures._11_graph_traversal
2+
3+
data class Node(private val vertex: String, private val connections: MutableList<String>) {
4+
5+
fun getVertex(): String {
6+
return vertex
7+
}
8+
9+
fun getConnections(): MutableList<String> {
10+
return connections
11+
}
12+
13+
override fun toString(): String {
14+
return "Node(vertex='$vertex', connections=$connections)"
15+
}
16+
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package pl.dmichalski.algorithms.data_structures._11_graph_traversal
2+
3+
object Runner {
4+
5+
private const val VERTEX_A = "A"
6+
private const val VERTEX_B = "B"
7+
private const val VERTEX_C = "C"
8+
private const val VERTEX_D = "D"
9+
private const val VERTEX_E = "E"
10+
private const val VERTEX_F = "F"
11+
12+
@JvmStatic
13+
fun main(args: Array<String>) {
14+
println("------------------ Initial undirected graph ------------------ ")
15+
var undirectedGraph = getUndirectedGraph()
16+
printUndirectedGraph(undirectedGraph)
17+
18+
println("------------------ Depth First Search recursive traversal ------------------ ")
19+
undirectedGraph = getUndirectedGraph()
20+
var depthFirstSearch = undirectedGraph.depthFirstSearchRecursive(VERTEX_A)
21+
println("Graph elements: $depthFirstSearch")
22+
printUndirectedGraph(undirectedGraph)
23+
24+
println("------------------ Depth First Search iterative traversal ------------------ ")
25+
undirectedGraph = getUndirectedGraph()
26+
depthFirstSearch = undirectedGraph.depthFirstSearchIterative(VERTEX_A)
27+
println("Graph elements: $depthFirstSearch")
28+
printUndirectedGraph(undirectedGraph)
29+
}
30+
31+
/**
32+
* It returns undirected graph like this:
33+
* <pre>
34+
* A
35+
* / \
36+
* B C
37+
* \ /
38+
* D -- E
39+
* \ /
40+
* F
41+
* </pre>
42+
*/
43+
private fun getUndirectedGraph(): UndirectedGraph {
44+
val undirectedGraph = UndirectedGraph()
45+
46+
undirectedGraph.addVertex(VERTEX_A)
47+
undirectedGraph.addVertex(VERTEX_B)
48+
undirectedGraph.addVertex(VERTEX_C)
49+
undirectedGraph.addVertex(VERTEX_D)
50+
undirectedGraph.addVertex(VERTEX_E)
51+
undirectedGraph.addVertex(VERTEX_F)
52+
53+
undirectedGraph.addEdge(VERTEX_A, VERTEX_B)
54+
undirectedGraph.addEdge(VERTEX_A, VERTEX_C)
55+
undirectedGraph.addEdge(VERTEX_B, VERTEX_D)
56+
undirectedGraph.addEdge(VERTEX_C, VERTEX_E)
57+
undirectedGraph.addEdge(VERTEX_D, VERTEX_E)
58+
undirectedGraph.addEdge(VERTEX_D, VERTEX_F)
59+
undirectedGraph.addEdge(VERTEX_E, VERTEX_F)
60+
61+
return undirectedGraph
62+
}
63+
64+
private fun printUndirectedGraph(undirectedGraph: UndirectedGraph) {
65+
println(undirectedGraph)
66+
}
67+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package pl.dmichalski.algorithms.data_structures._11_graph_traversal
2+
3+
import java.util.*
4+
import kotlin.collections.ArrayList
5+
import kotlin.collections.HashSet
6+
7+
class UndirectedGraph {
8+
9+
private val adjacencyList: MutableList<Node> = ArrayList()
10+
11+
fun addVertex(vertex: String) {
12+
val node = findNode(vertex)
13+
14+
if (node == null) {
15+
val newNode = Node(vertex, mutableListOf())
16+
this.adjacencyList.add(newNode)
17+
}
18+
}
19+
20+
fun addEdge(vertex1: String, vertex2: String) {
21+
val node1 = findNode(vertex1)
22+
val node2 = findNode(vertex2)
23+
24+
node1!!.getConnections().add(vertex2)
25+
node2!!.getConnections().add(vertex1)
26+
}
27+
28+
fun depthFirstSearchRecursive(vertex: String): MutableList<Node> {
29+
val result: MutableList<Node> = ArrayList()
30+
val visited: MutableSet<String> = HashSet()
31+
32+
val node = findNode(vertex)
33+
34+
fun dfs(node: Node?) {
35+
if (node == null) {
36+
return
37+
}
38+
visited.add(node.getVertex())
39+
result.add(node)
40+
node.getConnections()
41+
.map { con -> findNode(con) }
42+
.filter { neighbour -> !visited.contains(neighbour!!.getVertex()) }
43+
.forEach { neighbour -> dfs(neighbour) }
44+
}
45+
46+
dfs(node)
47+
48+
return result
49+
}
50+
51+
fun depthFirstSearchIterative(vertex: String): MutableList<Node> {
52+
val stack = ArrayDeque<Node>()
53+
stack.push(findNode(vertex)!!)
54+
val result: MutableList<Node> = ArrayList()
55+
val visited: MutableSet<String> = HashSet()
56+
var currentVertex: Node?
57+
58+
visited.add(vertex)
59+
while (stack.size > 0) {
60+
currentVertex = stack.pop()
61+
result.add(currentVertex)
62+
63+
currentVertex.getConnections()
64+
.map { con -> findNode(con) }
65+
.filter { neighbour -> !visited.contains(neighbour!!.getVertex()) }
66+
.forEach { neighbour ->
67+
visited.add(neighbour!!.getVertex())
68+
stack.push(neighbour)
69+
}
70+
}
71+
72+
return result
73+
}
74+
75+
override fun toString(): String {
76+
return "UndirectedGraph(adjacencyList='$adjacencyList')\n"
77+
}
78+
79+
private fun findNode(vertex: String): Node? {
80+
return adjacencyList.stream()
81+
.filter { node -> node.getVertex() == vertex }
82+
.findFirst()
83+
.orElse(null)
84+
}
85+
86+
}

0 commit comments

Comments
 (0)