图解:有向环、拓扑排序与Kosaraju算法

首先来看一下今天的内容大纲,内容非常多,主要是对算法思路与来源的讲解,图文并茂,希望对你有帮助~

1.有向图的概念和表示
概念

有向图与上一篇文章中的无向图相对,边是有方向的,每条边所连接的两个顶点都是一个有序对,它们的邻接性都是单向的。

一幅有方向的图(或有向图)是由一组顶点和一组有方向的边组成的,每条有方向的边都连接着一对有序的顶点。

其实在有向图的定义这里,我们没有很多要说明的,因为大家会觉得这种定义都是很自然的,但是我们要始终记得有方向这件事!
数据表示

我们依然使用邻接表存储有向图,其中v–>w表示为顶点v的邻接链表中包含一个顶点w。注意因为方向性,这里每条边只出现一次!

我们来看一下有向图的数据结构如何实现,下面给出了一份Digraph类(Directed Graph)

package Graph.Digraph;
import java.util.LinkedList;

public class Digraph{
private final int V;//顶点数目
private int E;//边的数目
private LinkedList adj[];//邻接表

public Digraph(int V){
    //创建邻接表
    //将所有链表初始化为空
    this.V=V;this.E=0;
    adj=new LinkedList[V];
    for(int v=0;v<V;++v){
        adj[v]=new LinkedList<>();
    }
}

public int V(){ return V;}//获取顶点数目
public int E(){ return E;}//获取边的数目

//注意,只有这里与无向图不同
public void addEdge(int v,int w){
    adj[v].add(w);//将w添加到v的链表中
    E++;
}

public Iterable<Integer> adj(int v){
    return adj[v];
}

//获取有向图的取反
public Digraph reverse(){
    Digraph R=new Digraph(V);
    for(int v=0;v<V;v++){
        for(int w:adj(V))
            R.addEdge(w, v);//改变加入的顺序
    }
    return R;
}

}

如果你已经掌握了无向图的数据表示,你会发现有向图只是改了个名字而已,只有两处需要注意的地方:addEdge(v,w)方法与reverse()方法。在添加一条边时因为有了方向,我们只需要在邻接表中增加一次;reverse()方法能够返回一幅图的取反(即每个方向都颠倒过来),它会在以后的应用中发挥作用,现在我们只要有个印象就行。
2.有向图的可达性

在无向图(上一篇文章)中,我们使用深度优先搜索可以找到一条路径,使用广度优先搜索可以找到两点间的最短路径。仔细想一下,它们是否对有向图适用呢?是的,同样的代码就可以完成这个任务,我们不需要做任何的改动(除了Graph换成Digraph)。

因为这些内容在上篇文章中都已经详细介绍过,所以就不展开了,有兴趣的话可以翻一下上篇文章,有详细的图示讲解。
3.环和有向无环图

我们在实际生活中可能会面临这样一个问题:优先级限制下的调度问题。说人话就是你需要做一些事情,比如A,B,C,但是做这三件事情有一定的顺序限制,做B之前必须完成A,做C之前必须完成B…………你的任务就是给出一个解决方案(如何安排各种事情的顺序),使得限制都不冲突。

如上图,第一种和第二种情况都比较好办,但是第三种?是不是哪里出了问题!!!

对于上面的调度问题,我们可以通过有向图来抽象,顶点表示任务,箭头的方向表示优先级。不难发现,只要有向图中存在有向环,任务调度问题就不可能实现!所以,我们下面要解决两个问题:

如何检测有向环(只检查存在性,不考虑有多少个)
对于一个不存在有向环的有向
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值