设G={V,E}是一个具有 n 个顶点的有向图,V中的顶点序列 v1,v2,......,vn,满足若从顶点 vi 到 vj 有一条路径,则在顶点序列中顶点 vi 必在顶点 vj 之前。则称这样的顶点序列为一个拓扑序列。
在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,称为 AOV 网(Activity On Vertex Network)。
拓扑排序,其实就是对一个有向图构造拓扑序列的过程。构造时会有两个结果,如果此网的全部顶点都被输出,则说明它是不存在(回路)的 AOV 网;如果输出顶点数少了,哪怕是少了一个,也说明这个网存在环(回路),不是 AOV 网。
对 AOV 网进行拓扑排序的基本思路是:从 AOV 网中选择一个入度为 0 的顶点输出,然后删除此顶点,并删除以此顶点为尾的弧,继续重复此步骤,直到输出全部顶点或者 AOV 网中不存在入度为0的顶点为止。
具体代码如下:(代码虽然能输出正确答案,但会报错,我自己找不到原因.....还请大家多多指点。)
/*TopologicalSort.h头文件*/ /*用邻接表的方式建立有向图,并完成拓扑排序*/ #include<iostream> #define OK 1 #define ERROR 0 #define MAXVEX 100 typedef int Status; using namespace std; class EdgeNode{ /*边表结点*/ public: EdgeNode(){} ~EdgeNode(); int adjvex; /*邻接点域,存储该顶点对应的下标*/ int weight; /*用于存储权值,对于非网图可以不需要*/ class EdgeNode *next; /*链域,指向下一个邻接点*/ }; class VertexNode{ /*顶点表结点*/ public: VertexNode():in(0),data(0),firstedge(NULL){} ~VertexNode(); int in; /*顶点入度*/ int data; /*顶点域,存储顶点信息*/ EdgeNode *firstedge; /*边表头指针*/ }; class graphAdjList{ public: graphAdjList(){ for (int x=0;x<MAXVEX;x++) { adjList[x] = new VertexNode; } } ~graphAdjList(); VertexNode* adjList[MAXVEX]; int numVertexes,numEdges; /*图中当前顶点数和边数*/ }; void CreateALGraph(graphAdjList **G) /*建立图的邻接表结构*/ { int i,j,k; EdgeNode *e; cout<<"输入顶点数和边数:"<<endl; cin>>(*G)->numVertexes>>(*G)->numEdges; cin.clear(); for(i=0; i<(*G)->numVertexes; i++) { cout<<"输入各顶点信息:"<<endl; cin>>(*(*G)->adjList)[i].data; cin.clear(); (*(*G)->adjList)[i].firstedge = NULL; (*(*G)->adjList)[i].in = 0; } for(k=0; k<(*G)->numEdges; k++) { cout<<"输入边(vi,vj)上的顶点序号:"<<endl; cin>>i>>j; cin.clear(); ++(*(*G)->adjList)[j].in; e = new EdgeNode; e->adjvex = j; e->next = (*(*G)->adjList)[i].firstedge; (*(*G)->adjList)[i].firstedge = e; } } /*拓扑排序,若GL无回路,则输出拓扑排序序列并返回OK,若有回路返回ERROR*/ Status TopologicalSort(graphAdjList *GL) { EdgeNode *e; int i,k,gettop; int top = 0; /*用于栈指针下标*/ int count = 0; /*用于统计输出顶点的个数*/ int *stack = new int[GL->numVertexes]; /*建栈存储入度为0的顶点*/ for(i=0; i<GL->numVertexes; i++) if(0 == (*(GL->adjList))[i].in) stack[top++] = i; cout<<"拓扑排序为:"<<endl; while(0 != top) { gettop = stack[--top]; /*出栈*/ cout<<(*(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*/ stack[top++] = k; /*若为0则入栈,以便于下次循环输出*/ } } cout<<endl; delete[] stack; if (count < GL->numVertexes) /*如果count小于顶点数,说明存在环*/ { cout<<"存在环"<<endl; return ERROR; } else { cout<<"不存在环"<<endl; return OK; } }
对于如下的有向图:
运行结果如下:
但是同时还存在这样一个报错,请大家指点是为什么。。。。感激万分。