拓撲排序

1.AOV網測試

  若是用圖中的頂點表示活動,邊表示活動之間的前後關係,好比從頂點Vi到Vj之間存在有向邊<Vi,Vj>,則表示活動活動Vi必須在活動Vj以前進行,這樣用弧表示優先關係的有向圖稱爲頂點表示活動的網(Activity On Vertex NetWork),簡稱AOV網。ui

  以下圖:編碼

  

  

  說明:AOV網中不含迴路,由於存在迴路意味着某項活動應以本身爲先決條件,顯然這是荒謬的。你想嘛,一件事必須等該件事作完了纔開始作,那這件事到底何時作呢?答案是無窮無盡的等待,死循環。spa

2.拓撲排序code

  對於一個AOV網,其全部頂點能夠排成一個線性序列Vi1,Vi2,Vi3,...,Vin,該線性序列具備如下性質:若是在AOV網中,從頂點Vi到頂點Vj存在一條路徑,則在該序列中頂點Vi必定排在頂點Vj以前,具備這種性質的線性序列稱爲拓撲序列,構造拓撲序列的操做稱之爲拓撲排序。blog

  那麼如何進行拓撲排序呢?排序

  ①在有向圖中選取一個沒有前驅的頂點並輸出ci

  ②從圖中刪除該頂點和全部以它爲尾的弧get

 

 
 AOV網,初始狀態
                              輸出V1以後
                      輸出V2以後
                 輸出V3以後(V3和V4都知足入度爲零的條件,因此先選哪一個都不要緊)
                             輸出V4以後

 

  

3.編碼實現it

  採用鄰接表存儲有向圖:

  arcNode結構體存儲爲以adjvex爲弧頭的弧的相關信息

  vNode存儲節點信息並指向第一個出邊

  topoSequence存儲拓撲排序中輸出的頂點

  findIndegree查找全部頂點的入度:從第0號位置開始查找,遇到以adjvex爲弧頭的弧對應的indegree就加一,這樣查找完後,indegree中就記錄了每一個頂點的入讀

  topologicalSort進行拓撲排序

  

  

#include<stdio.h>
#include<stdlib.h>
typedef struct _arcNode
{
    int adjvex;
    int weight;
    struct _arcNode *nextarc;
}arcNode;
typedef struct  _vNode
{
    char data;
    arcNode *firstarc;
}vNode;
#define  MaxVertexNum 100
typedef vNode adjList[MaxVertexNum];
typedef struct _adjGraph
{
    adjList ver;
    int e, n;
}adjGraph;
void createAdjGraph(adjGraph *G)
{
    scanf("%d,%d", &G->n, &G->e);
    getchar();
    for (int i = 0; i < G->n; i++)
    {
        scanf("%c ", &G->ver[i].data);
        G->ver[i].firstarc = NULL;
    }
    int a, b, w;
    for (int i = 0; i < G->e; i++)
    {
        scanf("%d,%d,%d", &a, &b, &w);
        arcNode *tmp = (arcNode*)malloc(sizeof(arcNode));
        tmp->weight = w;
        if (G->ver[a].firstarc == NULL)
        {
            tmp->adjvex = b;
            tmp->nextarc = NULL;
            G->ver[a].firstarc = tmp;
        }
        else
        {
            tmp->adjvex = b;
            tmp->nextarc = G->ver[a].firstarc;
            G->ver[a].firstarc = tmp;
        }
    }
}
typedef struct  _topoSequenceS
{
    char data[MaxVertexNum];
    int top;
}topoSequenceS;
topoSequenceS *topoS = (topoSequenceS*)malloc(sizeof(topoSequenceS));
void findInDegree(adjGraph *G, int *indegree)
{
    for (int i = 0; i < G->n; i++)
    {
        arcNode *arcPos = G->ver[i].firstarc;
        while (arcPos != NULL)
        {
            indegree[arcPos->adjvex] += 1;
            arcPos = arcPos->nextarc;
        }
    }
}
void topologicalSort(adjGraph *G)
{
    int *indegree = (int*)malloc(sizeof(int)*G->n);
    for (int i = 0; i < G->n; i++)
        indegree[i] = 0;
    findInDegree(G, indegree);
    int *tmpS = (int*)malloc(sizeof(int)*G->n);
    int top = -1;
    for (int i = 0; i < G->n; i++)
    {
        if (!indegree[i])tmpS[++top] = i;
    }
    topoS->top = -1;
    int i = 0;
    while (top != -1)
    {
        i=topoS->data[++topoS->top] = tmpS[top--];
        arcNode *arcPos = G->ver[i].firstarc;
        while (arcPos != NULL)
        {
            if (!(--indegree[arcPos->adjvex]))tmpS[++top] = arcPos->adjvex;
            arcPos = arcPos->nextarc;
        }
    }
}
#include<conio.h>
int main(void)
{
    freopen(".\\in.txt", "r", stdin);
    adjGraph *G = (adjGraph*)malloc(sizeof(adjGraph));

    createAdjGraph(G);
    fclose(stdin);
    for (int i = 0; i < G->n; i++)
    {
        printf("%c->", G->ver[i].data);
        arcNode *pos = G->ver[i].firstarc;
        while (pos != NULL)
        {
            printf("%c->", G->ver[pos->adjvex].data);
            pos = pos->nextarc;
        }
        printf("\n");
    }
    topologicalSort(G);
    if (topoS->top < G->n - 1)
        printf("Error!There is a circuit!\n");
    else
    {
        int vexNum = 0;
        int pos = 0;
        while (topoS->top != pos-1)
        {
            vexNum = topoS->data[pos];
            printf("%c\n", G->ver[vexNum].data);
            pos++;
        }
    }
    getch();
    return 0;
}

  

  測試文本in.txt:

5,5
A B C D E
0,1,1
1,2,2
1,3,3
2,4,4
3,4,5

測試結果:

  

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息