深度优先搜索实现无向图环的检测(java实现)

一、问题描述

如何检测无向图中的环?注意:本题中不考虑自环和平行环

二、解决思路

由于深度优先搜索性质,我们可以用它来检测环。假设当前访问顶点为v,访问v之前访问的顶点为prev,则prev为v的前驱节点。设w为v的后继节点,且w != prev并且w已被访问了,则可以判断图中存在环;假设第一个访问的顶点的前驱节点为其本身,我们以图1 为例进行讲解:

第一步:我们先访问0号顶点,此时v = 0 , prev = 0,w = 1。满足w != prev,但不满足w以访问,继续执行下一步;如下图:

第二步:我们访问1号顶点,此时v = 1,prev = 0,w = 2或3;不满足条件继续执行如下图所示:

第三步:我们访问2号顶点,此时v = 2,prev = 1,w = 1或3;不满足条件继续执行,如下图所示:

第四步:我们访问3号顶点,此时v = 3,prev = 2;两种情况,第一种情况:w = 2,v = 3,prev = 2不满足w != prev;第二种情况:w = 1,v = 3,prev = 2满足w != prev并且满足w已经访问,所以该图是一个有环图。

三、算法实现

本算法依赖上一篇文章所建立图,其图的创建代码参考上一篇文章无向图的创建(java实现),代码实现如下所示:

package graph;

import java.util.Arrays;

/**
 * 通过深度优先搜索检测图中是否存在环
 *
 * @date 2021-01-22 15:18
 * @author hh
 */
public class CycleTest {
    /**
     * 图对象
     */
    private Graph graph;

    /**
     * 标记哪些顶点被访问
     */
    private boolean[] marked;

    /**
     * 是否存在环
     */
    private boolean isHasCycle;

    private CycleTest() {
    }

    public boolean hasCycle(){
        return isHasCycle;
    }

    public CycleTest(Graph graph) {
        this.graph = graph;
        //默认不存在环
        this.isHasCycle = false;
        marked = new boolean[graph.getVertices()];
        Arrays.fill(marked,Boolean.FALSE);
        this.dfs();
    }

    /**
     * 深度优先搜索
     */
    public void dfs(){
        for(int v = 0; v < graph.getVertices(); v++ ){
            if(!isMarked(v)){
                this.search(v,v);
            }
        }
    }


    private void search(int v,int prev){
        System.out.print(v +" ");
        marked[v] = true;
        for(Integer w : graph.adj(v)){
            if(!isMarked(w)){
                search(w,v);
            }else if (w != prev){
                isHasCycle = true;
            }
        }
    }

    /**
     * 顶点w是否被访问过
     * @param w :顶点编号
     * @return ;是否被访问
     */
    private boolean isMarked(int w){
        return this.marked[w];
    }
}

测试代码如下所示:

public static void main(String[] args) throws Exception {
        String filename = "D:\\Desktop\\graph5.txt";
        Graph graph = new Graph();
        graph.createGraphByFile(filename);
        CycleTest cycleTest = new CycleTest(graph);
        boolean hasCycle = cycleTest.hasCycle();
        System.out.print("\n是否存在环:" + hasCycle);
    }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值