图的广度优先搜索(bfs)

2023-11-02

图的广度优先搜索(Broad First Search)

所谓的深度优先搜索,指的是在搜索时,如果遇到一个结点既有子结点,又有兄弟结点,那么先找兄弟结点,然后找子结点。

类似于一个分层搜索的过程,广度优先遍历需要使用一个队列以保持访问过的结点的顺序,以便按这个顺序来访问这些结点的邻接结点

广度优先遍历算法步骤

  1. 访问初始结点v并标记结点v为已访问。
  2. 结点v入队列
  3. 当队列非空时,继续执行,否则算法结束。
  4. 出队列,取得队头结点u。
  5. 查找结点u的第一个邻接结点w。
  6. 若结点u的邻接结点w不存在,则转到步骤3
  7. 否则循环执行以下三个步骤:
  8.  若结点w尚未被访问,则访问结点w并标记为已访问。
  9. 结点w入队列
  10. 查找结点u的继w邻接结点后的下一个邻接结点w,转到步骤6。

 API设计

API设计
类名 BreadthFirstSearch
构造方法 BreadthFirstSearch(Graph G,int s):构造广度优先搜索对象,使用广度优先搜索找出G图中s顶点的所有相邻顶点
成员方法

1.private void bfs(Graph G, int v):使用广度优先搜索找出G图中v顶点的所有相邻顶点

2.public boolean marked(int w):判断w顶点与s顶点是否相通

3.public int count():获取与顶点s相通的所有顶点的总数

成员变量

1.private boolean[] marked: 索引代表顶点,值表示当前顶点是否已经被搜索

2.private int count:记录有多少个顶点与s顶点相通

3.private Queue waitSearch: 用来存储待搜索邻接表的点

代码实现

package 深度优先搜索;

import 基本图.Graph;

public class DepthFirstSearch {
    //索引代表顶点,值表示当前顶底是否已经被搜索过
    private boolean[] marked;
    //记录有多少个顶点与s顶点相通
    private int count;

    //构造深度优先搜索对象,使用深度优先搜索找出G图中顶点的所有相邻顶点(找兄弟节点)
    //s为起点5
    public DepthFirstSearch(Graph G, int s){
        //初始化marked数组
        this.marked = new boolean[G.v()];
        //初始化跟顶点s相通的顶点的数量
        this.count = 0;
        dfs(G,s);
    }

    //使用深度优先搜索找出G图中v顶点的所有相通的顶点(找子节点)
    private void dfs(Graph G,int v){
        //把v标识为已搜索
        marked[v] = true;

        for (Integer w : G.adj(v)) {
            //判断当前w顶点有没有被搜索过,如果没有被搜索过 ,则递归调用dfs方法进行深度搜索
            if(!marked[w]){
                dfs(G,w);
            }
        }
        //相通顶点的数量+1,找到兄弟节点
        count++;
    }

    //判断w顶点与s顶点是否相通
    public boolean marked(int w){
        return marked[w];
    }

    //获取与顶点s相通的所有顶点的总数
    public int count(){
        return count;
    }
}

核心代码

    //使用深度优先搜索找出G图中v顶点的所有相通的顶点(找子节点)
    private void dfs(Graph G,int v){
        //把v标识为已搜索
        marked[v] = true;

        for (Integer w : G.adj(v)) {
            //判断当前w顶点有没有被搜索过,如果没有被搜索过 ,则递归调用dfs方法进行深度搜索
            if(!marked[w]){
                dfs(G,w);
            }
        }
        //相通顶点的数量+1,找到兄弟节点
        count++;
    }

Demo

package 深度优先搜索;

import 基本图.Graph;

public class DepthFirstSearchTest {
    public static void main(String[] args) {
        //准备Graph对象
        Graph G = new Graph(13);
        G.addEdge(0,5);
        G.addEdge(0,1);
        G.addEdge(0,2);
        G.addEdge(0,6);
        G.addEdge(5,3);
        G.addEdge(5,4);
        G.addEdge(3,4);
        G.addEdge(4,6);

        G.addEdge(7,8);

        G.addEdge(9,11);
        G.addEdge(9,10);
        G.addEdge(9,12);
        G.addEdge(11,12);

        //准备深度优先搜索对象
        DepthFirstSearch search = new DepthFirstSearch(G,0);

        //准备深度优先搜索对象
        int count = search.count();
        System.out.println("与起点0相通的顶点的数量为:" + count);

        //测试与某个顶点相通的顶点数量
        boolean marked1 = search.marked(5);
        System.out.println("顶点5和0是否相通:" + marked1);

        //测试某个顶点与起点是否相通
        boolean marked2 = search.marked(7);
        System.out.println("顶点7和0是否相通:" + marked2);
    }
}

