GESP6级C++考试语法知识(二十七、广度优先搜索(二、二维BFS))


第二课《迷宫王国大冒险------二维 BFS》


🌟一、故事开始:迷宫王国的宝藏

1、很久以前,在:

🏰「迷宫王国」里,

藏着一颗神秘宝石。


2、小骑士阿勇接到了任务:

找到宝藏!


3、可是问题来了:

迷宫里:

  • 有墙壁

  • 有陷阱

  • 有死胡同


4、而且:

阿勇必须走最短路线!


5、于是,他想:

"这次不能用 DFS 乱冲了!"

因为:

DFS 容易:

复制代码
一条路冲到底

结果绕远路。


6、这次应该使用BFS的方法:

于是他按照BFS方法,上路了。


🌟二、今天同学们要学什么?

今天是:

🌟二维 BFS!


上一课:

我们在一维"数字线"上移动。

今天:

我们进入:

🗺️二维地图!


🌟三、认识地图坐标

1、假设地图长这样:

复制代码
S . . #
# . . .
. . # E

2、这里:

复制代码
S = 起点
E = 终点
# = 墙
. = 可以走

3、🌟地图中的位置怎么表示?

使用:

坐标!


4、例如:

复制代码
(行, 列)

比如:

(1) 左上角:

复制代码
(0,0)

(2) 终点:

复制代码
(2,3)

🌟四、在地图里怎么移动?

小骑士每次可以:


⬆️上

⬇️下

⬅️左

➡️右


这叫:

四方向移动


🌟五、方向数组

这是 BFS 的经典的技巧!


1、🌟方向数组

复制代码
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

2、🌟什么意思?


(1)第0个方向

复制代码
(-1, 0)

表示:

向上走


(2)第1个方向

复制代码
(1, 0)

表示:

向下走


(3)第2个方向

复制代码
(0, -1)

表示:

向左走


(4)第3个方向

复制代码
(0, 1)

表示:

向右走


🌟六、BFS 如何搜索迷宫?


1、假设阿勇在:

复制代码
(0,0)

2、BFS 会:


(1)第1层

搜索:

一步能到的位置。


(2)第2层

搜索:

两步能到的位置。


(3)第3层

搜索:

三步能到的位置。


3、像不像:

🌊水波扩散?


🌟七、为什么 BFS 一定最短?

这是今天最核心的问题!


1、因为:

BFS 是按层搜索的!


2、它的搜索方式:

第一层:

1步到达


第二层:

2步到达


第三层:

3步到达


.......


3、所以:


第一次到终点,

一定是最少步数!


4、这就是:

BFS 最强大的地方!


🌟八、visited 二维数组

1、上一课:

我们用:

复制代码
vis[x]

2、今天地图是二维的。

所以:

复制代码
vis[x][y]

3、表示:

复制代码
(x,y) 是否来过

4、🌟为什么必须有 visited?

否则:

阿勇会这样:

复制代码
左 → 右 → 左 → 右

无限绕圈!


🌟九、地图越界问题(初学者易错!)

1、假设地图大小:

复制代码
n 行
m 列

2、合法位置必须满足:

复制代码
0 <= x < n
0 <= y < m

3、否则:

就会:

🚫走出地图!


🌟十、第一道迷宫题


1、🎮题目

地图:

复制代码
S . . #
# . . .
. . # E

2、要求:

求最少步数


🌟十一、BFS 参考程序


复制代码
#include <iostream>
#include <queue>
using namespace std;

struct Node
{
    int x;
    int y;
    int step;
};

char mp[105][105];

bool vis[105][105];

int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

