拓扑排序

拓扑排序只针对于有向无环图,它是所有结点的一个线性序列,确保如果有边(u,v),则结点u一定在v前面。

引理:有向图有环的充要条件是DFS存在back edge。

证明:充分性很好证明,当DFS存在back edge时,比如(v,u),又由于可以沿DFS找到u到v的路径,则找到一个环u=>...=>v=>u;

必要性证明,考虑有向图中的某个环u=>...=>v=>u,不失一般性可以假设DFS过程最先访问环中的结点u,则此时该环中的其他结点均没有被访问过,根据白色路径定理,可以知识环中的所有结点均是u的子孙结点,即v也是u的子孙结点,于是边(u,v)为back edge

 

拓扑排序的方法:对于有向无环图G,从任意结点开始DFS,并遍历所有结点,按照结点访问结束的时间顺序降序排列,便得到此有向无环图的拓扑排序。

证明:考虑G的任意一条边(u,v),分两种情况考虑

(1) 假设先访问结点u,则根据白色路径定理,v一定是u的子孙结点,于是DFS过程中结点v一定比u先结束。这种情况下得证

(2) 假设先访问结点v,由于图G没有环,故在结点v访问结点之前不可能访问到u,否则就找到一条从v到u的路径导致图G有环了,故也得证

 

22.4-3 求O(V)复杂度的算法,确定一个无向图中是否有环

只要对图进行DFS,看是否有backedge就可以确定是否有环了,但DFS的复杂度为O(E+V)。如果将复杂度降为O(V)呢?

于是变换一种思路,确定边数|E|和点数|V|的关系,如果|E|>= |V|,则图必有环,即清点边数,当其大于等于点数时停止,确定此图有环。当|E|<|V|时,再进行DFS确定是否有环,因此算法复杂度为O(V)。下面证明这个结论:如果|E| >= |V|,则无向图必有环

证明:无向无环图G,|E| < |V|,这是树的一种定义。无向无环图点数为|V|,则其最大边数|E| < |V|,边数最大时必定为连通图,否则可以添加一条边了。此时再添加任何一条边都会成环,即任意两点u,v,都是连通的。

使用数学归纳法,当|V|=1时显然;假设当|V|=n时成立;

当|V|=n+1时,找到这n+1个点中度数为1的点u,删除这个点和其相连的一条边,点数为n,根据归纳假设其边数为n-1,则|V|=n+1时,|E|=n。注意,无向无环连通图中一定有度数为1的点(|V|>1时),否则DFS过程中不可能所有边都是tree edge,即有back edge,即此图有环矛盾。

 

22.4-4 有向有环图中按照DFS进行拓扑排序获得的结点序列,是否保证最少的“坏边”?

不能保证最少的坏边,举例如下:A、B、C三点成环(A=>B=>C=>A),还存在一条边C=>B,从点A开始DFS,得到的拓扑序列为A BC,但其坏边有两条,分别是C=>A C=>B,有一个序列C A B,它的坏边只有一条,即B=>C

事实上如果有向有环图G中的所有环不相交,则DFS一定保证最少的坏边

 

22.4-5 拓扑排序的另一种方法

基本思路,取未处理结点中的入度为0的结点,总体复杂度为O(V+E),步骤如下:

(1) 处理所有结点,得到每个结点的入度数,并将入度为0的结点插入队列,O(V+E)

(2) 如果队列不空则输出一个结点,更新与此结点相关联的所有结点的入度数,注意将0入度的结点入队列,重复(2)这个过程直到链表为空。若链表空时还有未处理结点则表示图有环,否则为无环图同时输出的序列为拓扑排序序列。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值