Skip to content

Commit

Permalink
DFS topology sort
Browse files Browse the repository at this point in the history
  • Loading branch information
email2liyang committed Jan 30, 2019
1 parent efeef70 commit f6f6d53
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 1 deletion.
44 changes: 43 additions & 1 deletion scala/src/main/scala/ch43_topology_sort/GraphTopology.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ch43_topology_sort

import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer

class GraphTopology(vertex: Int) {

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

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

seq.toArray
}

def topologySortByDFS(): Array[Int] = {
val inverseAdj = new Array[mutable.MutableList[Int]](vertex)
for (i <- Range(0, vertex)) {
inverseAdj(i) = new mutable.MutableList[Int]()
}

//build the inverse adj
for (i <- Range(0, vertex)) {
for (j <- adjacency(i).indices) {
val index = adjacency(i).get(j).get
inverseAdj(index) += i
}
}

val visited = new Array[Boolean](vertex)
val seq = new ArrayBuffer[Int]()
for (i <- Range(0, vertex)) {
if (!visited(i)) {
visited(i) = true
//call dfs
seq ++= dfs(i, inverseAdj, visited)
}
}

seq.toArray
}

def dfs(index: Int, inverseAdj: Array[mutable.MutableList[Int]], visited: Array[Boolean]): ArrayBuffer[Int] = {
val seq = new ArrayBuffer[Int]()

for (i <- inverseAdj(index).indices) {
val sourceIndex = inverseAdj(index).get(i).get
if (!visited(sourceIndex)) {
visited(sourceIndex) = true
seq ++= dfs(sourceIndex, inverseAdj, visited)
}
}
seq += index
seq
}
}


56 changes: 56 additions & 0 deletions scala/src/test/scala/ch43_topology_sort/GraphTopologyTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,60 @@ class GraphTopologyTest extends FlatSpec with Matchers {
val seq = graphTopology.topologySortByKahn()
seq.map(nodes(_)).mkString(",") should equal("a")
}

/*
a -> b
| |
\|/ \|/
c -> d -> e
*/
it should "topologySortByDFS - 1" in {
val nodes = Array("a", "b", "c", "d", "e")
val graphTopology = new GraphTopology(nodes.length)
graphTopology.addEdge(0, 1)
graphTopology.addEdge(0, 2)
graphTopology.addEdge(1, 3)
graphTopology.addEdge(2, 3)
graphTopology.addEdge(3, 4)

val seq = graphTopology.topologySortByDFS()
seq.map(nodes(_)).mkString(",") should equal("a,b,c,d,e")
}

/*
a -> d ---
| |
\|/ \|/
e -> c
*/
it should "topologySortByDFS - 2" in {
val nodes = Array("a", "b", "c", "d", "e")
val graphTopology = new GraphTopology(nodes.length)
graphTopology.addEdge(0, 3)
graphTopology.addEdge(3, 4)
graphTopology.addEdge(3, 2)
graphTopology.addEdge(4, 2)

val seq = graphTopology.topologySortByDFS()
seq.map(nodes(_)).mkString(",") should equal("a,b,d,e,c")
}

/*
a -> d <- b
| /|\
\|/ |
e -> c
*/
it should "topologySortByDFS - 3" in {
val nodes = Array("a", "b", "c", "d", "e")
val graphTopology = new GraphTopology(nodes.length)
graphTopology.addEdge(0, 3)
graphTopology.addEdge(3, 4)
graphTopology.addEdge(4, 2)
graphTopology.addEdge(2, 1)
graphTopology.addEdge(1, 3)

val seq = graphTopology.topologySortByKahn()
seq.map(nodes(_)).mkString(",") should equal("a")
}
}

0 comments on commit f6f6d53

Please sign in to comment.