拓撲排序(Topological Sorting)

2021-08-30 15:59:47 字數 1506 閱讀 9579

一、什麼是拓撲排序

在圖論中,拓撲排序(topological sorting)是乙個有向無環圖(dag, directed acyclic graph)的所有頂點的線性序列。且該序列必須滿足下面兩個條件:

每個頂點出現且只出現一次。

若存在一條從頂點 a 到頂點 b 的路徑,那麼在序列中頂點 a 出現在頂點 b 的前面。

有向無環圖(dag)才有拓撲排序,非dag圖沒有拓撲排序一說。

例如,下面這個圖:

它是乙個 dag 圖,那麼如何寫出它的拓撲排序呢?這裡說一種比較常用的方法:

從 dag 圖中選擇乙個 沒有前驅(即入度為0)的頂點並輸出。

從圖中刪除該頂點和所有以它為起點的有向邊。

重複 1 和 2 直到當前的 dag 圖為空或當前圖中不存在無前驅的頂點為止。後一種情況說明有向圖中必然存在環。

於是,得到拓撲排序後的結果是 。

通常,乙個有向無環圖可以有乙個或多個拓撲排序序列。

二、拓撲排序的應用

拓撲排序通常用來「排序」具有依賴關係的任務。

比如,如果用乙個dag圖來表示乙個工程,其中每個頂點表示工程中的乙個任務,用有向邊表示在做任務 b 之前必須先完成任務 a。故在這個工程中,任意兩個任務要麼具有確定的先後關係,要麼是沒有關係,絕對不存在互相矛盾的關係(即環路)。

三、拓撲排序的實現

根據上面講的方法,我們關鍵是要維護乙個入度為0的頂點的集合。

圖的儲存方式有兩種:鄰接矩陣和鄰接表。這裡我們採用鄰接表來儲存圖,c++**如下:

#include

#include

#include

using namespace std;

/************************類宣告************************/

class graph

;/************************類定義************************/

graph::graph(int v)

void graph::addedge(int v, int w)

bool graph::topological_sort()

if(count < v)

return false;           // 沒有輸出全部頂點,有向圖中有迴路

else

return true;            // 拓撲排序成功

}測試如下dag圖:

int main()

輸出結果是 4, 5, 2, 0, 3, 1。這是該圖的拓撲排序序列之一。

每次在入度為0的集合中取頂點,並沒有特殊的取出規則,隨機取出也行,這裡使用的queue。取頂點的順序不同會得到不同的拓撲排序序列,當然前提是該圖存在多個拓撲排序序列。

由於輸出每個頂點的同時還要刪除以它為起點的邊,故上述拓撲排序的時間複雜度為o(v+e)o(v+e)。

另外,拓撲排序還可以採用 深度優先搜尋(dfs)的思想來實現,詳見《topological sorting via dfs》。

python 拓撲排序 Python 拓撲排序

python 拓撲排序 在圖論中,由乙個有向無環圖的頂點組成的序列,當且僅當滿足下列條件時,稱為該圖的乙個拓撲排序 英語 topological sorting 每個頂點出現且只出現一次 若a在序列中排在b的前面,則在圖中不存在從b到a的路徑。print 拓撲排序結果 g.topologicalso...

python 排序 拓撲排序

在電腦科學領域中,有向圖的拓撲排序是其頂點的先行排序,對於每個從頂點u到頂點v的有向邊uv,在排序的結果中u都在v之前。如果圖是有向無環圖,則拓撲排序是可能的 為什麼不說一定呢?圖論 是組合數學的乙個分支,它和其他分支比如 群論 拓撲學 矩陣論有著密切的關係。圖是圖論的主要研究物件。圖是由若干給定的...

拓撲排序演算法

對許多資料結構教材實在不滿意,至少我是看不懂 至於拓撲排序演算法,教材上那些偽 真真教人頭暈。只寫了幾個struct結構,我根本看不出這是鄰接表。如果給出乙個清晰明了的圖,一切不就簡單了?總之,關鍵就是建立乙個鄰接表。然後利用這個表進行拓撲排序。邊表結點宣告 typedef struct edgen...