02_02_广度优先搜索(Breadth-First Search,BFS)

2023-11-08

广度优先搜索(Breadth-First Search,BFS)

广度优先搜索(Breadth-First Search,BFS)介绍:

是一种图遍历算法,其原理是逐层遍历图的节点。BFS从起始节点开始,先访问起始节点的所有邻居节点,然后再逐层访问其他邻居节点。

广度优先搜索(Breadth-First Search,BFS)原理:
  1. 选择一个起始节点,并将其标记为已访问。
  2. 将起始节点放入队列(通常是使用队列数据结构实现BFS)。
  3. 当队列不为空时,执行以下步骤:
    ● 从队列中取出一个节点作为当前节点。
    ● 访问当前节点,并进行相应的操作。
    ● 将当前节点的所有未访问的邻居节点加入队列,并标记为已访问。
  4. 如果队列为空,表示已经遍历完所有节点,算法结束。
Java 代码实现:
package com.algorithm.graph;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class BFS {

    /**
     * 测试方法
     *
     * @param args todo
     */
    public static void main(String[] args) {

        /**
         * 创建有 6 个节点的图对象
         */
        BFSGraph graph = new BFSGraph(6);

        /**
         * 添加节点
         */
        graph.addEdge(0, 1);
        graph.addEdge(0, 2);
        graph.addEdge(1, 3);
        graph.addEdge(2, 4);
        graph.addEdge(2, 5);

        System.out.println("Breadth-First Traversal (starting from vertex 0):");

        /**
         * 调用 BFS 算法遍历节点
         */
        graph.BFS(0);
    }

}

/**
 * BFS 算法实现原理
 * <p>
 * 1.选择一个起始节点,并将其标记为已访问。
 * 2.将起始节点放入队列(通常是使用队列数据结构实现BFS)。
 * 3.当队列不为空时,执行以下步骤:
 * 从队列中取出一个节点作为当前节点。
 * 访问当前节点,并进行相应的操作。
 * 将当前节点的所有未访问的邻居节点加入队列,并标记为已访问。
 * 4.如果队列为空,表示已经遍历完所有节点,算法结束。
 */
class BFSGraph {

    /**
     * 节点数量
     */
    private int numVertices;

    /**
     * 邻接表
     */
    private List<List<Integer>> adjacencyList;

    /**
     * 构造方法,将所有的节点全部存储在 ArrayList 集合中
     *
     * @param numVertices 节点数量
     */
    public BFSGraph(int numVertices) {
        this.numVertices = numVertices;
        this.adjacencyList = new ArrayList<>(numVertices);
        for (int i = 0; i < numVertices; i++) {
            adjacencyList.add(new ArrayList<>());
        }
    }

    /**
     * 添加边到邻接表
     *
     * @param source      起始节点
     * @param destination 终点节点
     */
    public void addEdge(int source, int destination) {
        adjacencyList.get(source).add(destination);
        /**
         * 如果是无向图,需要添加反向边
         */
        adjacencyList.get(destination).add(source);
    }

    /**
     * 算法实现
     *
     * @param startVertex 开始节点
     */
    public void BFS(int startVertex) {

        /**
         * 标记节点是否已被访问
         */
        boolean[] visited = new boolean[numVertices];

        /**
         * 使用队列来存储待访问的节点
         */
        Queue<Integer> queue = new LinkedList<>();

        /**
         * 从起始节点开始,将其标记为已访问并加入队列
         * 队列特点:先入先出
         */
        visited[startVertex] = true;
        queue.add(startVertex);

        /**
         * 遍历队列
         */
        while (!queue.isEmpty()) {
            int currentVertex = queue.poll();

            /**
             * 打印节点
             */
            System.out.print(currentVertex + " ");

            List<Integer> neighbors = adjacencyList.get(currentVertex);
            for (int neighbor : neighbors) {
                if (!visited[neighbor]) {
                    /**
                     *将未访问的邻居节点标记为已访问
                     */
                    visited[neighbor] = true;

                    /**
                     * 将节点加入队列
                     */
                    queue.add(neighbor);
                }
            }
        }
    }
}
代码简单解释:

在这个代码示例中,我们定义了一个Graph类来表示图数据结构,包括节点数量numVertices和邻接表adjacencyList。addEdge方法用于添加边到邻接表,注意在无向图中需要添加反向边。

在BFS方法中,我们使用一个布尔数组visited来标记节点是否已被访问,并使用一个队列queue来存储待访问的节点。我们从起始节点开始,将其标记为已访问并入队列。然后,进入循环直到队列为空。在循环中,我们从队列中取出一个节点,打印该节点,并将其未访问的邻居节点标记为已访问并入队列。

