// 算法7.13 P185 // 有向网G采用邻接表存储结构,求各顶点事件的最早发生时间ve(全局变量)。 // T为拓扑序列顶点栈,S为零入度顶点栈。 // 若G无回路,则用栈T返回G的一个拓扑排序列,并函数值返回1,否则返回0 int topologicalOrder(ALGraph G,SqStack *T){ int j,k,count,indegree[MAX_VERTEX_NUM]; SqStack S; ArcNode *p; findInDegree(G,indegree);//对各顶点入度indegree[0..vernum-1] initStack(&S);//初始化栈 for(j=0;j<G.vexnum;j++){//建零入度顶点栈S if(!indegree[j]) push(&S,j);//入度为0者进栈 } initStack(T);//初始化拓扑序列顶点栈 count = 0;//对输出顶点计数 for(j=0;j<G.vexnum;j++){//初始化ve[]=0(最小值) vearly[j] = 0; } printf("topological sort:\n"); while(!stackEmpty(S)){ // 栈不空 pop(&S,&j); printf("%s ",G.vertices[j].data);//输出i号顶点并计数 push(T,j);//j号顶点入T栈并计数 count++;//顶点计数 for(p=G.vertices[j].firstarc;p;p=p->nextarc){ // 对j号顶点的每个邻接点的入度减1 k = p->adjvex;//弧头顶点 // 若入度减为0,则入栈 if(!(--indegree[k])) push(&S,k); // 如果弧尾最早开始时间+持续时间大于弧头开始时间 if(vearly[j]+*(p->info)>vearly[k]) vearly[k] = vearly[j]+*(p->info); } } if(count<G.vexnum){ // 此有向图有回路 printf("\nThis directed graph has contour.\n\n"); return 0; }else{ printf("\nThis is topological list.\n\n"); return 1; } }
//如有向图无回路,则输出G的顶点的一个拓扑序列并返回OK,否则返回ERROR status toplogicalSort(ALGraph G){ //先初始化各个顶点的入度 findInDegree(G, indegree); int stack[MAX_VERTEX_NUM];//维护一个栈来存放入度为0的顶点,当栈为空时,则说明图中不存在无前驱的顶点了(即没有入度为0的顶点了),说明图中无环 //否则如果此时仍然存在顶点,而且这些顶点有前驱,则说明有环 int top = 0;//栈顶指针 //将入度为0的顶点入栈 for(int i = 0; i < G.vexnum; i++){ if(!indegree[i]){ stack[top++] = i; } } int count = 0;//对输出的顶点计数 ArcNode *p; while(top != 0){//栈不为空 int topElemVex_i = stack[--top];//栈顶元素出栈,即第一个无前驱的顶点 printf("v%d ", G.vexs[topElemVex_i].data);//输出当前结点 count++; //去掉以该结点为前驱的点与他的弧,以将相关顶点的入度减1的操作来实现 for(p = G.vexs[topElemVex_i].firstarc; p; p = p->nextarc){ indegree[p->adjvex]--; if(!indegree[p->adjvex]){ stack[top++] = p->adjvex;//入度为0者入栈 } } } printf("\n"); if(count < G.vexnum)//该有向图有回路 return ERROR; else return OK; }