导入的包

package 队列;

import java.util.Iterator;

public class Queue<T> implements Iterable<T>{
    //记录首结点
    private Node head;
    //记录最后一个结点
    private Node last;
    //记录队列中元素的个数
    private int N;


    private class Node{
        public T item;
        public Node next;

        public Node(T item, Node next) {
            this.item = item;
            this.next = next;
        }
    }
    public Queue() {
        this.head = new Node(null,null);
        this.last=null;
        this.N=0;
    }

    //判断队列是否为空
    public boolean isEmpty(){
        return N==0;
    }

    //返回队列中元素的个数
    public int size(){
        return N;
    }

    //向队列中插入元素t
    public void enqueue(T t){

        if (last==null){
            //当前尾结点last为null
            last= new Node(t,null);
            head.next=last;
        }else {
            //当前尾结点last不为null
            Node oldLast = last;
            last = new Node(t, null);
            oldLast.next=last;
        }

        //元素个数+1
        N++;
    }

    //从队列中拿出一个元素
    public T dequeue(){
        if (isEmpty()){
            return null;
        }

        Node oldFirst= head.next;
        head.next=oldFirst.next;
        N--;

        //因为出队列其实是在删除元素,因此如果队列中的元素被删除完了,需要重置last=null;

        if (isEmpty()){
            last=null;
        }
        return oldFirst.item;
    }


    @Override
    public Iterator<T> iterator() {
        return new QIterator();
    }

    private class QIterator implements Iterator{
        private Node n;

        public QIterator(){
            this.n=head;
        }
        @Override
        public boolean hasNext() {
            return n.next!=null;
        }

        @Override
        public Object next() {
            n = n.next;
            return n.item;
        }
    }


}

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

图的广度优先搜索(bfs) 的相关文章

  • matplotlib—画正弦、余弦函数图

    一 导入模块 import matplotlib pyplot as plt import numpy as np plt rcParams font sans serif SimHei 用于正常显示中文标签 plt rcParams ax
  • 人工智能与神经网络-激活函数

    人工神经元的工作原理 大致如下 上述过程的数学可视化过程如下图 激活函数 Activation Function 是一种添加到人工神经网络中的函数 旨在帮助网络学习数据中的复杂模式 类似于人类大脑中基于神经元的模型 激活函数最终决定了要发射

