AOV網的定義
以頂點表示活動,以有向邊表示活動之間的優先關係的有向圖稱為頂點表示活動的網(Activity On Vertex Network),簡稱AOV網。
例如:計算機專業課學習流程
為保證流程可執行,AOV網中不應該出現迴路。
拓撲排序
拓撲序列:設G=(V,E)是一個具有n個頂點的有向圖,V中的頂點序列v1,v2,…,vn,滿足若從頂點vi到vj有一條路徑,則在頂點序列中頂點vi必在頂點vj之前
拓撲排序:構造拓撲序列的過程
拓撲排序方法:
-
從AOV網中選擇一個沒有前驅的頂點,並輸出;
-
從AOV網中去掉該頂點以及以該頂點為出發點的所有邊;
-
重複上述過程,直到AOV網中的不存在入度為0的頂點。
判斷有無迴路:
完成3後,如果AOV網中還有頂點,說明有迴路;反之,說明所有頂點都被輸出,即沒有迴路。
例如:(紅圈表示當前刪除頂點)
演算法
儲存結構——鄰接表
typedef struct AOVedge{
int adj; //該邊的終止頂點在頂點結點中的位置
int weight; //邊的權值
struct AOVedge *next; //指向下一個邊結點
}AELink;
typedef struct AOVver{
int indegree; //頂點的入度
int vertex; //頂點資訊
AELink *link; //指向第一個邊結點
}TOPOVLink;
程式碼實現
void TOPO_sort(TOPOVLink G[],int n,int V[]) //G[]為頂點結點陣列,n為頂點個數,V[]為存放拓撲序列的陣列
{
AELink *p;
int i,j,k,top=-1;
for(i=0;i<n;i++) //棧初始化:將原圖入度為0的頂點進棧
{
if(G[i].indegree==0)
{
G[i].indegree=top; //用陣列實現連結串列功能
top=i; //top是當前入度為0的下標,G[top].indegree是前一個下標
}
}
for(i=0;i<n;i++)
{
if(top==-1) //top==-1本該在n個結點輸出後再出現,但提前了,說明圖中還剩結點但入度均非0
{
printf("\n網中存在迴路!\n");
break;
}
else //如果一直走這條支路,沒走if,說明n個結點依次被輸出,不存在迴路
{
j=top;
top=G[top].indegree; //退出棧頂元素
V[i]=G[j].vertex; //輸出一個頂點的資訊
p=G[j].link;
while(p!=NULL) //“刪除”邊結點,並尋找新的入度為0的點
{
k=p->adj;
G[k].indegree--; //已進棧說明入度為0,此步不會修改棧中頂點的indegree
if(G[k].indegree==0)
{
G[k].indegree=top;
top=k;
}
p=p->next;
}
}
}
}
演算法分析
設AOV網中有n個頂點,e條邊。初始化迴圈時間為O(n),出棧共n次,對每個頂點的邊進行刪除共進行e次,從而演算法時間複雜度為O(e+n)。