【算法】【图论】拓扑排序

引言

发现普林斯顿那本算法和算法导论都侧重于用介绍用DFS实现拓扑排序,所以这一篇文章我们来着重套路下用队列实现拓扑排序的Khan算法。

核心思想

有向图中的每个节点有入度和出度这两个属性,如一个只包含a和b的有向图中,a到b有且仅有一条边则称b的入度等于 1,而a的出度为1。出度为0的顶点不可能到达其他的顶点,这样的顶点称为终点(sink),同样入度为0的顶点不可能被任何其他顶点到达,这样的顶点称为起点(source)。
khan算法利用上面的结论首先将图中所有起点存入集合,同时构建一个入度表储存所有节点的入度,然后重复的将队列中的起点出队放入集合来储存排序的结果,最后将该节点的所有邻居节在入度表中的入度-1再判断该节点的入度是否为零,如果是则将他存进起点集合,然后重复这个操作。

算法实现(伪代码)

public Stack topologicalSort(Graph graph) {
	Queue sources = new LinkedList();
	Map degrees = new HashMap();
	for (int v : graph.vertexSet()){
		int d = graph.inDegree(v);
		if (d == 0){
			sources.add(v);
		}
		degrees.put(v,d);
	}
	Stack topSorted = new Stack();
	int count = 0;
	while(!sources.isEmpty()){
		int v = sources.poll();
		topSorted.add(v);
		for (int adj : graph.adj(v)){
			int degree = degrees.get(v) - 1;
			if (degree == 0){
				sources.add(adj);
			} else {
				degrees.put(adj,degree);
			}
		}
		count += 1;
	}
	//是否有环
	if (count!=graph.vertexSet.size()){
		throw new HasCycleException();
	}
	return topSorted;
}

算法特性

可以在线性时间内排序并判断图中是否有环

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章