圖的拓撲排序

1、概念

活動的網(AOV網):在一個表示工程的有向圖中,用頂點表示活動,用弧表示活動之間的優先關係,這樣的有向圖爲頂點表示活動的網,我們成爲AOV網(Activity On Vertext Network)。

AOV網中的弧表示活動之間存在的某種制約關係。

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

拓撲排序:就是對一個有向圖構造拓撲序列的過程。

2、應用範圍

拓撲排序常用來確定一個依賴關係集中,事物發生的順序。例如,在日常工作中,可能會將項目拆分成A、B、C、D四個子部分來完成,但A依賴於B和D,C依賴於D。爲了計算這個項目進行的順序,可對這個關係集進行拓撲排序,得出一個線性的序列,則排在前面的任務就是需要先完成的任務。

3、實現方法:

(1)從有向圖中選擇一個沒有前驅(即入度爲0)的頂點並且輸出它。

(2)從網中刪去該頂點,並且刪去從該頂點發出的全部有向邊。

(3)重複上述兩步,直到剩餘的網中不再存在沒有前趨的頂點爲止。

4、條件

圖使鄰接表存儲。

此時我們需要爲頂點表增加一個入度域in,表示入度個數。

5、code

/*頂點表結點*/
typedef struct VertexNode
{
    int in;    /*頂點入度*/
    int data;    /*頂點域,存儲頂點信息*/
    EdgeNode *firstedge;    /*邊表頭指針*/
}EdgeNode;


/*邊表結點*/
typedef struct EdgeNode
{
    int adjvex;    /*鄰接點域,存儲該頂點對應的下標*/
    int weight;    /*用於存儲權值,對於非網圖可以不需要*/
    struct EdgeNode *next;    /*鏈域,指向下一個鄰接點*/
}VertexNode,AdjList[MAXVEX];

typedef struct
{
    AdjList adjList;
    int numVertexes,numEdges;    /*圖中當前頂點數和邊數*/
}graphAdjList,*GraphAdjList;

/*拓撲排序,若GL無迴路,則輸出拓撲排序序列並返回OK,若有迴路返回ERROR*/
Status TopologicalSort(GraphAdjList GL)
{
    EdgeNode *e;
    int i,k,gettop;
    int top=0;    /*用於棧指針下標*/
    int count=0;    /*用於統計輸出頂點的個數*/
    int *stack;    /*建棧存儲入度爲0的頂點*/
    stack=(int *)malloc(GL->numVertexes * sizeof(int));
    for(i=0;i<GL->numVertexes;i++)
        if(GL->adjList[i].in==0)
            stack[++top]=i;    /*將入度爲0的頂點入棧*/
    while(top!=0)
    {
        gettop=stack[top--];    /*出棧*/
        printf("%d —> ",GL->adjList[gettop].data);    /*打印此頂點*/
        count++;    /*統計輸出頂點數*/
        for(e=GL->adjList[gettop].firstedge;e;e=e->next)
        {
            /*對此頂點弧表(邊表)進行遍歷*/
            k=e->adjvex;
            if(!(--GL->adjList[k].in))    /*將k頂點鄰接點的入度減1後值爲0,則入棧*/
                stack[++top]=k;
        }
    }
    if(count<GL->numVertexes)    /*如果count小於頂點數,說明存在環路*/
        return ERROR;
    else
        return OK;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章