AOV網與拓撲排序

Chase_Tsai發表於2024-05-25

AOV網的定義

以頂點表示活動,以有向邊表示活動之間的優先關係的有向圖稱為頂點表示活動的網(Activity On Vertex Network),簡稱AOV網

例如:計算機專業課學習流程

為保證流程可執行,AOV網中不應該出現迴路。

拓撲排序

拓撲序列:設G=(V,E)是一個具有n個頂點的有向圖,V中的頂點序列v1,v2,…,vn,滿足若從頂點vi到vj有一條路徑,則在頂點序列中頂點vi必在頂點vj之前

拓撲排序:構造拓撲序列的過程

拓撲排序方法

  1. 從AOV網中選擇一個沒有前驅的頂點,並輸出;

  2. 從AOV網中去掉該頂點以及以該頂點為出發點的所有邊;

  3. 重複上述過程,直到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)。

相關文章