拓扑排序

拓扑排序,对有向无圈图的顶点的一种排序,如果图中存在一条从顶点vi到vj的路径,那么在排序中vj必须出现vi后面,并且顶点都只出现一次。

度是指一个顶点所有与之相关联的边的数量。
入度是指以该顶点为终点的边的数量。
出度是指以该顶点为起点的边的数量。

在一个有向无圈图中,列出所有顶点的入度,找出一个入度为0的顶点,编号为1,然后删除图中所有以1号为起点的边。然后再找出一个入度为0的顶点,编号为2,重复上述步骤至图中没有顶点。
这个过程中有时会出现多个入度为0的顶点,这时算法可以继续下去,拓扑排序只要不违反上面两条原则就可以执行。
算法执行完毕,但是图中还有顶点没有输出,但是再也找不到入度为0的顶点了,这说明图中有环。(这不就是证明图中存在环么。。。)

实现是这样的,将所有还没有分配拓扑编号的入度为0的顶点放在队列中,在随后的执行过程中,队列不空,就推出队列的顶点,并编号它,然后将所有与它邻接的顶点的入度减1,只要某个顶点的入度减为0,就把他加入队列中。当最后实际编号的顶点数小于图的顶点数,就报告这个图有环。

void TopSort(Graph G,int TopNum[],int indegree[]) //图,拓扑排序结果,入度。
{
Queue Q;
int count=0; //编号计数
Vertex v,w; //顶点下标
AdjVNode M; //顶点

Q=MakeQueue(G->Nv);
MakeEmpty(Q);
for(i=0;i<G->Nv;i++)
{
    if (indegree[i]==0)
    {
        Enqueue(i,Q);
    }
}

while(!IsEmpty(Q))
{
    v=Dequeue(Q);
    TopNum[v]=++count;   //分配编号

    for(M=G->G[v].FirstEdge->Next;;M=M->Next)        //G-G[]是邻接表。
    {
        indegree[M->Adjv]--;         //M->Adjv是这个邻接点的下标
        if (indegree[M->Adjv]==0)
        {
            Enqueue(M->Adjv,Q);        //入度减为0的顶点进入队列
        }
    }
}

if(count!=G->Nv)
{
    printf("Graph has a cycle");
}
DisposeQueue(Q);         //删掉队列.

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值