您的位置:首页 > 编程语言 > Java开发

拓扑排序(java)

2017-04-26 16:32 405 查看
拓扑排序
       
对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点(每一个顶点出现且只出现一次)排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前(换言之,若顶点u在序列中排在顶点v的前面,则在图中不存在从顶点v到顶点u的路径)。

算法描述:

第一步:从DAG图中选择一个没有前驱(入度为零)的顶点输出

第二步:从图中删除该顶点,以及所有以它为起点(弧尾)的边

第三步:重复第一步和第二步的步骤直到DAG图为空,或者当前图中不存在无前驱的顶点为止,后一种情况则说明此有向图中存在环

package ccnu.offer.graph;

import java.util.ArrayList;
import java.util.Stack;

public class Demo03 {
public static void main(String[] args) {
int vertexNum = 5;
char[] vertexs = { 'a', 'b', 'c', 'd', 'e' };
int[][] matrix = { { 0, 1, 1, 0, 1 },
{ 0, 0, 1, 0, 0 },
{ 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 0 } };
Graph g = new Graph(vertexNum, vertexs, matrix);
for(char ch : topologicalSort(g)){
System.out.print(ch);
}
}

// 对有向无环图DAG(Directed Acyclic Graph)图的排序,AOV(Activity On Vertex)网即DAG图表示一个工程,那么其顶点表示活动
public static ArrayList<Character> topologicalSort(Graph g) {
ArrayList<Character> topologySerials = new ArrayList<Character>();
int[] inDegree = getInDegree(g);
Stack<Integer> s = new Stack<Integer>(); // 这是用来存放当前图中入度为零的顶点的容器(不一定要用栈,队列、List等都行)
for(int i = 0; i < inDegree.length; i++){
if(inDegree[i] == 0){ // 所有无前驱顶点的顶点入栈
s.push(i);
}
}
while(!s.isEmpty()){
int v = s.pop();
topologySerials.add(g.vertexs[v]);
for(int i = 0; i < g.matrix.length; i++){
if(g.matrix[v][i] != 0){ // 顶点i的前驱为顶点v
if(--inDegree[i] == 0){ // 顶点i已无前驱
s.push(i);
}
}
}

}
return topologySerials;
}

public static int[] getInDegree(Graph g) {
int[] inDegree = new int[g.vertexNum];
for (int i = 0; i < g.matrix.length; i++) {
for (int ii = 0; ii < g.matrix.length; ii++) {
if (g.matrix[ii][i] != 0) {
inDegree[i]++;
}
}
}
return inDegree;
}

private static class Graph {
private int vertexNum;
private char[] vertexs;
private int[][] matrix;

public Graph(int vertexNum, char[] vertexs, int[][] matrix) {
this.vertexNum = vertexNum;
this.vertexs = vertexs;
this.matrix = matrix;
}
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  AOV DAG 拓扑排序