拓撲排序的原理與實現

2021-08-19 15:53:26 字數 1987 閱讀 3156

拓撲排序顧名思義是一種排序演算法,它用於給有向圖排序。

有向圖是由一組頂點和一組有方向的邊組成的圖,每條有方向的邊都連線著有序的一對頂點,因此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 拓撲排序可用來解決什麼問題呢?比如說課程排序,編譯...

拓撲排序的原理分析

拓撲排序,顧名思義,就是一種排序方法。這是一種什麼排序?這種排序的作用?然後怎麼去實現這種排序演算法?現在就讓我們仔細研究下。實際上,拓撲排序是一種圖論演算法,該演算法在 資料結構與演算法 一書中有涉獵。引用維基百科的定義 在圖論中,由乙個有向無環圖的頂點組成的序列,當且僅當滿足下列條件時,稱為該圖...