Kahn topology sort
This commit is contained in:
parent
45758ee438
commit
a5f97492c1
58
scala/src/main/scala/ch43_topology_sort/GraphTopology.scala
Normal file
58
scala/src/main/scala/ch43_topology_sort/GraphTopology.scala
Normal 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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user