有向无环图之拓扑排序

                 **有向无环图之拓扑排序**

一.
偏序:若集合X上的关系R是自反的,反对称的和传递的,则称R是集合X上的偏序关系。
全序:设R是集合X上的偏序,如果对每个x,y属于X,必有xRy或yRx,则称R是集合X上的全序关系。
二.
拓扑排序:
简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序,由偏序定义得到拓扑有序的操作便是拓扑排序。其实就是人为的把不属于偏序关系的相关顶点变成属于偏序关系的,就变成全序了。
如图:
a->b
c->d
加上一条弧 b->c,就变成全序的了
三.
AOV网:用顶点表示活动,用弧表示活动时间的优先关系的有向图称为顶点表示活动的网(Activity On Vertex Network),简称AOV-网.
四.
AOV-网的应用:一个软件专业的学生必须学习一系列基本课程,其中有些课程是基础课,它独立于其他课程,如《高等数学》,而另外一些课程必须在学完作为它的基础的先修课才能开始,如在《离散数学》
学完之前就不能开始学习《数据结构》。这些先决条件定义了课程之间的领先(优先)关系。这个关系就可以用AOV-网来表示。AOV-网中不能有环,否则有死循环了。
五.
拓扑排序的应用:
检测一个AOV-网是否有环,就使用拓扑有序序列,若网中的所有顶点都在它的拓扑有序序列中,则该AOV-网必定不存在环。
原因:人为的把不属于偏序关系的顶点变成属于偏序关系的,图就变成全序关系的。而偏序具有自反的,反对称的和传递的,假设R是偏序,就是某个a课程领先于另外一个b课程的关系,有一个课程x,
它的子孙有到x顶点的回路,有传递性可知,那么就有xRx,x领先于x,显然相矛盾,所以这个回路上的顶点都不属于偏序R,所以在AOV-网的拓扑有序序列中就不会有这些顶点, 那么就少于该有向图的顶点数,就说明有环。
六.
如何进行拓扑排序:
1 在有向图中选一个没有前驱的顶点且输出之
2 从图中删除该顶点和所有以它为尾的弧
重复上述两步,直至全部顶点均已输出,或者当前图中不存在没有前驱的顶点为止(这一种情况说明有向图有环)
七.
例图:
这里写图片描述
八.
代码:

void tpcSort(struct Graph g){
    int i,j,k,count=0;
    struct ArcNode * p;
    struct sqstack s;
    /*这个栈的作用是存放入度为0的顶点,可以避免重复检测入度为0的顶点*/
    struct ArcNode * getNextArc(struct ArcNode * p);
    initStack(&s);
    for(i=0;i<g.vexnum;i++){
        if(indegree[i]==0) push(&s, i);
        /*把入度为0的顶点放入栈中,需要找入度为0的顶点时可以直接去栈中取*/
    }
    while(!stackEmpty(&s)){
        j=pop(&s);//取出入度为0的顶点
        printf("%c\t",g.verts[j].info);/*把这个顶点拿出来打印出来*/
        count++;//计算入度为0的顶点的个数
        for(p=g.verts[j].firstarc;p!=NULL;p=getNextArc(p)){
            k=p->adjvex;
            if(--indegree[k]<=0) push(&s, k);
            /*把和该顶点相邻的顶点的入度都减去1,这样可以间接实现删除以该顶点为尾的弧的操作,如果其邻接顶点的入度为0,就加入到栈中*/
        }
    }
    if(count<g.vexnum){
    /*count其实就代表拓扑有序序列中的顶点的个数*/
        printf("该有向图有环");
    }
}

完整源码:http://git@github.com:hglspace/Toplogincal.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值