对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中全部顶点排成一个线性序列,
使得图中随意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出如今v之前。
通常,这种线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。
简单的说。由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序.
步骤:
由AOV网构造拓扑序列的拓扑排序算法主要是循环运行下面两步,直到不存在入度为0的顶点为止。
(1) 选择一个入度为0的顶点并输出之。
(2) 从网中删除此顶点及全部出边。
循环结束后,若输出的顶点数小于网中的顶点数。则输出“有回路”信息,否则输出的顶点序列就是一种拓扑序列.
代码段例如以下:
//拓扑排序图AOE代码段 //杨鑫 /* *在一个表示project的有向图。用顶点表示活动,用弧表示活动之间的优先关系, *这种有向图为顶点表示活动的网。我们称为AOV(Activity On Vertex Network) * */ //边表结点 #define MAXVEX 1000 typedef struct EdgeNode { int adjvex; //邻接点域。存储该顶点相应的下标 int weight; //用于存储权值,对于非网图能够不须要 struct EdgeNode *next; //链域。指向下一个邻接点 }EdgeNode; //顶点表结点 typedef struct VertexNode { int in; //顶点的入度 int data; //顶点域,存储顶点信息 EdgeNode *firstedge; //边表头指针 }VertexNode, AdjList[MAXVEX]; typedef struct { AdjList adjList; int numVertexes, numEdges; //图中当前的顶点数和边数 }graphAdjList, *GraphAdjList; //此处还应该定义一个栈来存储入度为0的顶点。目的是为了避免每次查找都要去遍历顶点表 //找有没有入度为0的顶点 //拓扑排序。若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; //将K号顶点的邻接点的入度减1 if(!(--GL->adjList[k].in)) { stack[++top] = k; //若为0则入栈,以方便下次循环输出 } } } if(count < GL->numVertexes) //假设count小于顶点数,说明存在环 return ERROR; else return OK; }