拓扑排序:是对有向无圈图的顶点的一种排序。它使得如果存在一条从vi到vj的路径,那么vi在排序中必须在vj的前面。
思路:一个简单的求拓扑排序的算法是先找出任意一个没有入边的顶点,然后我们显示出该顶点,并将它和它的边一起从图中删除。对图的其余部分应用同样的方法处理。
实现过程:把顶点v的入度(indegree)定义为边(u,v)的条数,计算图中所有顶点的入度,记录在Indegree数组中。
建立队列,扫描该数组,将入度为0的顶点,入队列。
当队列不为空的时候,删除队列中的顶点v,同时删除顶点v到其它顶点的边,并将其它顶点的入度减1,
如果入度减1后,为0,则加入队列,重复以上过程,直到队列为空。
void topSort(Graph G,int TopOrder[]) {
//G为图,TopOrder为记录排序的数组
linkQueue Q; //创建队列
ptrNode p;
int Indegree[MAXVERTEX]; //记录入度个数的数组
int cut = 0; //记录已排序顶点的个数
int i;
Q = createQueue(); //创建队列
//初始化记录入度节点
for (i = 0; i < G->Nv; i++)
{
Indegree[i] = 0;
}
//计算各个顶点入度的个数
for (i = 0; i < G->Nv; i++) {
for (p = G->G[i].first; p; p = p->next) {
Indegree[p->v]++;
}
}
for (i = 0; i < G->Nv; i++) {
//将入度为0的顶点加入队列
if (Indegree[i] == 0) {
EeueueQueue(i, Q);
}
}
while (!IsEmpty(Q)) {
i = frontAndDeueue(Q); //出队列并获取队列的首元素
for (p = G->G[i].first; p; p = p->next) {
//将与该顶点邻接的入度减1;
--Indegree[p->v];
if (Indegree[p->v]==0) {
EeueueQueue(p->v, Q);
}
}
TopOrder[cut++] = i;
}
if (cut==G->Nv) {
printf("拓扑排序成功\n");
for (i = 0; i < cut; i++)
printf("%d ", TopOrder[i]);
}
else {
printf("存在回路,拓扑排序失败\n");
}
}