对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若<u,v> ∈E(G),则u在线性序列中出现在v之前
【例】对如上学生选课工程图进行拓扑排序, 得到的拓扑有序序列为
C1 , C2 , C3 , C4 , C5 , C6 , C8 , C9 , C7
或 C1 , C8 , C9 , C2 , C5 , C3 , C4 , C7 , C6
下面为拓扑排序的C代码
typedef struct Gnode{ /*邻接表的表节点类型*/
int adjvex; /*邻接顶点编号*/
int weight; /*弧上的权值*/
struct Gnode *nextarc; /*指示下一个弧的节点*/
}Gnode
typedef struct Adjlist { /*邻接表的头节点类型*/
char vdata; /*顶点的数据信息*/
struct Gnode *Firstadj; /*指向下一个弧的第一个表节点*/
}Adjlist;
typedef struct LinkedWDigraph{ /*图的类型*/
int n,e; /*图中顶点个数和边数*/
struct Adjlist *head; /*指向图中第一个顶点的邻接表的头节点*/
}LinkedWDigraph;
int Toplogical(LinkedWDigraph G)
{
Gnode *p;
int j,w,top=0;
int *Stack,*ve,*indegree;
ve=(int *)malloc((G.n+1)*sizeof(int));
indegree=(int *)malloc((G.n+1)*sizeof(int)); /*存储网中各顶点的入度*/
Stack=(int *)malloc((G.n+1)*sizeof(int)); /*存储入度为0的顶点的编号*/
if (!ve || !indegree || !Stack) exit(0);
for (j=1;j<=G.n;j++) {
ve[j]=0; indegree[j]=0;
} /*for*/
for (j=1;j<=G.n;j++) { /*求网中各顶点的入度*/
p=G.head[j].Firstadj;
while(p) {
indegree[p->adjvex]++]; p=p->nextarc;
} /*while*/
}
for (j=1;j<G.n;j++) /*求网中入度为0的顶点并保存其编号*/
if (!indegree[j]) Stack[++top]=j;
while (top>0) {
w=Stack[top--];
printf("%c ",G.head[w].vdata);
p=G.head[w].Firstadj;
while (p){
indegree[p->adjvex]--;
if (!indegree[p->adjvex])
Stack[++top]=p->adjvex;
if (ve[p->adjvex<ve[w]+p->weight)
ve[p->adjvex]=ve[w]+p->weight;
p=p->nextarc;
}
}
return ve[w];
}