Kahn topology sort

This commit is contained in:
Ivan Li 2019-01-30 19:08:06 +08:00
parent 45758ee438
commit a5f97492c1
2 changed files with 103 additions and 0 deletions

View File

@ -0,0 +1,58 @@
package ch43_topology_sort
import scala.collection.mutable
class GraphTopology(vertex: Int) {
//define the graph
val adjacency = new Array[mutable.MutableList[Int]](vertex)
for (i <- Range(0, vertex)) {
adjacency(i) = new mutable.MutableList[Int]()
}
def addEdge(startIndex: Int, targetIndex: Int) = {
adjacency(startIndex) += targetIndex
}
def topologySortByKahn(): Array[Int] = {
val seq = new mutable.ArrayBuffer[Int]()
//inDgrees contains all the inDegree for a given node
val inDegrees = new Array[Int](vertex)
for (i <- Range(0, vertex)) {
for (j <- adjacency(i).indices) {
val index = adjacency(i).get(j).get
inDegrees(index) += 1
}
}
val queue = new mutable.Queue[Int]()
for (i <- inDegrees.indices) {
if (inDegrees(i) == 0) {
// means there is no inDegree for this node,
// this could be the starting point of the dependency graph
queue += i
}
}
//start to navigating the graph from the starting point
while (queue.nonEmpty) {
val index = queue.dequeue()
//push to the result
seq += index
for (i <- adjacency(index).indices) {
val inDegreeIndex = adjacency(index).get(i).get
inDegrees(inDegreeIndex) -= 1
if (inDegrees(inDegreeIndex) == 0) {
queue += inDegreeIndex
}
}
}
seq.toArray
}
}

View File

@ -0,0 +1,45 @@
package ch43_topology_sort
import org.scalatest.{FlatSpec, Matchers}
class GraphTopologyTest extends FlatSpec with Matchers {
behavior of "GraphTopologyTest"
/*
a -> b
| |
\|/ \|/
c -> d -> e
*/
it should "topologySortByKahn - 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.topologySortByKahn()
seq.map(nodes(_)).mkString(",") should equal("a,b,c,d,e")
}
/*
a -> d ---
| |
\|/ \|/
e -> c
*/
it should "topologySortByKahn - 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.topologySortByKahn()
seq.map(nodes(_)).mkString(",") should equal("a,b,d,e,c")
}
}