拓扑排序(java)

拓扑排序

        对一个有向无环图(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;
		}
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值