C语言 图的拓扑排序

一、拓扑排序的概念

对于一个AOV网,我们通常需要把它的所有顶点排成一个满足下述关系的线性序列V1,V2,····,V(n).如果AOV网中从顶点Vi到顶点Vj有一条路径,则在该线性序列中顶点Vi必在顶点Vj之前。满足这种关系的序列成为拓扑排序。

对AOV网构造拓扑序列的操作成为拓扑排序,即将AOV网中各个顶点排列成一个有序序列,使得所有前驱和后继关系能够得到满足。拓扑排序是对非线性结构的有向图进行线性化的重要手段。需要注意的是,只有不存在回路的AOV网才能排成拓扑序列。如果存在有向回路,可以比喻成某项活动的开工是以自己工作的完成为先决条件的,显然是不对的。

例如:

 如图所示的有向图才能进行拓扑排序。

二、算法思路

对AOV网进行拓扑排序的基本思路是:从AOV网中选择一个入度为0的顶点输出,然后删除该顶点,并删除以此顶点为尾的弧,继续重复这个步骤,直到输出全部顶点或者AOV网中不存在入度为0的顶点为止。

上图的拓扑排序过程为:

        

 为了实现拓扑排序,需要删除结点,用邻接表会比较方便,考虑到排序过程中始终要查找入度为0的顶点,我们可以给结点结构增加一个入度域inDegree,

 整体代码:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #define MAXVEX 20
 4 #define OK 1
 5 #define ERROR -1
 6 typedef struct EdgeNode{
 7     int adjvex;//邻接点域,存储该顶点对应下标 
 8     int weight;//存储权值 
 9     struct EdgeNode *next;//指向下一个邻接点 
10 }EdgeNode;
11 typedef struct VertexNode{
12     int inDegree;//顶点入度 
13     int data;//顶点域,存储顶点信息 
14     EdgeNode *headEge;//边表头指针 
15 }VertexNode,AdjList[MAXVEX];
16 typedef struct{
17     AdjList adjList; 
18     int numVertexes,numEdges;//当前顶点数和边数 
19 }graphAdjList,*GraphAdjList;
20 void CreateAlGraph(graphAdjList    *G){
21     int i,j,k;
22     EdgeNode *s1,*s2;
23     printf("请输入顶点数和边数:\n");
24     scanf("%d,%d",&G->numVertexes,&G->numEdges);
25     for(i=0;i<G->numVertexes;i++){
26         scanf("%d",&G->adjList[i].data);
27         G->adjList[i].inDegree=0;
28         G->adjList[i].headEge=NULL;
29     }
30     for(k=0;k<G->numEdges;k++){
31         printf("输入边(vi,vj)的顶点序号:");
32         scanf("%d,%d",&i,&j);
33         s1=(EdgeNode *)malloc(sizeof(EdgeNode));
34         s1->adjvex=j;
35         s1->next=G->adjList[i].headEge;
36         G->adjList[i].headEge=s1;
37         G->adjList[j].inDegree++; 
38     }
39 } 
40 
41 int TopologicalSort(graphAdjList *GL){
42     EdgeNode *e;
43     int i,k,gettop;
44     int top=0;
45     int count=0;
46     int *stack;
47     stack=(int *)malloc(GL->numVertexes*sizeof(int));
48     for(i=0;i<GL->numVertexes;i++)
49         if(GL->adjList[i].inDegree==0)
50             stack[++top]=i;//top的值先加一再进行运算 
51     while(top!=0){
52         gettop=stack[top--];//先进行运算top的值再减一 
53         printf("%d->",GL->adjList[gettop].data);
54         count++;
55         for(e=GL->adjList[gettop].headEge;e;e=e->next){
56             k=e->adjvex;
57             if(!(--GL->adjList[k].inDegree))//入度减一,若为0则入栈 
58                 stack[++top]=k;
59         }
60     } 
61     printf("\n");
62     if(count<GL->numVertexes)
63         return ERROR;
64     else return OK;
65 }
66 int main(){
67     graphAdjList G;
68     CreateAlGraph(&G);
69     printf("------输出拓扑排序:");
70     TopologicalSort(&G);
71     return 0;
72 }

测试结果:

 

如有问题, 欢迎交流呀!!

 

 

posted @ 2021-12-02 15:17  旺旺哈  阅读(329)  评论(0)    收藏  举报