int main()
{
    int n = 3;
    int m = 4;

    // 地图
    char temp[3][4] =
    {
        {'S','.','.','#'},
        {'#','.','.','.'},
        {'.','.','#','E'}
    };

    // 复制地图
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            mp[i][j] = temp[i][j];
        }
    }

    queue<Node> q;

    // 起点
    q.push({0,0,0});

    vis[0][0] = true;

    while(!q.empty())
    {
        Node cur = q.front();
        q.pop();

        int x = cur.x;
        int y = cur.y;

        // 到达终点
        if(mp[x][y] == 'E')
        {
            cout << "最少步数:" << cur.step << endl;
            return 0;
        }

        // 枚举四个方向
        for(int i = 0; i < 4; i++)
        {
            int nx = x + dx[i];
            int ny = y + dy[i];

            // 判断是否合法
            if(nx >= 0 && nx < n &&
               ny >= 0 && ny < m &&
               !vis[nx][ny] &&
               mp[nx][ny] != '#')
            {
                vis[nx][ny] = true;

                q.push({nx, ny, cur.step + 1});
            }
        }
    }

    cout << "无法到达终点" << endl;

    return 0;
}

🌟十二、程序执行过程


1、开始:

复制代码
(0,0)

进入队列。


2、然后扩展:

复制代码
(0,1)

3、再扩展:

复制代码
(1,1)
(0,2)

4、继续:

像水波一样。


5、最终:

第一次到达:

复制代码
E

时,

一定最短!


🌟十三、二维 BFS 模板


🌊二维 BFS 四步法


第一步

起点入队。


第二步

取出队头。


第三步

枚举四个方向。


第四步

合法就入队。


🌟十四、新手易犯的错误


❌错误1:忘记 visited

会无限循环。


❌错误2:忘记判断边界

数组越界。


❌错误3:墙壁也进入队列

必须:

复制代码
mp[nx][ny] != '#'

❌错误4:step 不加1

下一层步数必须:

复制代码
cur.step + 1

🌟十五、什么时候想到二维 BFS?

以后看到:


1、🏰迷宫


2、🛣️最短路径


3、🚶最少移动次数


4、🌊扩散问题


5、🔥火焰蔓延


6、🦠病毒感染


🌟就要想到:

BFS!是不是可以!


⚔️十六、课堂挑战题 ⚔️


🎮挑战1

地图:

复制代码
S . #
. . .
# . E

求最少步数。


🎮挑战2

如果:

小骑士还能:

斜着走

怎么办?


提示:

方向数组要改成:

八方向!


🌟十七、本课总结


1、🌊二维 BFS 的本质:

在地图上进行层层扩散!


2、📦BFS 的核心工具:

queue 队列


3、🧭方向数组:

专门处理移动方向


4、🚪第一次到终点:

一定最短!


5、🛑visited 必不可少:

防止重复进入!


🌟今天同学们真正学会的:

不只是走迷宫的方法。

而要掌握:

"地图中的最短路思维"。

相关推荐
北域码匠6 小时前
SHA-1算法:安全哈希原理与应用解析
算法·c#·哈希算法
坚果派·白晓明7 小时前
【鸿蒙PC】SDL3 移植:AtomCode Skills 4 步速通多媒体库适配
c++·华为·ai编程·harmonyos·atomcode·c/c++三方库
手写码匠7 小时前
手写 GraphRAG:从零实现图增强检索增强生成系统
人工智能·深度学习·算法·aigc
BomanGe17 小时前
NSK重载高刚性滚珠丝杠技术详解
经验分享·算法·规格说明书
赴生-8 小时前
C++进阶 C++11(下)
开发语言·c++
有点。8 小时前
C++(贪心算法一)
c++·贪心算法
Matrix_118 小时前
手机里的计算摄影:广角形变校正算法
人工智能·算法·智能手机·计算摄影
WBluuue8 小时前
数据结构与算法:有序表(二):跳表
数据结构·c++·算法·skiplist
赴生-8 小时前
C++进阶 异常
开发语言·c++
x138702859579 小时前
c语言中srtlen(指针使用计算字符长度)、传值和传址调用
c语言·开发语言·算法·visual studio