Mind and Hand Help

TopoSort (Directed)

具体实现

class TopoSort(graph: Graph) : GraphCompute(graph) { init { // 必须是有向无环图 checkEmpty().checkDirected(true) val cycleAnalyzer = CycleAnalyzer(graph) if (cycleAnalyzer.findCycles().cycles.isNotEmpty()) { throw IllegalArgumentException("Graph has cycle") } } /** * Kahn 算法实现拓扑排序 */ fun kahn(): Result { // 计算每个顶点的入度 val inDegree = IntArray(graph.vertexIndex().size()) graph.getEdges().forEach { edge -> inDegree[edge.to.id]++ } // 找到所有入度为 0 的顶点 val zeroDegreeVertices = graph.getVertexes() .filter { inDegree[it.id] == 0 } .map { VertexWrapper(0, it) } val result = Result() val queue = ArrayDeque(zeroDegreeVertices) val processedVertices = TreeSet<Int>() while (queue.isNotEmpty()) { val current = queue.removeFirst() processedVertices.add(current.vertex.id) result.add(current) // 处理当前顶点的所有邻接顶点 graph.adjacentEdges(current.vertex.id).forEach { edge -> val neighbor = edge.to if (neighbor.id !in processedVertices) { inDegree[neighbor.id]-- // 如果邻接顶点的入度变为 0,则加入队列 if (inDegree[neighbor.id] == 0) { queue.offer(VertexWrapper(current.degree + 1, neighbor)) } } } } return result } /** * 顶点包装器,包含入度信息 * @param degree 入度 * @param vertex 顶点 */ data class VertexWrapper(val degree: Int, val vertex: Vertex) { override fun toString(): String { return "${vertex.name}($degree)" } } /** * 拓扑排序结果 */ class Result { private val _sorted = mutableListOf<VertexWrapper>() val sorted: List<VertexWrapper> get() = _sorted.toList() internal fun add(vertexWrapper: VertexWrapper) { _sorted.add(vertexWrapper) } /** * 打印拓扑排序结果 */ fun printTopoSort() { printTopoSort(sorted) } /** * 打印拓扑排序结果 */ private fun printTopoSort(sorted: List<VertexWrapper>) { if (sorted.isEmpty()) { println("No vertices in the graph") return } println("Topological Sort Result: ") println(sorted.joinToString(" -> ") { it.toString() }) } /** * 检查拓扑排序是否有效(是否包含所有顶点) */ fun isValid(totalVertices: Int): Boolean { return sorted.size == totalVertices } /** * 获取排序后的顶点名称列表 */ fun getVertexNames(): List<String> { return sorted.map { it.vertex.name } } /** * 获取指定顶点在拓扑排序中的位置 */ fun getPosition(vertexName: String): Int { return sorted.indexOfFirst { it.vertex.name == vertexName } } } }
27 January 2026