【数据结构】广度优先遍历(BFS)模板及其讲解

这篇具有很好参考价值的文章主要介绍了【数据结构】广度优先遍历(BFS)模板及其讲解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🎊专栏【数据结构】

🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。

🎆音乐分享【勋章】

大一同学小吉,欢迎并且感谢大家指出我的问题🥰

目录

 文章来源地址https://www.toymoban.com/news/detail-458903.html

🎁定义

🎁遍历方法 

🎁根据题目来理解BFS

🏳️‍🌈走迷宫

🏳️‍🌈思路

🏳️‍🌈代码(BFS模板)

🏳️‍🌈分析


 

🎁定义

        BFS 全称是 Breadth-First-Search,即广度优先搜索。它是一种图遍历算法,在搜索时先访问起始顶点的所有邻居顶点,然后再依次访问这些邻居顶点的邻居顶点,直到遍历完整个图。这种算法可以用来寻找两个节点之间的最短路径,也可以用于树的遍历等其他场景。

        BFS 通常使用队列来实现,从起始顶点开始,将其加入队列中,然后访问它的邻居顶点,并将其加入队列尾部。接着将队列头部的顶点出队并访问其邻居顶点,将未访问的邻居顶点加入队列中,直到队列为空为止。

        BFS 算法在运行时,由于是逐层遍历,因此每一层的节点都会被访问,遍历到的第一个目标节点所在的层数也就是最短距离,因此 BFS 算法可以用来求解无权图的最短路径问题。

🎁遍历方法 

如下图所示

【数据结构】广度优先遍历(BFS)模板及其讲解

由于是逐层遍历,那么遍历顺序是 1 -> 2 -> 3 -> 4 -> 5 - > 6 -> 7 - > 8

🎁根据题目来理解BFS

🏳️‍🌈走迷宫

给定一个n*m的二维整数数组,用来表示一个迷宫,数组中只包含0或1,其中0表示可以走的路,1表示不可通过的墙壁。

最初,有一个人位于左上角(1, 1)处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。

请问,该人从左上角移动至右下角(n, m)处,至少需要移动多少次。

数据保证(1, 1)处和(n, m)处的数字为0,且一定至少存在一条通路。

输入格式

第一行包含两个整数n和m。

接下来n行,每行包含m个整数(0或1),表示完整的二维数组迷宫。

输出格式

输出一个整数,表示从左上角移动至右下角的最少移动次数。

数据范围

1≤n,m≤100


输入样例:
5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
输出样例:
8

🏳️‍🌈思路

        从起点开始,往前走第一步,记录下所有第一步能走到的点,然后从所第一步能走到的点开始,往前走第二步,记录下所有第二步能走到的点,重复下去,直到走到终点。输出步数即可。

🏳️‍🌈代码(BFS模板)

#include <cstring>   // 处理内存块的头文件
#include <iostream>  // 标准输入输出头文件
#include <algorithm> // STL 常用算法头文件
#include <queue>     // 队列头文件

using namespace std;  // 命名空间

typedef pair<int, int> PII;  // 定义 pair 类型

const int N = 110;  // 设定二维数组的大小

int n, m;           // n 和 m 分别代表二维数组的行和列
int g[N][N], d[N][N];  // g 表示从输入中读取的二维数组信息,d 用来记录遍历每个点的距离

int bfs()  // BFS 算法主函数
{
    queue<PII> q;  // 定义一个队列,队列中的元素是 pair 类型的变量

    memset(d, -1, sizeof d);  // 初始化距离数组 d 数组的值都设置为 -1,表示还未遍历到
    d[0][0] = 0;  // 起点格子的距离设置为 0
    q.push({0, 0});  // 将起点的坐标加入队列中

    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};  // 定义上右下左四个方向的移动距离

    while (q.size())  // 队列不为空
    {
        auto t = q.front();  // 取出队首元素,并标记当前这个点已经访问过了
        q.pop();

        for (int i = 0; i < 4; i ++ )  // 尝试四个方向的移动
        {
            int x = t.first + dx[i], y = t.second + dy[i];  // 计算出移动后的点的坐标

            if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1)  // 如果移动后的点满足条件(没有越界、不是障碍、且未遍历到)
            {
                d[x][y] = d[t.first][t.second] + 1;  // 更新移动后的点的距离
                q.push({x, y});  // 将新的点加入队列
            }
        }
    }

    return d[n - 1][m - 1];  // 返回终点的距离,即最短路径长度
}

int main()  // 主函数
{
    cin >> n >> m;  // 读入二位数组的行和列数
    for (int i = 0; i < n; i ++ )  // 读入二维数组的每一个元素
        for (int j = 0; j < m; j ++ )
            cin >> g[i][j];

    cout << bfs() << endl;  // 调用 BFS 算法函数,输出最少需要多少步才能从起点走到终点

    return 0;  // 返回运行成功标志
}

🏳️‍🌈分析

~用 g 存储地图,f存储起点到其他各个点的距离。
~从起点开始广度优先遍历地图。
~当地图遍历完,就求出了起点到各个点的距离,输出d[n][m]即可。

【数据结构】广度优先遍历(BFS)模板及其讲解


 while (q.size())  // 队列不为空
 {
        auto t = q.front();  // 取出队首元素,并标记当前这个点已经访问过了
        q.pop();

        for (int i = 0; i < 4; i ++ )  // 尝试四个方向的移动
        {
            int x = t.first + dx[i], y = t.second + dy[i];  // 计算出移动后的点的坐标

            if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1)  // 如果移动后的点满足条件(没有越界、不是障碍、且未遍历到)
            {
                d[x][y] = d[t.first][t.second] + 1;  // 更新移动后的点的距离
                q.push({x, y});  // 将新的点加入队列
            }
        }
    }

