拓撲排序顧名思義是一種排序演算法,它用於給有向圖排序。
有向圖是由一組頂點和一組有方向的邊組成的圖,每條有方向的邊都連線著有序的一對頂點,因此a -> b代表a可以到達b,並不代表b就能到達a。
拓撲排序的結果就是乙個有向圖的頂點序列(或稱為拓撲序列)。
想要學習《c++程式設計》就需要先學習《計算機導論》
想要學習《資料結構和演算法》就需要先學習《c++程式設計》
想要學習《網路作業系統》就需要先學習《計算機導論》
由此可以看出,這些活動都是有序的,每門課程就是圖中的頂點,而有向邊便是學習的順序。你不能先學習《c++程式設計》,再學習《計算機導論》。就好比你不能先脫內衣,再脫外套一樣。
那麼,有向圖是否就能拓撲排序呢?答案是不一定的。當圖中存在環路時,比如學習a之前要學習b,學習b之前又要學習a,那麼順序就不可控了(到底a在前還是b在前?),故拓撲排序的充要條件是它是有向無環圖。aov網(頂點活動網)就是一種有向無環圖。
同時,拓撲排序有時是不唯一的,如上圖,學習順序可以是:
《計算機導論》 -> 《c++程式設計》 -> 《網路作業系統》 ->《資料結構和演算法》
也可以是:
《計算機導論》 -> 《網路作業系統》 ->《c++程式設計》 -> 《資料結構和演算法》
由此可見,圖中存在a->b的有向邊,那麼拓撲排序結果a必在b前面(從左指向右)。
1. 遍歷頂點,找到入度為 0 的頂點(沒有後繼)
2. 刪除該頂點及其相連的邊,重複第一步,直到所有點都刪除,由此構成的順序就是拓撲序列
拓撲排序不適用簡單的計算環境,而在中大型的複雜環境中就顯得重要了。
在linux作業系統中,安裝軟體都是自動完成的,比如我安裝a,需要依賴b和c,安裝b需要依賴d、e和f,那麼用拓撲排序就可以很好解決順序問題:
d -> c -> e -> f -> b -> a
l
s while(s非空)
}if(圖還有邊)
return error of 存在環路;
else
return l;
1.計算所有頂點的入度
2.將入度為0的頂點加入集合
3.從圖中刪除該頂點及其相連的邊,並將相鄰頂點的入度-1
4.重複上述步驟
5.當集合為空檢查是否還有邊,有說明存在環路;否則排序結束
遍歷所有的頂點和邊,因此時間複雜度為o(v+e)
l
s for(s中的所有頂點)
dfs(n)
void dfs(node n)
l.push(n);
}
dfs是一種遞迴的方法,從出度為 0 的頂點開始,最先呼叫dfs卻是最後加入集合中的,排在序列的最後面。
#include #include #include #include #include using namespace std;
int v, e;
map< int, vector> g;
bool visited[100]; // 已訪問
queuepostorder; // 後序序列
和kahn演算法一樣,時間複雜度為o(v+e)
拓撲排序原理和實現
轉至 拓撲排序,顧名思義,就是一種排序方法。這是一種什麼排序?這種排序的作用?然後怎麼去實現這種排序演算法?現在就讓我們仔細研究下。實際上,拓撲排序是一種圖論演算法,該演算法在 資料結構與演算法 一書中有涉獵。引用維基百科的定義 在圖論中,由乙個有向無環圖的頂點組成的序列,當且僅當滿足下列條件時,稱...
拓撲排序的原理和實現
在圖論中,由乙個有向無環圖組成的序列,只要滿足下面兩種情況則稱為拓撲排序 可以從這副圖中發現,如果按照dfs的思想,那麼其訪問結點的結果為 5,2,3,1,0,4,但是如果是拓撲排序的話,訪問結點的結果為5,4,2,0,1,3,類似於多叉樹的bfs 拓撲排序可用來解決什麼問題呢?比如說課程排序,編譯...
拓撲排序的原理分析
拓撲排序,顧名思義,就是一種排序方法。這是一種什麼排序?這種排序的作用?然後怎麼去實現這種排序演算法?現在就讓我們仔細研究下。實際上,拓撲排序是一種圖論演算法,該演算法在 資料結構與演算法 一書中有涉獵。引用維基百科的定義 在圖論中,由乙個有向無環圖的頂點組成的序列,當且僅當滿足下列條件時,稱為該圖...