返回顶部
首页 > 资讯 > 后端开发 > Python >基于Java实现无向环和有向环的检测
  • 578
分享到

基于Java实现无向环和有向环的检测

2024-04-02 19:04:59 578人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录无向环有向环有向图检测算法无向环 一个含有环的无向图如下所示,其中有两个环,分别是 0-2-1-0 和 2-3-4-2: 要检测无向图中的环,可以使用深度优先搜索。假设从顶点

无向环

一个含有环的无向图如下所示,其中有两个环,分别是 0-2-1-0 和 2-3-4-2:

要检测无向图中的环,可以使用深度优先搜索。假设从顶点 0 出发,再走到相邻的顶点 2,接着走到顶点 2 相邻的顶点 1,由于顶点 0 和顶点 1 相邻,并且顶点 0 被标记过了,说明我们饶了一圈,所以无向图中存在环。虽然顶点 2 和顶点 1 相邻,但是并不能说明存在环,因为我们就是从顶点 2 直接走到顶点 1 的,这二者只有边的关系。算法如下所示:

package com.zhiyiyo.graph;

import com.zhiyiyo.collection.stack.LinkStack;
import com.zhiyiyo.collection.stack.Stack;


public class Cycle {
    private boolean[] marked;
    private Graph graph;
    private boolean hasCycle;

    public Cycle(Graph graph) {
        this.graph = graph;
        marked = new boolean[graph.V()];

        for (int v = 0; v < graph.V(); ++v) {
            if (!marked[v]) {
                dfs(v);
            }
        }
    }

    private void dfs(int s) {
        if (hasCycle()) return;

        Stack<Integer> vertexes = new LinkStack<>();
        vertexes.push(s);
        marked[s] = true;

        int lastVertex = s;
        while (!vertexes.isEmpty()) {
            int v = vertexes.pop();

            for (int w : graph.adj(v)) {
                if (!marked[w]) {
                    marked[w] = true;
                    vertexes.push(w);
                } else if (w != lastVertex) {
                    hasCycle = true;
                    return;
                }
            }

            lastVertex = v;
        }
    }

    
    public boolean hasCycle() {
        return hasCycle;
    }
}

有向环

有向图

有向图的实现方式和上一篇博客 《如何在 Java 中实现无向图》 中无向图的实现方式几乎一样,只是在添加边 v-w 时只在顶点 v 的链表上添加顶点 w,而不对顶点 w 的链表进行操作。如果把 LinkGraph 中成员变量的访问权限改成 protected,只需继承并重写 addEdge 方法即可:

package com.zhiyiyo.graph;


public class LinkDigraph extends LinkGraph implements Digraph {

    public LinkDigraph(int V) {
        super(V);
    }

    @Override
    public void addEdge(int v, int w) {
        adj[v].push(w);
        E++;
    }

    @Override
    public Digraph reverse() {
        Digraph digraph = new LinkDigraph(V());
        for (int v = 0; v < V(); ++v) {
            for (int w : adj(v)) {
                digraph.addEdge(w, v);
            }
        }
        return digraph;
    }
}

检测算法

一个含有有向环的有向图如下所示,其中 5-4-3-5 构成了一个环:

这里使用递归实现的深度优先搜索来检测有向环。假设从顶点 0 开始走,一路经过 5、4、3 这三个顶点,最终又碰到了与顶点 3 相邻的顶点 5,这时候如果知道顶点 5 已经被访问过了,并且递归函数还被压在栈中,就说明深度优先搜索从顶点 5 开始走,又回到了顶点 5,也就是找到了有向环。算法如下所示:

package com.zhiyiyo.graph;

import com.zhiyiyo.collection.stack.LinkStack;
import com.zhiyiyo.collection.stack.Stack;


public class DirectedCycle {
    private boolean[] marked;
    private boolean[] onStack;
    private int[] edgeTo;
    private Graph graph;
    private Stack<Integer> cycle;

    public DirectedCycle(Digraph graph) {
        this.graph = graph;
        marked = new boolean[graph.V()];
        onStack = new boolean[graph.V()];
        edgeTo = new int[graph.V()];

        for (int v = 0; v < graph.V(); ++v) {
            if (!marked[v]) {
                dfs(v);
            }
        }
    }

    private void dfs(int v) {
        marked[v] = true;
        onStack[v] = true;

        for (int w : graph.adj(v)) {
            if (hasCycle()) return;
            if (!marked[w]) {
                marked[w] = true;
                edgeTo[w] = v;
                dfs(w);
            } else if (onStack[w]) {
                cycle = new LinkStack<>();
                cycle.push(w);
                for (int i = v; i != w; i = edgeTo[i]) {
                    cycle.push(i);
                }
                cycle.push(w);
            }
        }

        onStack[v] = false;
    }

    
    public boolean hasCycle() {
        return cycle != null;
    }

    
    public Iterable<Integer> cycle() {
        return cycle;
    }
}

以上就是基于Java实现无向环和有向环的检测的详细内容,更多关于Java无向环 有向环的资料请关注编程网其它相关文章!

--结束END--

本文标题: 基于Java实现无向环和有向环的检测

