关于邻接表的拓扑排序

算法思想如下:

利用邻接表存储图,先设一个辅助数组indegree[]来计算所有节点的入度;首先把入度为零的节点入栈,当栈不为空时,把栈中的元素出栈,然后删除输出元素为弧尾的所有弧,并判断相应节点的入度是否为零,为零,则压入栈中。重复执行,直到栈空。

 

#include <stdio.h>
#include <stdlib.h>
#define MAX 30

int indegree[MAX];//用来存储所有节点的入度之和

typedef struct ArcNode{
	struct ArcNode *nextarc;
	int adjvex;
}ArcNode;
typedef struct{
	ArcNode *firstarc;
	char data;
}VNode,Vertice[MAX];
typedef struct{
	int vexnum,arcnum;
	Vertice vex;
}ALGraph;
typedef struct{
	int top;
	int *base;
	int stacksize;
}SqStack;

int LocateVex(ALGraph G, char v){
	for(int i = 0; i < G.vexnum; i ++){
		if(v == G.vex[i].data)
			return i;
	}

	return -1;
}

void CreateALGraph(ALGraph &G){
	int i,j,k;
	char v1[3],v2[3];
	ArcNode *p,*s;

	printf("输入节点和边的数目:\n");
	scanf("%d%d",&G.vexnum,&G.arcnum);

	printf("输入结点:\n");
	for(i = 0; i < G.vexnum; i ++){
		scanf("%s",v1);
		G.vex[i].data = v1[0];
		G.vex[i].firstarc = NULL;
	}

	printf("输入各条边:\n");
	for(i = 0; i < G.arcnum; i ++){
		scanf("%s%s",&v1,&v2);

		j = LocateVex(G,v1[0]);	k = LocateVex(G,v2[0]);
		s = (ArcNode *)malloc(sizeof(ArcNode));
		s->adjvex = k;		s->nextarc = NULL;


		if(!G.vex[j].firstarc){
			G.vex[j].firstarc = s;
		}
		else{
			p = G.vex[j].firstarc;

			while(p->nextarc)
				p = p->nextarc;

			p->nextarc = s;
		}
	}
}

void FindInputDgeree(ALGraph G){//计算所有节点的入度
	ArcNode *p;
	int i;

	for(i = 0; i < G.vexnum; i ++)
		indegree[i] = 0;

	for(i = 0; i < G.vexnum; i ++){
		p = G.vex[i].firstarc;

		while(p){
			indegree[p->adjvex] ++;
			p = p->nextarc;
		}
	}
}

void InitStack(SqStack &S){
	S.base = (int *)malloc(sizeof(int) * MAX);

	if(!S.base)
		return ;

	S.top = 0;
	S.stacksize = MAX;
}

void Push(SqStack &S, int i){
	if(S.top >= S.stacksize){
		S.base = (int *)realloc(S.base,(S.top + MAX) * sizeof(int));

		if(!S.base)
			return ;

		S.stacksize += MAX;
	}

	S.base[S.top ++] = i;
}

int StackEmpty(SqStack S){
	if(!S.top )
		return 1;

	return 0;
}

void Pop(SqStack &S, int &i){
	if(!S.top)
		return;

	i = S.base[-- S.top];
}

void TopologicalSort(ALGraph G){
	FindInputDgeree(G);
	int count = 0,i;
	SqStack S;		ArcNode *p;
	InitStack(S);

	for(i = 0; i < G.vexnum; i ++)
		if(!indegree[i])//把入度为零的节点入栈
			Push(S,i);

	printf("拓扑序列如下:\n");
	while(!StackEmpty(S)){
		Pop(S,i);
		printf("%c",G.vex[i].data);	count ++;

		p = G.vex[i].firstarc;

		while(p){
			if(!(-- indegree[p->adjvex]))//判断去掉一条边后节点的入度是否为零
				Push(S,p->adjvex);

			p = p->nextarc;
		}
		if(!StackEmpty(S)) printf("-->");
	}

	if(count < G.vexnum)
		printf("该图为有向有环图");
    printf("\n");
}

int main(){
	ALGraph G;

	CreateALGraph(G);//建立图

	TopologicalSort(G);//进行拓扑排序

	return 0;
}

 

 

 

 

 

    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/i1020/article/details/53206833
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