在主函数中,我们创建一个Graph对象,并通过addEdge方法添加边。然后调用BFS方法以广度优先的方式遍历图,从起始节点0开始。

程序执行结果:
Breadth-First Traversal (starting from vertex 0):
0 1 2 3 4 5 
Process finished with exit code 0
备注:

广度优先搜索算法的原理是逐层遍历,从起始节点开始,先访问起始节点的所有邻居节点,然后逐层访问下一层的邻居节点。这样可以保证从起始节点到其他节点的最短路径被优先访问到。BFS算法还可以用于解决一些问题,如寻找最短路径、连通性检测、图的遍历等。

广度优先搜索(Breadth-First Search,BFS)算法图示:

假设我们有以下图结构:

     0
    / \
   1   2
  /   / \
 3   4   5

开始时,选择起始节点0进行广度优先搜索。我们从节点0开始,然后按照层级逐层访问节点的邻居节点。首先,我们访问节点0的邻居节点1和2。然后,访问节点1的邻居节点3,访问节点2的邻居节点4和5。

下面是BFS算法执行的过程描述:

  1. 选择起始节点0,并将其标记为已访问。
     0*
    / \
   1   2
  /   / \
 3   4   5
  1. 访问节点0的邻居节点1和2,并将它们标记为已访问。
     0*
    / \
   1*  2*
  /   / \
 3   4   5
  1. 访问节点1的邻居节点3,并将其标记为已访问。
     0*
    / \
   1*  2*
  /   / \
 3*  4   5
  1. 访问节点2的邻居节点4和5,并将它们标记为已访问。
     0*
    / \
   1*  2*
  /   / \
 3*  4*  5*

最终,BFS算法的遍历路径为0-1-2-3-4-5。

总结:

通过图的可视化,我们可以更直观地理解BFS算法的执行过程。在每一层级中,我们先访问当前层级的所有节点,然后再进入下一层级的节点。这种层级遍历的方式可以帮助我们找到起始节点到其他节点的最短路径,并保证我们按照距离逐层遍历图的节点。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

