資料結構之拓撲排序

2021-07-07 05:16:47 字數 3445 閱讀 6991

拓撲排序(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 出現在...