在图论中,拓扑排序(Topological Sorting)是一个有向无环图(DAG, Directed Acyclic Graph)的所有顶点的线性序列。且该序列必须满足下面两个条件:
入度 (indegree):指向该顶点的边的数量; 出度 (outdegree):该顶点指向其他点的边的数量。
问题:
针对给定的有向图找到任意一种拓扑排序的顺序
解法:
Kahn’s algorithm: First, find a list of “start nodes” which have no incoming edges and insert them into a set S; at least one such node must exist in a non-empty acyclic graph. Then:
L ← Empty list that will contain the sorted elements
S ← Set of all nodes with no incoming edge
while S is not empty do
remove a node n from S
add n to L
for each node m with an edge e from n to m do
remove edge e from the graph
if m has no other incoming edges then
insert m into S
if graph has edges then
return error (graph has at least one cycle)
else
return L (a topologically sorted order)
时间复杂度: O(V+E),空间复杂度: O(V)
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
class DirectedGraphNode {
int label;
ArrayList<DirectedGraphNode> neighbors;
DirectedGraphNode(int x) {
label = x;
neighbors = new ArrayList<DirectedGraphNode>();
}
};
public class TopologicalSort {
/**
* @param graph: A list of Directed graph node
* @return: Any topological order for the given graph.
**/
public ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph) {
List<DirectedGraphNode> result = new ArrayList<DirectedGraphNode>();
if (graph == null) {
return result;
}
// 1. count in-degree
HashMap<DirectedGraphNode, Integer> map = new HashMap();
for (DirectedGraphNode node : graph) {
for (DirectedGraphNode neighbor : node.neighbors) {
map.put(neighbor, map.getOrDefault(neighbor, 0) + 1);
}
}
// 2.
Deque<DirectedGraphNode> queue = new ArrayDeque<>();
for (DirectedGraphNode node : graph) {
if (!map.containsKey(node)) {
queue.offer(node);
result.add(node);
}
}
while (!queue.isEmpty()) {
DirectedGraphNode node = queue.poll();
for (DirectedGraphNode node : node.neighbors) {
map.put(node, map.get(node) - 1);
if (map.get(node) == 0) {
result.add(node);
queue.offer(node);
}
}
}
return result;
}
}