在一个没有回路的有向图中,用顶点表示活动,用弧表示活动间的优先关系,这样的有向图称为顶点表示活动的网,简称AOV网(Activity On Vertex Network)。若图中任意两个顶点vi到顶点vj有一条路径,且在序列中vi排在vj之前,称(v’1,v’2,…,v’i,…,v’n)为AOV网的一个拓扑序列,给出拓扑序列的过程叫拓扑排序,它是确定事件的进程。下面用c语言实现拓扑排序。
#include"stdio.h"
#include"stdlib.h"
#define M 20
typedef char vertextype;
typedef struct node //边结点类型定义
{
int adjvex;
struct node *next;
}EdgeNode;
typedef struct //带顶点入度的头结点定义
{
EdgeNode *firstedge;
vertextype vertex;
int id; //顶点的入度域
}VertexNode;
typedef struct //AOV网的邻接表结构
{
VertexNode adjlist[M];
int n,e; //图的顶点数与边数
}AovGraph;
void creataov(AovGraph *g) //建立AOV网的邻接表
{
int i,j,k;
EdgeNode *s;
printf("输入图的顶点数与边数:");
scanf("%d%d",&g->n,&g->e);
printf("输入顶点及顶点的入度\n");
for(i=0;i<g->n;i++)
{
scanf("%ls%d",&g->adjlist[i].vertex,&g->adjlist[i].id);
g->adjlist[i].firstedge=NULL;
}
printf("输入有序对\n");
for(k=0;k<g->e;k++)
{
scanf("%d%d",&i,&j);
s=(EdgeNode*)malloc(sizeof(EdgeNode));
s->adjvex=j;
s->next=g->adjlist[i].firstedge;
g->adjlist[i].firstedge=s;
}
}
void TopSort(Aovgraph g) //AOV网拓扑排序
{
int i,j,v,flag[M],queue[M],rear,front;
EdgeNode *p;
front=rear=0; //初始化空队列
for(i=0;i<g.n;i++)
flag[i]=0; //初始化访问标记
for(i=0;i<g.n;i++) //入度为0的结点进队
{
if(g.adjlist[i].id==0&&flag[i]==0)
{
queue[rear++]=i;
flag[i]=1;
}
}
printf("输出AOV网的拓扑序列:");
while(front<rear) //队列不为空
{
v=queue[front++]; //队首元出队
printf("%c ",g.adjlist[v].vertex);
p=g.adjlist[v].firstedge;
while(p) //所有与v邻接的顶点的入度减1
{
j=p->adjvex;
if(--g.adjlist[j].id==0&&flag[j]==0) //入度为0则进队
{
queue[rear++]=j;
flag[j]=1;
}
p=p->next;
}
}
}
int main()
{
AovGraph ag;
printf("创建一个AOV网的邻接表\n");
creataov(&ag);
TopSort(ag);
return 0;
}
以下是程序运行的结果:要注意输入顶点及有序对的顺序,按照其邻接表来进行输入
A B C D E F G H I对应的编号为0 1 2 3 4 5 6 7 8