【算法】【圖論】拓撲排序

引言

發現普林斯頓那本算法和算法導論都側重於用介紹用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;
}

算法特性

可以在線性時間內排序並判斷圖中是否有環

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