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 }
测试结果:


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

浙公网安备 33010602011771号