本文链接: https://lsjlt.com/news/145075.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 基于Java实现无向环和有向环的检测
    目录无向环有向环有向图检测算法无向环 一个含有环的无向图如下所示,其中有两个环,分别是 0-2-1-0 和 2-3-4-2: 要检测无向图中的环,可以使用深度优先搜索。假设从顶点 ...
    99+
    2024-04-02
  • 基于Java实现双向链表
    本文实例为大家分享了Java实现双向链表的具体代码,供大家参考,具体内容如下 双向链表与单链表的对比: 1、单向链表查找只能是一个方向,双向链表可以向前或者向后查找2、单向链表不能自...
    99+
    2024-04-02
  • java双向循环链表的实现代码
    例1:复制代码 代码如下:package com.xlst.util; import java.util.HashMap;import java.util.Map;import ja...
    99+
    2022-11-15
    java 双向循环链表
  • Java和Unix:如何在实时环境中实现重定向?
    重定向是Unix系统中非常常见的一个功能,它允许将一个命令的输出重定向到一个文件或者另一个命令中。在实时环境中,比如说服务器端,重定向也是非常常见的。Java作为一种非常流行的编程语言,也提供了一些API来实现重定向。本文将介绍如何在Ja...
    99+
    2023-10-02
    重定向 实时 unix
  • 重定向在 Java 中的实现方式,是否适用于 Linux 环境?
    重定向是一种将输出从一个程序导向另一个程序或文件的技术。在Java中,重定向可以通过System类的setIn、setOut和setErr方法来实现。但是,这种实现方式是否适用于Linux环境呢?让我们来探讨一下。 在Java中,我们可以使...
    99+
    2023-09-16
    linux laravel 重定向
  • 基于Python OpenCV和 dlib实现眨眼检测
    目录了解“眼睛纵横比”(EAR)使用面部标志和 OpenCV 检测眨眼眨眼检测结果总结今天,我们使用面部标记和 OpenCV 检测视频流中的眨眼次数。 为了构建我们的眨眼检测器,我们...
    99+
    2024-04-02
  • C语言如何实现双向链表和双向循环链表
    本文小编为大家详细介绍“C语言如何实现双向链表和双向循环链表”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言如何实现双向链表和双向循环链表”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。双向链表和双向循环链表...
    99+
    2023-06-16
  • vue实现公告消息横向无缝循环滚动
    本文实例为大家分享了vue实现公告消息横向无缝循环滚动的具体代码,供大家参考,具体内容如下 该组件实现了公告消息的无缝横向滚动。我命名为marqueex.vue文件,感谢原来博主的分...
    99+
    2024-04-02
  • Java 单向队列及环形队列的实现原理
    目录队列的特点图解实现过程:优化解决——环形队列实现思路环形队列各步骤及各方法实现讲解最后:队列的特点 1.可以使用数组和链表两种方式来实现。 2.遵循先入先出(FIFO)的规则,即...
    99+
    2024-04-02
  • Java如何实现一个单向非循环链表
    这篇文章主要介绍“Java如何实现一个单向非循环链表”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java如何实现一个单向非循环链表”文章能帮助大家解决问题。1、什么是链表?链表是一种物理存储结构上...
    99+
    2023-07-04
  • 基于深度学习和OpenCV实现目标检测
    目录使用深度学习和OpenCV进行目标检测MobileNets:高效(深度)神经网络使用OpenCV进行基于深度学习的对象检测使用OpenCV检测视频使用深度学习和 OpenCV 进...
    99+
    2024-04-02
  • 如何实现基于opencv的行人检测
    这篇文章主要为大家展示了“如何实现基于opencv的行人检测”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何实现基于opencv的行人检测”这篇文章吧。基于方向梯度直方图(HOG)/线性支持向...
    99+
    2023-06-22
  • java基于双向环形链表解决丢手帕问题的示例分析
    这篇文章主要为大家展示了“java基于双向环形链表解决丢手帕问题的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“java基于双向环形链表解决丢手帕问题的示例分析”这篇文章吧。具体如下:问...
    99+
    2023-05-30
    java
  • Android实现横向无限循环滚动的单行弹幕效果
    本期将带领大家实现一个这样的效果,支持无限循环的单行弹幕效果。 实现思路分析 要实现上面的效果,我们先拆分下实现要素: 1、弹幕布局是从屏幕的右侧向左侧滚动,单个弹幕之间的间距是固...
    99+
    2024-04-02
  • vue怎么实现公告消息横向无缝循环滚动
    这篇文章主要讲解了“vue怎么实现公告消息横向无缝循环滚动”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue怎么实现公告消息横向无缝循环滚动”吧!marqueex.vue<templ...
    99+
    2023-06-29
  • 基于Flask和PaddleHub怎么实现人脸检测功能
    这篇文章主要介绍“基于Flask和PaddleHub怎么实现人脸检测功能”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“基于Flask和PaddleHub怎么实现人脸检测功能”文章能帮助大家解决问题。...
    99+
    2023-07-05
  • Java实现无向图的示例详解
    目录基本概念图的定义无向图的定义无向图的 API无向图的实现方式邻接矩阵边的数组邻接表数组无向图的遍历深度优先搜索广度优先搜索后记基本概念 图的定义 一个图是由点集V={vi}&nb...
    99+
    2024-04-02
  • Python基于链接表实现无向图最短路径搜索
    目录前言1. 链接表2. 最短路径算法2.1 无向图最短路径算法3. 总结前言 图的常用存储方式有 2 种: 邻接炬阵链接表 邻接炬阵的优点和缺点都很明显。优点是简单、易理解,对于大...
    99+
    2024-04-02
  • Java单向队列及环形队列的实现原理是什么
    这篇文章主要介绍“Java单向队列及环形队列的实现原理是什么”,在日常操作中,相信很多人在Java单向队列及环形队列的实现原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java单向队列及环形队列的实...
    99+
    2023-06-25
  • 基于C#实现的多边形冲突检测实例
    前言 之前在项目上碰到了一个多边形冲突检测的问题,经百度、bing、google,发现目前已有的方案,要么是场景覆盖不全,要么是通过第三方类库实现(而这些第三方类库几乎是无法逆向反编...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作