拓撲排序(topological order)是指,將乙個有向無環圖(directed acyclic graph簡稱dag)進行排序進而得到乙個有序的線性序列。
這樣說,可能理解起來比較抽象。下面通過簡單的例子進行說明!
例如,乙個專案包括a、b、c、d四個子部分來完成,並且a依賴於b和d,c依賴於d。現在要制定乙個計畫,寫出a、b、c、d的執行順序。這時,就可以利用到拓撲排序,它就是用來確定事物發生的順序的。
在拓撲排序中,如果存在一條從頂點a到頂點b的路徑,那麼在排序結果中b出現在a的後面。
拓撲排序演算法的基本步驟:
1.構造乙個佇列q(queue) 和 拓撲排序的結果佇列t(topological);以上圖為例,來對拓撲排序進行演示。2.把所有沒有依賴頂點的節點放入q;
3.當q還有頂點的時候,執行下面步驟:
3.1從q中取出乙個頂點n(將n從q中刪掉),並放入t(將n加入到結果集中);
3.2對n每乙個鄰接點m(n是起點,m是終點);
3.2.1去掉邊;
3.2.2如果m沒有依賴頂點,則把m放入q;
注:頂點a沒有依賴頂點,是指不存在以a為終點的邊。
第1步:將b和c加入到排序結果中。
頂點b和頂點c都是沒有依賴頂點,因此將c和c加入到結果集t中。假設abcdefg按順序儲存,因此先訪問b,再訪問c。訪問b之後,去掉邊和,並將a和d加入到佇列q中。同樣的,去掉邊和,並將f和g加入到q中。
(01) 將b加入到排序結果中,然後去掉邊和;此時,由於a和d沒有依賴頂點,因此並將a和d加入到佇列q中。
(02) 將c加入到排序結果中,然後去掉邊和;此時,由於f有依賴頂點d,g有依賴頂點a,因此不對f和g進行處理。
第2步:將a,d依次加入到排序結果中。
第1步訪問之後,a,d都是沒有依賴頂點的,根據儲存順序,先訪問a,然後訪問d。訪問之後,刪除頂點a和頂點d的出邊。
第3步:將e,f,g依次加入到排序結果中。
因此訪問順序是:b -> c -> a -> d -> e -> f -> g
拓撲排序是對有向無向圖的排序。下面以鄰接表實現的有向圖來對拓撲排序進行說明。
1. 基本定義
// 鄰接表中表對應的鍊錶的頂點
typedef struct _enode
enode, *penode;
// 鄰接表中表的頂點
typedef struct _vnode
vnode;
// 鄰接表
typedef struct _lgraph
lgraph;
(01)lgraph是鄰接表對應的結構體。 vexnum是頂點數,edgnum是邊數;vexs則是儲存頂點資訊的一維陣列。
(02)vnode是鄰接表頂點對應的結構體。 data是頂點所包含的資料,而firstedge是該頂點所包含鍊錶的表頭指標。
(03)enode是鄰接表頂點所包含的鍊錶的節點對應的結構體。 ivex是該節點所對應的頂點在vexs中的索引,而nextedge是指向下乙個節點的。
2. 拓撲排序
/*
* 拓撲排序
* * 引數說明:
* g -- 鄰接表表示的有向圖
* 返回值:
* -1 -- 失敗(由於記憶體不足等原因導致)
* 0 -- 成功排序,並輸入結果
* 1 -- 失敗(該有向圖是有環的)
*/int topological_sort(lgraph g)
}// 將所有入度為0的頂點入佇列
for(i = 0; i < num; i ++)
if(ins[i] == 0)
queue[rear++] = i; // 入佇列
while (head != rear) // 佇列非空
}if(index != g.vexnum)
// 列印拓撲排序結果
printf("== topsort: ");
for(i = 0; i < num; i ++)
printf("%c ", tops[i]);
printf("\n");
free(queue);
free(ins);
free(tops);
return 0;
}
說明:
(01)queue的作用就是用來儲存沒有依賴頂點的頂點。它與前面所說的q相對應。
(02)tops的作用就是用來儲存排序結果。它與前面所說的t相對應。
用頂點表示活動,用弧表示活動之間的優先關係,這樣的有向圖為頂點表示活動的網,稱之為aov網(activity on vertex network)。aov網中的弧表示活動之間存在的某種制約關係
設g(v,e)是乙個具有一條路徑,則在頂點序列中頂點vi必在頂點vj之前,這樣的頂點序列為乙個拓撲序列
拓撲排序:就是對乙個有向圖構造拓撲序列的過程。如果構造時網的全部頂點都被輸出,則說明它不存在環的aov網;如果輸出頂點數少了,說明這個網存在環,不是aov網
拓撲排序演算法
思路:從aov網中選擇乙個入度為0的頂點輸出(入度為0代表沒有頂點的順序在此頂點的前面),然後刪去此頂點,並刪除以此頂點為尾的弧,繼續重複此步驟,直到輸出全部頂點或者aov網中不存在入度為0的頂點為止。
資料結構:
in
data
firstedge
入度的數目:因為演算法過程中始終需要查詢入度為0的頂點
第乙個鄰接點
①之所以用到鄰接表,是因為要刪除頂點,鄰接表會更加方便 ;②可以利用棧,用來儲存處理過程中入度為0的頂點,目的是為了避免每個查詢是都要去遍歷頂點表棧有沒有入度為0的頂點
入棧的時間複雜度為o(n),而之後的while迴圈,每個頂點進一次棧,出一次棧,入度減1的操作工執行了e次,所以整個演算法的時間複雜度為o( n+e )
資料結構之拓撲排序
乙個簡單的求拓撲排序思路是 先找出任意乙個沒有入邊的頂點。然後列印出該頂點,並將它和它的邊一起從圖中刪除。然後,我們對圖的其餘部分採用同樣的方法處理。相應的我們可以定義乙個indegree 入度陣列 儲存所有頂點的入度。具體實現如下 鄰接表 define crt secure no warnings...
資料結構之拓撲排序
感覺重點就是鄰接表的建立和tp toposort 函式中的乙個變數 的變化很奇妙,相當於是乙個靜態指標的用法。include include include include include include include include include define inf 0x3f3f3f3f d...
資料結構之拓撲排序
一 什麼是拓撲排序 在圖論中,拓撲排序 topological sorting 是乙個有向無環圖 dag,directed acyclic graph 的所有頂點的線性序列。且該序列必須滿足下面兩個條件 每個頂點出現且只出現一次。若存在一條從頂點 a 到頂點 b 的路徑,那麼在序列中頂點 a 出現在...