随机推荐

  • 【宝塔面板建站】01. 5分钟windows宝塔面板的安装(保姆级图文)

    目录 1 下载宝塔面板 2 安装宝塔面板 3 初始化面板 4 安装套件 关于建站使用 总结 宝塔面板建站 分享宝塔面板从安装到实战的宝塔面板本机免云服务器免域名搭建网站等内容 欢迎关注 宝塔面板建站 系列 持续更新中 欢迎关注 宝塔面板建站
  • 机器人学之动力学笔记【11】—— 拉格朗日 动力学方程

    机器人学之动力学笔记 11 拉格朗日 动力学方程 1 拉格朗日法 2 举例 An RP Manipulator 3 转换到笛卡尔空间下 4 考虑能量损耗 1 拉格朗日法 之前我们学习了如何使用牛顿 欧拉法 基于力和力矩分析 建立机械臂的动力
  • 解决文件只能在windows系统上传成功,而linux系统上传失败。

    场景 在我们项目准备上线进行SIT测试的时候 测试在文件上传的时候 一直上传不成功 表示当前文件不支持上传 然后我们让测试将他的文件发送给我们进行测试 我们是能够上传成功的 然后询问他们使用的什么系统 发现他们使用的是Linux发行版操作系
  • android中surfaceview时间长了卡主,被SurfaceView搞死了的搞后感

    这几天遇到一个问题 视频播放时 为了保持视频的宽高比 就需要在surfaceView的父view的大小改变的时候 改变SurfaceView的大小 父View的大小改变的时候 会走View的onSizeChanged回调 所以 复写了这个方
  • Oracle 11G Client 客户端安装步骤(图文详解)

    oracle 2010 http www cnblogs com jiguixin archive 2011 09 09 2172672 html 下载地址 http download oracle com otn nt oracle11g
  • 文件操作 和 IO

    目录 编辑一 认识文件 1 文件路径 2 其它知识 二 Java 中操作文件 三 文件内容的读写 1 Reader 2 InputStream 3 输出 一 认识文件 文件是在硬盘上存储数据的一种方式 操作系统帮我们把硬盘的一些细节都封装起
  • docker运行nginx为什么要使用 nginx -g ‘daemon off;‘

    1 docker容器跑着为啥会挂掉 docker 容器默认会把容器内部第一个进程 也就是pid 1的程序作为docker容器是否正在运行的依据 如果docker 容器pid挂了 那么docker容器便会直接退出 2 docker run的时
  • AngularJS全局API

    AngularJS全局API AngularJS全局API是一组全局JavaScript函数 用来进行一些常用的操作 例如 比较两个对象 迭代对象 进行数据格式转换 全局API函数可以通过angular对象来直接调用 下表列除了一些比较常用
  • Atitit. 有限状态机 fsm 状态模式

    Atitit 有限状态机 fsm 状态模式 1 有限状态机 1 2 状态表 和 状态轮换表 1 3 有限状态机概念 状态 State 事件 Event 转换 Transition 动作 Action 2 4 状态机的应用场景 2 4 1 有
  • 运行monkeyrunner报 ANDROID_SWT set error

    运行monkeyrunner报错 Please set ANDROID SWT to point to the folder containing swt jar for your platform 原因 monkeyrunner 找不到s
  • 《A Survey on Visual Transformer》阅读笔记

    文章目录 前言 一 用于视觉的transformer介绍 1 transformer发展的关键节点如下 视觉相关的transformer用红色标记 2 用于视觉的transformer代表性成果 二 transformer模型 1 原始tr
  • 【python爬虫】7.爬到的数据存到哪里?

    文章目录 前言 存储数据的方式 存储数据的基础知识 基础知识 Excel写入与读取 基础知识 csv写入与读取 项目 存储周杰伦的歌曲信息 复习 前言 上一关我们以QQ音乐为例 主要学习了如何带参数地请求数据 get请求 和Request
  • Web服务器、Servlet容器和Servlet

    1 什么是Web服务器 想要知道什么是Servlet容器 我们首先要知道什么是Web服务器 Web服务器使用HTTP协议来传输数据 最简单的一种情况是 用户在浏览器 客户端 client 中输入一个URL 如 www programcree
  • 「React 深入」一文吃透React v18 全部 Api(1.3w+ 字)

    点击上方 前端Q 关注公众号 回复加群 加入前端Q技术交流群 大家好 我是小杜杜 俗话说的好 工欲善其事必先利其器 什么意思呢 就是说你想玩转React就必须知道React有什么 无论是否运用到 首先都要知道 提升思维广度 其实React官
  • 教你如何测试局域网网速

    网络管理员最常遇到的问题就是网络连接问题 也许公司员工的计算机无法上网那么我们可以通过简单的几步就检测到问题所在 但有一种网络连接问题却让我们无所适从 那就是员工反映网络速度缓慢 因为决定网络速度的因素很多 不可能通过简单的操作检测出速度的
  • SpringBoot 将项目打包成 jar 包

    SpringBoot 将项目打包成 jar 包 一 项目打包成 jar 包 首先在 pom xml 文件中导入 Springboot 的 maven 依赖
  • java对redis的基本操作

    原文地址 http www cnblogs com edisonfeng p 3571870 html 一 server端安装 1 下载 https github com MSOpenTech redis 可看到当前可下载版本 redis2
  • SDN NSX-T 配置load balance

    配置负载均衡 创建一个T1网关 选择Edge池分配大小 配置T1服务接口 展开 服务接口 单击 设置 配置服务接口的名称 IP地址 连接的分段 配置完成后点击 保存 在NSX T Manager中 转到 网络 gt 网络服务 gt 负载均衡
  • 满二叉树等长路径

    满二叉树等长路径 给定一个深度为 n 的满二叉树 其 2n 11 个顶点的编号为 1 2n 11 树的根节点为 1 号节点 除根节点外 第 i 号节点的父节点为第 i2 号节点 例如 当 n 3 时 二叉树如下所示 树中每条边的长度已知 由
  • 图的广度优先搜索(bfs)

    图的广度优先搜索 Broad First Search 所谓的深度优先搜索 指的是在搜索时 如果遇到一个结点既有子结点 又有兄弟结点 那么先找兄弟结点 然后找子结点 类似于一个分层搜索的过程 广度优先遍历需要使用一个队列以保持访问过的结点的