02_02_广度优先搜索(Breadth-First Search,BFS) 的相关文章

  • 按键时关闭 ModalWindow

    我希望能够在用户按下某个键 在我的例子中是 ESC 时关闭 ModalWindow 我有一个用于按键的 Javascript 侦听器 它调用取消按钮 ID 的单击事件 jQuery modalWindowInfo closeButtonId
  • 如何将本机库链接到 IntelliJ 中的 jar?

    我正在尝试在 IntelliJ 中设置 OpenCV 但是我一直在弄清楚如何告诉 IntelliJ 在哪里可以找到本机库位置 在 Eclipse 中 添加 jar 后 您可以在 Build Config 屏幕中设置 Native 库的位置
  • 日期语句之间的 JPQL SELECT [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我想将此 SQL 语句转换为等效的 JPQL SELECT FROM events WHERE events date BETWE
  • Spring应用中Eureka健康检查的问题

    我正在开发一个基于 Spring 的应用程序 其中包含多个微服务 我的一个微服务充当尤里卡服务器 到目前为止一切正常 在我所有其他微服务中 用 EnableEurekaClient 我想启用这样的健康检查 应用程序 yml eureka c
  • Mockito:如何通过模拟测试我的服务?

    我是模拟测试新手 我想测试我的服务方法CorrectionService correctPerson Long personId 实现尚未编写 但这就是它将执行的操作 CorrectionService将调用一个方法AddressDAO这将
  • Java 枚举与创建位掩码和检查权限的混淆

    我想将此 c 权限模块移植到 java 但是当我无法将数值保存在数据库中然后将其转换为枚举表示形式时 我很困惑如何执行此操作 在 C 中 我创建一个如下所示的枚举 public enum ArticlePermission CanRead
  • org.apache.hadoop.security.AccessControlException:客户端无法通过以下方式进行身份验证:[TOKEN,KERBEROS] 问题

    我正在使用 java 客户端通过 Kerberos 身份验证安全访问 HDFS 我尝试打字klist在服务器上 它显示已经存在的有效票证 我收到的异常是客户端无法通过以下方式进行身份验证 TOKEN KERBEROS 帮助将不胜感激 这是一
  • 如何更改javaFX中按钮的图像?

    我正在使用javaFX 我制作了一个按钮并为此设置了图像 代码是 Image playI new Image file c Users Farhad Desktop icons play2 jpg ImageView iv1 new Ima
  • 谷歌应用程序引擎会话

    什么是java应用程序引擎 默认会话超时 如果我们将会话超时设置为非常非常长的时间 会不会产生不良影响 因为谷歌应用程序引擎会话默认情况下仅存储在数据存储中 就像facebook一样 每次访问该页面时 会话仍然永远存在 默认会话超时设置为
  • 来自 dll 的 Java 调用函数

    我有这个 python 脚本导入zkemkeeperdll 并连接到考勤设备 ZKTeco 这是我正在使用的脚本 from win32com client import Dispatch zk Dispatch zkemkeeper ZKE
  • 帮助将图像从 Servlet 获取到 JSP 页面 [重复]

    这个问题在这里已经有答案了 我目前必须生成一个显示字符串文本的图像 我需要在 Servlet 上制作此图像 然后以某种方式将图像传递到 JSP 页面 以便它可以显示它 我试图避免保存图像 而是以某种方式将图像流式传输到 JSP 自从我开始寻
  • volatile、final 和synchronized 安全发布的区别

    给定一个带有变量 x 的 A 类 变量 x 在类构造函数中设置 A x 77 我们想将 x 发布到其他线程 考虑以下 3 种变量 x 线程安全 发布的情况 1 x is final 2 x is volatile 3 x 设定为同步块 sy
  • Java ResultSet 如何检查是否有结果

    结果集 http java sun com j2se 1 4 2 docs api java sql ResultSet html没有 hasNext 方法 我想检查 resultSet 是否有任何值 这是正确的方法吗 if resultS
  • 在我的 Spring Boot 示例中无法打开版本 3 中的 Swagger UI

    我在 Spring Boot 示例中打开 swagger ui 时遇到问题 当我访问 localhost 8080 swagger ui 或 localhost 8080 root api name swagger ui 时出现这种错误 S
  • 专门针对 JSP 的测试驱动开发

    在理解 TDD 到底是什么之前 我就已经开始编写测试驱动的代码了 在没有实现的情况下调用函数和类可以帮助我以更快 更有效的方式理解和构建我的应用程序 所以我非常习惯编写代码 gt 编译它 gt 看到它失败 gt 通过构建其实现来修复它的过程
  • Cucumber 0.4.3 (cuke4duke) 与 java + maven gem 问题

    我最近开始为 Cucumber 安装一个示例项目 并尝试使用 maven java 运行它 我遵循了这个指南 http www goodercode com wp using cucumber tests with maven and ja
  • 干净构建 Java 命令行

    我正在使用命令行编译使用 eclipse 编写的项目 如下所示 javac file java 然后运行 java file args here 我将如何运行干净的构建或编译 每当我重新编译时 除非删除所有内容 否则更改不会受到影响 cla
  • 在java中为组合框分配键

    我想添加一个JComboBox在 Swing 中这很简单 但我想为组合中的每个项目分配值 我有以下代码 JComboBox jc1 new JComboBox jc1 addItem a jc1 addItem b jc1 addItem
  • 长轮询会冻结浏览器并阻止其他 ajax 请求

    我正在尝试在我的中实现长轮询Spring MVC Web 应用程序 http static springsource org spring docs 2 0 x reference mvc html但在 4 5 个连续 AJAX 请求后它会
  • 使用 svn 1.8.x、subclise 1.10 的 m2e-subclipse 连接器在哪里?

    我读到 m2e 的生产商已经停止生产 svn 1 7 以外的任何版本的 m2e 连接器 Tigris 显然已经填补了维护 m2e subclipse 连接器的空缺 Q1 我的问题是 使用 svn 1 8 x 的 eclipse 更新 url

随机推荐

  • VS2013配置SQLite数据库

    1 下载SQLite相关文件 官网 https sqlite org download html 下载这两个文件 3 编译 解压文件 里面存在两个文件 打开windows下的cmd 找到vs2013的安装路径下的lib exe所在的文件夹
  • 人工智能-搜索----启发式搜索

    搜索算法的形式化描述 lt 状态state 动作motion 状态转移state transition 路径path 测试目标test target gt 一 启发式搜索 有信息搜索 Heuristic Search 代表算法 贪婪最佳优先
  • latex 图片跑到引用后的解决办法

    问题描述 双栏情况下 当正文 参考文献占不到一页 而此时你的图片又刚好占了至少半页 此时图片就会被抵到参考文献后 解决办法 要想将参考文献调整到图片后 可以在论文开头引入包 usepackage section placeins 但这样的话
  • 用c语言开发一个安卓APP,c语言开发的app-用c语言可以开发app吗

    通常 IOS应用使用C 和对象的C 以写的 但到的xcode通过该程序 您可以写信给重用OC A应用程序也可以用一个OC C 结合起来写 我读了一外地开发商说 代码app1000行 他开发800是C 200条OC 电话软件 c编程语言都可以
  • 腾讯云Linux服务器搭建(二) DNS设置

    主机是用支付宝交钱 从付款到拿到主机用了20分钟左右吧 拿到后上去确认了配置是否相符 一切确认无误后 先把域名的DNS设置到主机上 然后再开始办理备案相关手续 域名解析 域名原来是从万网买的 现在万网早就被阿里收购了 只能去阿里云找了 直接
  • php curl 发起get和post网络请求.note

    curl介绍 curl是一个开源的网络链接库 支持http https ftp gopher telnet dict file and ldap 协议 之前均益介绍了python版本的pycurl http junyiseo com pyt
  • ClickHouse替换MySQL作为数仓APP层

    一 ClickHouse 是什么 二 业务问题 三 ClickHouse实践 四 遇到的坑 五 总结 一 ClickHouse 是什么 ClickHouse 是一个用于联机分析 OLAP 的列式数据库管理系统 DBMS 我们首先理清一些基础
  • 【转载】CNN模型复杂度(FLOPs、MAC)、参数量与运行速度

    备忘 作者写错了 1次乘加运算等于2次浮点运算 但在数值上正好反过来 即1 FLOPs 2 MACs 例如对于卷积运算的计算是 其MACs 参数m 输出尺寸 n 而FLOPs 2 MACs Nvidia团队论文里面写的是对的 2倍 CNN模
  • SQLServer导入导出excel及常见问题

    前几天考试系统导入导出学生信息 初次接触导入导出 为sqlserver和excel的数据传递方法之简和MS产品的高效兼容所震惊 但也遇到各种各样问题 在此介绍SQLServer导入导出excel方法及遇到的问题 SQLServer导出Exc
  • java 中Date日期类型

    4 日期相关 把1970年1月1日当做了时间原点 以毫秒值为单位 4 1 获得当前时间 System currentTimeMillis public class DateTest public static void main Strin
  • ifstream 和 ofstream 文件中读取和写入操作

    导读 ofstream是从内存到硬盘 ifstream是从硬盘到内存 其实所谓的流缓冲就是内存空间 在C 中 有一个stream这个类 所有的I O都以这个 流 类为基础的 包括我们要认识的文件I O stream这个类有两个重要的运算符
  • XGBoost和LightGBM的比较

    目录 1 XGBoost sgboost中树节点分裂时所采用的公式 xgboost的分裂步骤 xgboost总结 LightGBM 基于决策树算法的分布式梯度提升框架 LightGBM在模型的训练速度和内存方面的优化 LightGBM的le
  • arima模型 p q d 确定_【干货】时间预测之 ARIMA模型

    ARIMA 是 AutoRegressive Integrated Moving Average的简称 看起来很复杂 其实这个模型本身是多个模型的叠加或者说混合 AR 自相关模型 AutoRegressive MA 移动平均模型 Movin
  • Python显示目录的树形结构

    转自 http blog chinaunix net uid 21374062 id 5198995 html Python显示目录的树形结构 coding utf 8 仿Linux命令tree生成树形目录结构 并汇总当前目录下文件总算 A
  • pes2017服务器维护时间,PES2017授权详情与球场数据包发布时间

    East Dorsetshire AFC Bournemouth BOU Lancashire Claret Burnley BRN London FC Chelsea CHE South Norwood Crystal Palace CR
  • python:多维数组变一维数组

    python 多维数组变一维数组 b a flatten 将多维数组变为1维数组 具体代码如下 import numpy as np 1 随机生成一个4行3列的多维数组a a np random randn 4 3 print a prin
  • selenium自动化,更新到最新的chrome驱动

    很久没有做自动化了 最近想要熟悉下 发现之前的chrome驱动器与现在的chrome浏览器版本不匹配了导致报错 提示如下 raise exception class message screen stacktrace selenium co
  • (已解决)显卡(N卡)设置独显后,指定程序依旧使用集显渲染

    显卡 N卡 设置独显后 指定程序依旧使用集显渲染 设置流程如下 设置流程如下 1 打开 nvdia 控制面板 2 设置全局为独显 3 修改指定程序为独显 4 以上几步若无效 则按如下修改 选择对应的程序
  • Linux安装nginx

    Linux安装nginx 1 下载 2 准备目录 3 上传 解压 5 设置安装路径 如果 报错 gcc pcre 6 编译 7 安装 8 启动 9 其他命令 10 判断Nginx配置是否正确命令 11 开放nginx默认端口号80 12 访
  • 02_02_广度优先搜索(Breadth-First Search,BFS)

    广度优先搜索 Breadth First Search BFS 广度优先搜索 Breadth First Search BFS 介绍 是一种图遍历算法 其原理是逐层遍历图的节点 BFS从起始节点开始 先访问起始节点的所有邻居节点 然后再逐层