Skip to content

Commit f6f6d53

Browse files
committed
DFS topology sort
1 parent efeef70 commit f6f6d53

File tree

2 files changed

+99
-1
lines changed

2 files changed

+99
-1
lines changed

scala/src/main/scala/ch43_topology_sort/GraphTopology.scala

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package ch43_topology_sort
22

33
import scala.collection.mutable
4+
import scala.collection.mutable.ArrayBuffer
45

56
class GraphTopology(vertex: Int) {
67

@@ -16,7 +17,7 @@ class GraphTopology(vertex: Int) {
1617

1718
def topologySortByKahn(): Array[Int] = {
1819
val seq = new mutable.ArrayBuffer[Int]()
19-
//inDgrees contains all the inDegree for a given node
20+
//inDegrees contains all the inDegree for a given node
2021
val inDegrees = new Array[Int](vertex)
2122
for (i <- Range(0, vertex)) {
2223
for (j <- adjacency(i).indices) {
@@ -53,6 +54,47 @@ class GraphTopology(vertex: Int) {
5354

5455
seq.toArray
5556
}
57+
58+
def topologySortByDFS(): Array[Int] = {
59+
val inverseAdj = new Array[mutable.MutableList[Int]](vertex)
60+
for (i <- Range(0, vertex)) {
61+
inverseAdj(i) = new mutable.MutableList[Int]()
62+
}
63+
64+
//build the inverse adj
65+
for (i <- Range(0, vertex)) {
66+
for (j <- adjacency(i).indices) {
67+
val index = adjacency(i).get(j).get
68+
inverseAdj(index) += i
69+
}
70+
}
71+
72+
val visited = new Array[Boolean](vertex)
73+
val seq = new ArrayBuffer[Int]()
74+
for (i <- Range(0, vertex)) {
75+
if (!visited(i)) {
76+
visited(i) = true
77+
//call dfs
78+
seq ++= dfs(i, inverseAdj, visited)
79+
}
80+
}
81+
82+
seq.toArray
83+
}
84+
85+
def dfs(index: Int, inverseAdj: Array[mutable.MutableList[Int]], visited: Array[Boolean]): ArrayBuffer[Int] = {
86+
val seq = new ArrayBuffer[Int]()
87+
88+
for (i <- inverseAdj(index).indices) {
89+
val sourceIndex = inverseAdj(index).get(i).get
90+
if (!visited(sourceIndex)) {
91+
visited(sourceIndex) = true
92+
seq ++= dfs(sourceIndex, inverseAdj, visited)
93+
}
94+
}
95+
seq += index
96+
seq
97+
}
5698
}
5799

58100

scala/src/test/scala/ch43_topology_sort/GraphTopologyTest.scala

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,60 @@ class GraphTopologyTest extends FlatSpec with Matchers {
6161
val seq = graphTopology.topologySortByKahn()
6262
seq.map(nodes(_)).mkString(",") should equal("a")
6363
}
64+
65+
/*
66+
a -> b
67+
| |
68+
\|/ \|/
69+
c -> d -> e
70+
*/
71+
it should "topologySortByDFS - 1" in {
72+
val nodes = Array("a", "b", "c", "d", "e")
73+
val graphTopology = new GraphTopology(nodes.length)
74+
graphTopology.addEdge(0, 1)
75+
graphTopology.addEdge(0, 2)
76+
graphTopology.addEdge(1, 3)
77+
graphTopology.addEdge(2, 3)
78+
graphTopology.addEdge(3, 4)
79+
80+
val seq = graphTopology.topologySortByDFS()
81+
seq.map(nodes(_)).mkString(",") should equal("a,b,c,d,e")
82+
}
83+
84+
/*
85+
a -> d ---
86+
| |
87+
\|/ \|/
88+
e -> c
89+
*/
90+
it should "topologySortByDFS - 2" in {
91+
val nodes = Array("a", "b", "c", "d", "e")
92+
val graphTopology = new GraphTopology(nodes.length)
93+
graphTopology.addEdge(0, 3)
94+
graphTopology.addEdge(3, 4)
95+
graphTopology.addEdge(3, 2)
96+
graphTopology.addEdge(4, 2)
97+
98+
val seq = graphTopology.topologySortByDFS()
99+
seq.map(nodes(_)).mkString(",") should equal("a,b,d,e,c")
100+
}
101+
102+
/*
103+
a -> d <- b
104+
| /|\
105+
\|/ |
106+
e -> c
107+
*/
108+
it should "topologySortByDFS - 3" in {
109+
val nodes = Array("a", "b", "c", "d", "e")
110+
val graphTopology = new GraphTopology(nodes.length)
111+
graphTopology.addEdge(0, 3)
112+
graphTopology.addEdge(3, 4)
113+
graphTopology.addEdge(4, 2)
114+
graphTopology.addEdge(2, 1)
115+
graphTopology.addEdge(1, 3)
116+
117+
val seq = graphTopology.topologySortByKahn()
118+
seq.map(nodes(_)).mkString(",") should equal("a")
119+
}
64120
}

0 commit comments

Comments
 (0)