判断有向图中是否有环(内含代码详解)

如果学习x课程前必须先学习y课程,学习y课程前必须先学习z课程,学习z课程前必须先学习x课程,那么一定是有问题了,我们就没有办法学习了,因为这三个条件没有办法同时满足。其中这三门课程x,y,z的条件组成了一个环。
在这里插入图片描述
因此,如果我们要使用拓扑排序解决优先级问题,首先得保证图中没有环的存在。
1.1检测有向环的API设计
在这里插入图片描述在API中添加onStack[]布尔数组,索引为图的顶点,当我们深度搜索的时:
1:在如果当前顶点正在搜索,则把对应的onStack数组中的值修改为true,标识进栈;
2:如果当前顶点搜索完毕,则把对应的onStack数组中的值改为false,标识出栈;
3:如果即将要搜索某个顶点,但该顶点已经在栈中,则图中有环;
在这里插入图片描述
在这里插入图片描述
代码实现

public class DirectedCycle {
    //索引代表顶点,值表示当前顶点是否已经被搜索
    private boolean[] marked;
    //记录图中是否有环
    private boolean hasCycle;
    //索引代表顶点,使用栈的思想,记录当前顶点有没有已经处于正在搜索的有向路径上
    private boolean[] onStack;


    //创建一个检测对象,检测图G中是否有环
    public DirectedCycle(Digraph G){
        //初始化marked数组
        this.marked = new boolean[G.V()];
        //初始化hasCycle数组
        this.hasCycle = false;
        //初始化onStack数组
        this.onStack = new boolean[G.V()];

        //找到图中每一个顶点,让每一个顶点作为入口,调用一次dfs进行搜索
        for(int v = 0;v < G.V(); v++){
            //判断如果当前顶点还没有被搜索过,则调用dfs进行搜索
            if(!marked[v]){
                dfs(G,v);
            }
        }
    }

    /**
     * 基于深度优先搜索,检测图G中是否有环
     * @param G
     * @param v
     */
    private void dfs(Digraph G,int v){
        //把顶点v表示为已搜索
        marked[v] = true;

        //把当前顶点进栈
        onStack[v] = true;

        //进行深度搜索
        for (Integer w : G.adj(v)) {
            //判断如果当前顶点w没有被搜索过,则继续递归调用dfs方法完成深度优先搜索
            if(!marked[w]){
                dfs(G,w);
            }

            //判断当前顶点w是否已经在栈中,如果已经在栈中,证明当前顶点之前处于正在搜索的状态
            if(onStack[w]){
                hasCycle = true;
                return;
            }
        }
    }

    /**
     * 判断有向环中是否有环
     * @return
     */
    public boolean hasCycle(){
        return hasCycle;
    }
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

碳烤小肥羊。。。

你的鼓励是我创造最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值