示例#1
0
// 算法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;
}