1. 程式人生 > >拓撲排序(topological sorting)時間複雜度

拓撲排序(topological sorting)時間複雜度

AOV網路

  在有向圖中,用頂點表示活動,用有向邊<Vi, Vj>表示活動Vi必須先於活動Vj進行。這種有向圖叫作頂底表示活動的網路(Active on vertices),記作AOV網路。 
  在AOV網路中,如果活動Vi必須在Vj之前進行,則存在有向邊<Vi, Vj>,並稱Vi是Vj的直接前驅,Vj是Vi的直接後繼。這種前驅與後繼的關係具有傳遞性和反自反性,這要求AOV網路中不能出現迴路,即有向環。因此,對於給定的AOV網路,必須先判斷它是否存在有向環。

拓撲排序

  檢測有向環可以通過對AOV網路構造它的拓撲有序序列(即進行拓撲排序,topological sorting)。該過程將各個頂點排列成一個線性有序的序列,使得AOV網路中所有的前驅和後繼關係都能得到滿足

。 
  如果拓撲排序能夠將AOV網路的所有頂點都排入一個拓撲有序的序列中,則說明該AOV網路中沒有有向環,否則AOV網路中必然存在有向環。AOV網路的頂點的拓撲有序序列不唯一。

拓撲排序演算法的虛擬碼

  1. 棧S初始化;累加器count初始化;
  2. 掃描頂點表,將沒有前驅(即入度為0)的頂點壓棧;
  3. 當棧S非空時迴圈 
    3.1 vj=退出棧頂元素;輸出vj;累加器加1; 
    3.2 將頂點vj的各個鄰接點的入度減1; 
    3.3 將新的入度為0的頂點入棧;
  4. if (count<vertexNum) 輸出有迴路資訊;

利用頂點的入度陣列建立棧S

  為了建立棧S,可以不另外分配儲存空間,直接利用入度陣列inDegree[]中為零的元素,同時設立一個棧頂指標top,指示當前棧頂的位置,即某一個入度為零的頂點位置。棧初始化時置top=-1,表示空棧。

  1. 將頂點w進棧時(此時w的入度為0, 不再需要inDegree[w]): 
    count[w] = top; top = w;
  2. 退棧時: 
    v = top; top = inDegree[top]

演算法複雜度

  如果AOV網路有n個頂點,e條邊,在拓撲排序的過程中,搜尋入度為零的頂點所需的時間是O(n)。在正常情況下,每個頂點進一次棧,出一次棧,所需時間O(n)。每個頂點入度減1的運算共執行了e次。所以總的時間複雜為O(n+e)。