圖的拓撲排序詳解與實現
基本概念
有向無環圖(DAG)
如何用有向無環圖(DAG,Directed Acyclic Graph) 來表示偏序關係?
- 設 R R R 是有窮集合 X X X 上的偏序關係,對 X X X 中每個 v v v,用一個以 v v v 為標號的頂點表示,由此構成頂點集 V V V;對任意 ( u , v ) ∈ R , ( u ≠ v ) ( u , v )∈R,( u ≠ v ) (u,v)∈R,(u=v)(嚴格偏序或反自反偏序關係),由對應兩個頂點建立一條有向邊,由此構成邊集 E E E, 則 G = ( V , E ) G =( V , E ) G=(V,E) 是有向無環圖。
拓撲排序
拓撲排序(Topological Sorting):是由某個集合上的一個偏序關係得到該集合上的一個全序的過程,所得到的線性序列稱為拓撲序列(Topological order)。
在圖論中,拓撲排序是一個有向無環圖的所有頂點的線性序列,且該序列必須滿足下面兩個條件:
- 每個頂點出現且只出現一次;
- 若存在一條從頂點 A 到頂點 B 的路徑,那麼在序列中頂點 A 出現在頂點 B 的前面;
AOV 網
AOV 網就是一種有向無環圖。
一個較大的工程往往被劃分成許多子工程,在整個工程中,有些子工程(活動)必須在其它有關子工程完成之後才能開始,也就是說,一個子工程的開始是以它的所有前序子工程的結束為先決條件的,但有些子工程沒有先決條件,可以安排在任何時間開始。
為了形象地反映出整個工程中各個子工程(活動)之間的先後關係,可用一個有向圖來表示,用頂點表示活動,用弧表示活動之間的優先關係,稱這樣的有向圖為頂點表示活動的網,簡稱 AOV 網。
- AOV 網中的弧表示活動之間存在的某種制約關係。
- 一個 AOV 網應該是一個有向無環圖,即不應該帶有迴路,因為若帶有迴路,則迴路上的所有活動都無法進行。
其實 AOV 網就體現了各個子工程之間的一種偏序關係。在 AOV 網中所有活動可排列成一個線性序列,使得每個活動的所有前驅活動都排在該活動的前面,我們把此序列叫做拓撲序列,由AOV網構造拓撲序列的過程叫做拓撲排序。
AOV網的拓撲序列不是唯一的,滿足上述定義的任一線性序列都稱作它的拓撲序列。
DAG 拓撲排序演算法
課程及課程間的先修關係是偏序關係,可以用 AOV 網(DAG)表示。
利用 AOV 網進行拓撲排序的基本思想:
- (1) 從 AOV 網中選擇一個沒有前驅的頂點並且輸出它;
- (2) 從 AOV 網中刪去該頂點和所有以該頂點為尾的弧;
- (3) 重複上述兩步,直到全部頂點都被輸出,或AOV網中不存在沒有前驅的頂點;
廣搜優先搜尋實現拓撲排序
演算法過程——可以使用廣度優先搜尋演算法(使用佇列):
-
(1)建立入度為零的頂點佇列;
-
(2)掃描頂點表,將入度為0的頂點入隊(初始化);
-
(3)
while(佇列不空)
- (3.1)輸出隊頭結點;
- (3.2)記下輸出結點的數目;
- (3.3)刪去與之關聯的出邊;
- (3.4)若有入度為 0 的結點,入隊。
-
(4)若輸出結點個數小於 n n n,則輸出有環路;否則拓撲排序正常結束。
注意事項:
- 若圖中還有未輸出的頂點,但已跳出迴圈處理,說明圖中還剩下一些頂點,它們的入度都大於 0,也就是都有直接前驅,這時網路中必存在有向環。
與廣度優先搜尋的區別:
- 搜尋起點是入度為 0 的頂點;
- 需判斷是否有環路,看最後輸出的頂點數與圖中頂點數是否相同;
- 需刪除鄰接於 v 的邊(引入陣列
indegree[ ]
或在頂點表中增加一個屬性域indegree
)
虛擬碼如下:
void Topologicalsort(AdjGraph G)
{
QUEUE Q ;
count = 0 ;
MAKENUlLL(Q) ;
for(v=1; v<=G.n; ++v)
if(indegree[v] ==0)
ENQUEUE(v, Q) ;
while(!EMPTY(Q)) {
v = FRONT(Q) ;
DEQUEUE(Q) ;
cout << v << " "; // 廣度優先搜尋中,入佇列時訪問或出佇列時訪問是一樣的
count ++ ;
for(鄰接於 v 的每個頂點 w)
if(!(--indegree[w]))
ENQUEUE(w,Q) ;
}
if(count < n)
cout << “圖中有環路” ;
}
深度優先搜尋非遞迴實現拓撲排序
也可以使用深度優先搜尋來獲取拓撲序列,遞迴或非遞迴實現均可。
在深度優先搜尋的非遞迴實現中,需要用到棧:
-
(1)建立入度為零的頂點棧;
-
(2)掃描頂點表,將入度為0的頂點棧;
-
(3)
while(棧不空)
- (3.1)輸出隊頭結點;
- (3.2)記下輸出結點的數目;
- (3.3)刪去與之關聯的出邊;
- (3.4)若有入度為0的結點,入棧;
-
(4)若輸出結點個數小於 n n n,則輸出有環路;否則拓撲排序正常結束。
虛擬碼如下:
void Topologicalsort(AdjGraph G)
{
STACK S ;
count = 0 ;
MAKENUlLL(S) ;
for(v=1; v<=G.n; ++v)
if(indegree[v] == 0)
PUSH(v, S) ;
while(!EMPTY(S)) {
v = top(S) ;
S.pop() ;
cout << v << " "; // 深度優先搜尋中,必須在出棧時訪問
count ++ ;
for(鄰接於 v 的每個頂點 w)
if(!(--indegree[w]))
PUSH(w,S) ;
}
if(count < n)
cout << “圖中有環路” ;
}
深度優先搜尋遞迴實現拓撲排序
待補。
相關文章
- 圖解拓撲排序+程式碼實現圖解排序
- DFS實現拓撲排序排序
- 圖論——拓撲排序圖論排序
- Reward (圖論+拓撲排序)圖論排序
- AOV網與拓撲排序排序
- 圖(3)--拓撲排序與關鍵路徑排序
- 有向圖的拓撲排序——DFS排序
- 拓撲排序排序
- vue 實現動態拓撲圖Vue
- 演算法-圖論-拓撲排序演算法圖論排序
- 拓撲排序,YYDS排序
- 拓撲排序模板排序
- C語言實現有向無環圖的拓撲排序演算法C語言排序演算法
- 【圖論】拓撲排序+優先佇列圖論排序佇列
- 資料結構與演算法——有向無環圖的拓撲排序C++實現資料結構演算法排序C++
- 拓撲排序小結排序
- 筆記:拓撲排序筆記排序
- 拓撲排序 (BFS )DAG (有向無環圖)排序
- 拓撲排序 - Topological Sort排序
- 拓撲排序核心程式碼排序
- HDU 4857 逃生(拓撲排序)排序
- 【筆記/模板】拓撲排序筆記排序
- 拓撲排序詳解(梅開二度之dfs版按字典序輸出拓撲路徑+dfs版輸出全部拓撲路徑排序
- 拓撲排序就這麼回事排序
- HDU4857逃生(拓撲排序)排序
- 紙上談兵: 拓撲排序排序
- poj 1094 拓撲排序排序
- VOL.2 拓撲排序與關鍵路徑排序
- poj1094 拓撲排序排序
- 網路拓撲圖:網路拓撲圖介紹及線上製作
- Flink原理與實現:架構和拓撲概覽架構
- POJ 3249-Test for Job(拓撲排序&&DP)排序
- HDU 5438 Ponds (拓撲排序應用+DFS)排序
- CF 274D Lovely Matrix(拓撲排序)排序
- HDU 4857-逃生(反向拓撲排序-按條件排序)排序
- HTML5 網路拓撲圖整合 OpenLayers 實現 GIS 地圖應用HTML地圖
- 一個很漂亮的拓撲圖程式
- hdu 1811 並查集+拓撲排序並查集排序