一、问题
0 -> 1 -> 2
↓ ↓ ↓
3 -> 4 -> 5
输出该图的一条拓扑排序,比如
0 -> 1 -> 3 -> 2 -> 4 -> 5
二、代码
Java
public class DirectedLinkedGraph {
private int vertexNum; // 顶点个数
private LinkedList<Integer> adj[]; // 邻接表
public DirectedLinkedGraph(int vertexNum) {
this.vertexNum = vertexNum;
adj = new LinkedList[vertexNum];
for (int i = 0; i < vertexNum; ++i) {
adj[i] = new LinkedList<>();
}
}
public void addEdge(int from, int to) { // 有向图一条边存两次
adj[from].add(to);
}
/**
* 创建
* <p>
* 0 -> 1 -> 2
* ↓ ↓ ↓
* 3 -> 4 -> 5
*/
public void build() {
addEdge(0, 1);
addEdge(0, 3);
addEdge(1, 2);
addEdge(1, 4);
addEdge(2, 5);
addEdge(3, 4);
addEdge(4, 5);
}
/**
* 获取每个顶点的入度
*/
public List<Integer> getInDegrees() {
List<Integer> inDegrees = new ArrayList<>();
for(int i=0; i< adj.length; i++) {
inDegrees.add(0);
}
for (int i = 0; i < adj.length; i++) {
for (int j = 0; j < adj[i].size(); j++) {
int index = adj[i].get(j);
inDegrees.set(index, inDegrees.get(index) + 1);
}
}
return inDegrees;
}
/**
* 拓扑排序:Kahn算法
*/
public List<Integer> topoSort() {
List<Integer> topoList = new ArrayList<>();
//每个顶点的入度
List<Integer> inDegrees = getInDegrees();
//入度=0的顶点
Queue<Integer> zeroInDegreeQueue = new LinkedList<>();
for(int i=0; i<inDegrees.size(); i++) {
if (inDegrees.get(i) ==0) {
zeroInDegreeQueue.add(i);
}
}
while (!zeroInDegreeQueue.isEmpty()) {
Integer head = zeroInDegreeQueue.poll();
topoList.add(head);
//head能到的所有顶点的入度-1
for(int i=0; i<adj[head].size(); i++) {
int index = adj[head].get(i);
inDegrees.set(index, inDegrees.get(index) - 1);
if (inDegrees.get(index) == 0) {
zeroInDegreeQueue.add(index);
}
}
}
return topoList;
}
public static void main(String[] args) {
DirectedLinkedGraph graph = new DirectedLinkedGraph(6);
graph.build();
List<Integer> topoList = graph.topoSort();
for(int i=0; i<topoList.size(); i++) {
System.out.print(topoList.get(i));
if (i != topoList.size()-1) {
System.out.print(" -> ");
}
}
}
}
运行结果
0 -> 1 -> 3 -> 2 -> 4 -> 5