0)拓撲排序
拓撲排序是對有向無圈圖的頂點的一種排序,這個排序的結果是如果存在一條vi到vj的路徑,那麼排序中vi在vj的前面。
下圖是乙個有向無圈圖的例子:
在這個有向無圈圖中,1,6,5,7,4,2,3;1,6,5,7,2,4,3;這兩組都是拓撲排序,我們可以看到這兩種排序都滿足拓撲排序的要求,比如說1-4的路徑,可知1,7,4;1,6,5,4;1,6,7,4;1,6,5,7,4;這些路徑的點都按照拓撲排序的要求排列。
1) 簡單的拓撲排序演算法
下面我們介紹乙個簡單的拓撲排序演算法:
a)先找到乙個沒有輸入邊的點,輸出這個點,然後去掉與這個點連線的所有邊。
b)重複上面的步驟知道輸出所有的點。
這裡為了程式設計方便,我們要先定義乙個叫做indegree的概念:
indegree: 頂點v包含的邊(u,v)的個數。
注意是有向圖的v包含的邊(u,v)的個數。因此對於上圖的點1,它的indegree=0,因為進入點1的邊為0,點1的三條邊全是指向外的。
所以通過引入indegree概念,上面的簡單演算法就可以用下面的方式表示
a) 查詢indegree為0的點p
b) 對所有與p鄰接的點的indegree = indegree -1;
c) 查詢indegree為0的點(p除外),然後迴圈過程
下面是簡單的拓撲排序演算法的一段偽**
[cpp]view plain
copy
void topsort(graph g)
output[v] = num;
for each w adjacent to v
indegree[w]--;
} }
2) 拓撲排序的改進演算法
上面的簡單演算法還是很簡單的,也很好理解,那麼為什麼要改進上面的演算法呢?這個主要是因為上面演算法的時間複雜度為o(|v|^2)。
首先findnewvertexofdegreezero()函式因為要找到indegree=0的點,所以需要遍歷所有的點,因此時間複雜度為o(|v|)。而這個函式需要重複|v|次,因此上面的演算法的時間複雜度為o(|v|^2)。因此我們需要做一些改進,來降低執行時間。
可以看到,這裡可能能夠進行改進的就是findnewvertexofdegreezero()函式。當我們刪除乙個indegree=0的點後,只有與這個鄰接的點的indegree才會減一,其他的點的indegree值不變,因此當我們需要在一次findnewvertexofdegreezero時,不需要遍歷所有的點,只需要遍歷部分相關連的點就可以。
為了實現上面的思想,我們把indegree=0的點放到乙個box中,因此findnewvertexofdegreezero()函式只需要在這個box中尋找就好了。當乙個點的indegree=0時,我們就把這個點輸入到box中。
演算法:a) 把ndegree=0的點a放到乙個queue中;
b) 把點a出隊,然後對所有的與a鄰接的點的indegree減一;
c) 把新的ndegree=0的點入隊;
d) 重複上面的步驟
偽**實現:
[cpp]view plain
copy
void topsort(graph g)
if(num!=numvertex)
error("graph has a cycle!");
free(q);
}
這個方法相當於是以空間換時間,引入了乙個queue。
python 拓撲排序 Python 拓撲排序
python 拓撲排序 在圖論中,由乙個有向無環圖的頂點組成的序列,當且僅當滿足下列條件時,稱為該圖的乙個拓撲排序 英語 topological sorting 每個頂點出現且只出現一次 若a在序列中排在b的前面,則在圖中不存在從b到a的路徑。print 拓撲排序結果 g.topologicalso...
python 排序 拓撲排序
在電腦科學領域中,有向圖的拓撲排序是其頂點的先行排序,對於每個從頂點u到頂點v的有向邊uv,在排序的結果中u都在v之前。如果圖是有向無環圖,則拓撲排序是可能的 為什麼不說一定呢?圖論 是組合數學的乙個分支,它和其他分支比如 群論 拓撲學 矩陣論有著密切的關係。圖是圖論的主要研究物件。圖是由若干給定的...
拓撲排序演算法
對許多資料結構教材實在不滿意,至少我是看不懂 至於拓撲排序演算法,教材上那些偽 真真教人頭暈。只寫了幾個struct結構,我根本看不出這是鄰接表。如果給出乙個清晰明了的圖,一切不就簡單了?總之,關鍵就是建立乙個鄰接表。然後利用這個表進行拓撲排序。邊表結點宣告 typedef struct edgen...