拓撲排序(C語言實現)

2021-07-25 09:20:21 字數 2692 閱讀 2365

拓撲排序可以將乙個有向無環圖轉換為乙個線性序列。它也是判定乙個有向圖是否是無環的方法之一。如何進行拓撲排序,方法如下:

1

)從有向圖中選取乙個

沒有前驅

(

入度為

0)

頂點,並輸出之;

2

)從有向圖中刪去此頂點以及所有以它為尾的

(

弧頭頂點的入度減

1

)

重複上述兩步,直至圖空,或者圖不空但找不到

無前驅的頂點為止。

下圖:

這個理解起來是比較容易的,現在關鍵的是實現,如何得到入度為0的點?為避免每次都要搜尋入度為零的頂點,在演算法中設定乙個,以儲存入度為零的頂點。

在拓撲排序演算法中,需要設定乙個包含n個元素的一維整形陣列,假定用d表示,用它來儲存這個有向無環圖中每個頂點的入度值。對於上圖,得到陣列d的初始之為:00

2213

在進行拓撲排序時,為了把

所有入度為0的頂點都儲存起來,而且又便於插入、刪除以及節省空間,最好的方法是把它們鏈結成乙個棧。另外,當乙個頂點vi的入度為0時,陣列d中下標為i的元素d[i]的值為0(這句話的意思是我們沒有必要儲存入度為0的頂點的入度值,反而我們可以利用這個空間,用它來儲存下乙個入度為0的頂點的下標(序號),這裡很重要,好好理解。這樣,就可以把所有入度為0的頂點通過陣列d中的對應元素(陣列元素的下標對應著頂點編號)靜態鏈結成乙個棧。在這個鏈棧中,棧頂指標top指向第乙個入度為0的頂點所對應的陣列d中的元素,該元素的值(陣列中的值)則指向第二個入度為0的頂點所對應的陣列d中的元素,以此類推,最後乙個入度為0的頂點所對應的陣列d中的元素儲存-1,表示為棧底。

例如,根據上圖,建立鄰接表,如圖:

(1)開始置鏈棧為空,即給鏈棧指標top賦初值為-1     top=-1;

(2)將入度為0的元素d[0]進棧,即: d[0]=top;top=0        /*因為d[0]存放下乙個入度為0的頂點下標,在此,由於它是第乙個入度為0的頂點(沒有下乙個入度為0的頂點),因此d[0]的值為-1,top=0*/

d[1]=top;top=1;

(4)因d[2]至d[5]的值均不為0,所以它們均不進棧。至此,初始棧建立完畢,陣列d(多用途哦,即保留了頂點入度不為0的入度值,也作為鏈棧使用)如下圖所示:

現在頂點4輸出,以此為弧尾的頂點入度減一,得圖入下:

現在輸出頂點0,以此為弧尾的頂點入度減一,此時,頂點2的入度為0,因此入棧。d[2]=-1(d[2]=top;top=2),如圖

以此類推,直到top的值為-1,表示棧空,演算法執行結束。如果得到的頂點數是n(圖的頂點數),則表明該圖是有向無環圖,否則不是。

具體c語言實現:

#include

#include

void toposort(adjlist gl,int n)

}top=-1;   /*初始化用於鏈結入度為0的元素的棧的棧頂指標為-1*/

for(i=0;iadjvex;   /*vk是vj的乙個鄰接點*/

d[k]--;       /*vk入度減一*/

if(d[k]==0)     /*把入度為0的元素進棧,對應著圖看更容易明白*/

p=p->next;}}

printf("\n");

if(m時間複雜度o(n+e)。

C 語言實現 拓撲排序

1 拓撲排序的概念 對乙個1.在有向圖中選乙個沒有前驅的頂點並且輸出 2.從圖中刪除該頂點和所有以它為尾的弧 白話就是 刪除所有和它有關的邊 3.重複上述兩步,直至所有頂點輸出,或者當前圖中不存在無前驅的頂點為止,後者代表我們的有向圖是有環的,因此,也可以通過拓撲排序來判斷乙個圖是否有環。3 拓撲排...

基礎拓撲排序 C語言實現

演算法步驟 1 根據鄰接矩陣統計每個頂點的入度,統計結果存在mark中 2 在mark中尋找為0的頂點i,找到後將mark i 並且更新與該點相關的頂點的mark陣列 3 重複步驟 2 直到所有點的mark均為 1。例項以及 全域性變數,圖的鄰接矩陣以及記錄陣列mark int a 6 6 int ...

用C語言實現拓撲排序

aov網 在乙個表示工程的有向圖中,頂點表示活動 邊表示活動間先後關係的有向圖稱做頂點活動網 activity on vertex network 在某些活動中,一些子活動必須要在某個特定的子活動完成後才能進行,像這樣的工程圖必須是無環的。如果有向圖的所有頂點都輸出,說明此圖沒有環,否則就有環 拓撲...