C语言实现有向无环图的拓扑排序算法

对AOV网进行拓扑排序的基本思路是:从AOV网中选择一个入度为0的顶点输出,然后删除此顶点,并删除以此顶点为尾的弧,继续重复此步骤,直到输出全部顶点或者在AOV网中不存在入度为0的顶点为止。

这里图使用的数据结构是邻接表,并且在顶点表加入顶点入度一项。

以下程序在DEV C++中编译运行通过。

#include 
#include 
#define MAXVEX 20

typedef struct EdgeNode
{
	int adjvex;//邻接点域,存储该顶点对应的下标 
	struct EdgeNode *next;//链域,指向下一个邻接点 
}EdgeNode;
typedef struct VertexNode
{
	int in;//顶点入度
	char data;//顶点域,存储顶点信息
	EdgeNode *firstedge;//边表头指针 
}VertexNode,AdjList[MAXVEX];
typedef struct
{
	AdjList adjList;
	int numVertexes,numEdges;
}GraphAdjList;

void CreateALGraph(GraphAdjList *G)
{
	int i,j,k;
	EdgeNode *e;
	printf("输入顶点数和边数:\n");
	scanf("%d,%d",&G->numVertexes,&G->numEdges);
	getchar();
	for(i=0;inumVertexes;i++)
	{
		printf("输入第%d个顶点的值和入度:\n",i+1);
		scanf("%c,%d",&G->adjList[i].data,&G->adjList[i].in);
		G->adjList[i].firstedge=NULL;
		getchar();
	}	
	for(k=0;knumEdges;k++)
	{
		printf("输入第%d条有向边(vi,vj)上的顶点序号:\n",k+1);
		scanf("%d,%d",&i,&j);
		e=(EdgeNode*)malloc(sizeof(EdgeNode));
		e->adjvex=j;
		e->next=G->adjList[i].firstedge;
		G->adjList[i].firstedge=e;
	}
}

int TopologicalSort(GraphAdjList *G)
{
	EdgeNode *e;
	int i,k,gettop;
	int top=0;//用于栈指针下标
	int count=0;//用于统计输出顶点的个数
	int *Stack;//建栈存储入度为0的指针
	Stack=(int*)malloc(G->numVertexes*sizeof(int));
	for(i=0;inumVertexes;i++)
	{
		if(G->adjList[i].in==0)
			Stack[++top]=i;//将入度为0的顶点的序号入栈 
	 } 
	 while(top!=0)
	 {
	 	gettop=Stack[top--];
	 	printf("%c->",G->adjList[gettop].data);
	 	count++;
	 	for(e=G->adjList[gettop].firstedge;e;e=e->next)
	 	{
	 		//对此顶点的弧表进行遍历
			 k=e->adjvex;//邻接点的序号
			 if(!(--G->adjList[k].in))
			 	Stack[++top]=k; 
		 }
	 }
	 if(countnumVertexes)
	 	return -1;
	else 
		return 0;
}

void main()
{
	GraphAdjList G;
	int flag;
	CreateALGraph(&G);
	flag=TopologicalSort(&G);
	if(flag==-1)
		printf("该有向图存在环,构造拓扑序列失败!\n");
	else if(flag==0)
		printf("构造拓扑序列成功!\n");
	
}

运行结果如图所示。


C语言实现有向无环图的拓扑排序算法_第1张图片

C语言实现有向无环图的拓扑排序算法_第2张图片

求出的结果不是唯一的拓扑排序方案。

整个算法的时间复杂度为O(n+e),n是顶点数,e是边数。

你可能感兴趣的:(数据结构和算法)