上面这一段代码就是来寻找下一步要走的路,尝试四个方向的移动,int x = t.first + dx[i], y = t.second + dy[i];  计算出移动后的点的坐标,判断4个方向是否满足移动条件【if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1)  没有越界、不是障碍、且未遍历到)】,如果找到了,就 d[x][y] = d[t.first][t.second] + 1;更新移动后的点的距离(距离+1),并且 q.push({x, y});   将新的点加入队列,标记这一点,表示这个点已经访问过了

🥰如果大家有不明白的地方,或者文章有问题,欢迎大家在评论区讨论,指正🥰   

 

到了这里,关于【数据结构】广度优先遍历(BFS)模板及其讲解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构第十六天(二叉树层序遍历/广度优先搜索(BFS)/队列使用)

    目录 前言 概述 接口 源码 测试函数 运行结果 往期精彩内容 从前的日色变得慢,车,马,邮件都慢,一生,只够爱一个人。 二叉树的层序遍历可以使用广度优先搜索(BFS)来实现。具体步骤如下: 创建一个队列 queue,并将根节点入队。 当队列不为空时,重复执行以下步骤:

    2024年02月22日
    浏览(37)
  • 大话数据结构-图的深度优先遍历和广度优先遍历

      图的遍历分为深度优先遍历和广度优先遍历两种。   深度优先遍历(Depth First Search),也称为深度优先搜索,简称DFS,深度优先遍历,是指从某一个顶点开始,按照一定的规则,访问并记录下一个未访问顶点。对于非连通图,则是按连通分量,采用同一规则进行深度优

    2024年02月04日
    浏览(58)
  • 【数据结构】图的广度优先遍历

    广度优先遍历,类似于树的层次遍历,又是熟悉的队列实现。首先将第一个顶点添加到队列中,然后讲该顶点的所有邻接顶点都加入队列中,再将该顶点输出。如此重复直到遍历完整个图。 Q:队列,用于存放顶点。 front,rear:队头和队尾指针,用于入队和出队。 p:工作指针,用

    2024年02月05日
    浏览(50)
  • 数据结构--5.3图的遍历(广度优先遍历)

    广度优先遍历:         广度优先遍历(BreadthFirstSearch),又称为广度优先搜索,简称BFS。 要实现对图的广度遍历,我们可以利用队列来实现。  (参考队列)(上述为结构)

    2024年02月10日
    浏览(48)
  • (超详细)C++图的深度优先遍历、广度优先遍历(数据结构)

            根据下图,编写代码实现图的深度优先遍历和广度优先遍历。          按照英文字母顺序,以邻接表为存储结构,实现图的深度优先和广度优先遍历。遍历的顺序从顶点a开始。 以用户指定的结点为起点,分别输出每种遍历下的结点访问序列。   (1)从顶点a,

    2024年02月08日
    浏览(61)
  • 【数据结构与算法】搜索算法(深度优先搜索 DFS和广度优先搜索 BFS)以及典型算法例题

    【数据结构与算法】系列文章链接: 【数据结构与算法】递推法和递归法解题(递归递推算法典型例题) 【数据结构与算法】系列文章链接: 【数据结构与算法】C++的STL模板(迭代器iterator、容器vector、队列queue、集合set、映射map)以及算法例题 【数据结构与算法】系列文章链

    2024年04月13日
    浏览(78)
  • 【数据结构与算法】图的深度优先和广度优先遍历

    😊😊作者简介😊😊 : 大家好,我是南瓜籽,一个在校大二学生,我将会持续分享Java相关知识。 🎉🎉个人主页🎉🎉 : 南瓜籽的主页 ✨✨座右铭✨✨ : 坚持到底,决不放弃,是成功的保证,只要你不放弃,你就有机会,只要放弃的人,他肯定是不会成功的人。 图是一

    2024年02月02日
    浏览(58)
  • 【数据结构】图的创建(邻接矩阵,邻接表)以及深度广度遍历(BFS,DFS)

    图是由顶点集合及顶点间的关系组成的一种数据结构:G = (V, E),其中: 顶点集合V = {x|x属于某个数据对象集}是有穷非空集合; E = {(x,y)|x,y属于V}或者E = {x, y|x,y属于V Path(x, y)}是顶点间关系的有穷集合,也叫 做边的集合。 完全图:在有n个顶点的无向图中,若有n * (n-1)/2条边,

    2024年02月04日
    浏览(45)
  • 【数据结构】二叉树的·深度优先遍历(前中后序遍历)and·广度优先(层序遍历)

    💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃 个人主页 :阿然成长日记 👈点击可跳转 📆 个人专栏: 🔹数据结构与算法🔹C语言进阶 🚩 不能则学,不知则问,耻于问人,决无长进 🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍 (1) 先序遍历 的过

    2024年01月24日
    浏览(45)
  • 数据结构学习笔记——图的遍历算法(深度优先搜索和广度优先搜索)

    图的遍历指从图中某一顶点出发(任意一个顶点都可以作为访问的起始顶点),按照某种遍历方法,对图中所有的顶点访问一次且只访问一次。图与树不一样,其中一个顶点可能与多个顶点相连,所以需记录已访问过的顶点,当访问一个顶点后,考虑如何选取下一个要访问的

    2024年02月05日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包