【搜索与图论】BFS(广度优先搜索)

一、定义

从起始节点开始,首先访问所有与起始节点距离为 1 的邻居节点,然后依次访问距离为 2、距离为 3...... 的节点,直到遍历完整个图或找到目标节点为止。

二、核心原理

BFS 算法通常依赖**队列(Queue)**这一数据结构来维护待访问节点的顺序。

使用bfs算法处理的不管是图、树,还是迷宫问题,本质都是"队列+访问标记"的组合,

  1. 初始化:创建一个队列,将「起始节点」加入队列,并标记该节点为"已访问";
  2. 循环: 只要队列不为空,就执行以下操作:
    1. **出队:**取出队列头部的节点(当前节点);
    2. **处理:**对当前节点进行需要的操作(比如记录路径、判断是否是目标节点);
    3. **入队:**找到当前节点的所有"未访问"的邻居节点,标记为"已访问",并依次加入队列;
  3. **终止:**当队列为空,或者找到目标节点时,遍历结束。

三、例题

走迷宫

题目描述(来源于AcWing)

思路

  1. 用二维数组 g[N][N] 存迷宫地图(0 能走,1 是墙),dist[N][N] 存每个点到起点的距离,用队列 queue<PII> 存待遍历的坐标,用方向数组 dx[]、dy[] 控制上下左右移动。

  2. 初始化

    1. 把所有点的距离初始化为 -1(表示没走过)

    2. 起点 (1,1) 入队

    3. 起点距离设为 0(自己到自己步数为 0)

  3. bfs搜索**(只要队列不为空,就重复)**

    1. 取出队头坐标,作为当前位置

    2. 往上下左右 4 个方向尝试走一步

    3. 对下一步坐标做 3 个判断:

      • 没越界

      • 没走过(dist = -1)

      • 不是墙(g = 0)

    4. 满足条件就:

      • 记录距离 = 当前距离 + 1

      • 把新坐标加入队列

    5. 如果走到终点 (n,m),直接返回距离(BFS 第一次到达就是最短)

代码

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

typedef pair<int, int> PII;// 存储坐标
const int N = 110;
int n, m;
int g[N][N];//用于存储地图
int dist[N][N];//用于存储每个点到起点的距离
queue<PII> q; 
//定义方向数组
int dx[] = {-1,0,1,0};
int dy[] = {0,1,0,-1};

//两个参数是起点的坐标
int bfs(int x, int y){
    //初始化所有点到起点的距离为-1   ----这里使用memset函数
    memset(dist, -1, sizeof(dist));
    //起点入队列
    q.push({x,y});
    //修改距离数组
    dist[x][y] = 0;
    
    //当队列不为空的时候开始广度搜索
    while(!q.empty()){
        //取出队头
        auto t = q.front();
        //出队
        q.pop();
        
        //进行向上下左右四个方向走
        for(int i = 0; i < 4; i++){
            //求出下一步的横纵坐标
            int a = t.first + dx[i];
            int b = t.second + dy[i];
            
            //判断是否越界
            if(a < 1 || a > n || b < 1 || b > m){
                continue;
            }
            //判断该点是否已经走过
            if(dist[a][b] > -1){
                continue;
            }
            //判断g数组是否为0
            if(g[a][b] != 0){
                continue;
            }
            
            //将更新后的坐标进队列
            q.push({a,b});
            //更新距离数组
            dist[a][b] = dist[t.first][t.second] + 1;
            
            //如果已经到(n,m)了
            if(a == n && b == m){
                //返回结果
                return dist[n][m];
            }
        }
    }
    //返回距离
    return dist[n][m];
}
int main(){
    cin>>n>>m;
    
    //输入地图
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            cin>>g[i][j];
        }
    }
    
    //广度优先搜索--- 得到最少移动次数
    int res = bfs(1,1);
    
    //输出结果
    cout<< res <<endl;
}

四、总结

如果每条边的权重都相等,则bfs算法可以求的最短路。

相关推荐
yi0113 小时前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
灯澜忆梦5 小时前
【面向对象编程C++】| 基础语法
java·c++·算法
小蒋观天下6 小时前
专项方案:大场景港口AI安防、多干扰环境下的算法调优与落地实操
人工智能·深度学习·算法·安全·机器学习·计算机视觉·ai大模型
Evand J6 小时前
【电机滤波例程5】渐消因子自适应扩展卡尔曼滤波(EKF),MATLAB。PMSM负载突变下的状态估计。附下载链接
算法·matlab
H.莓飛6 小时前
【数据结构】二叉树_OJ题
linux·开发语言·数据结构·算法
好想像大佬一样能够ak所有7 小时前
Leetcode35.搜索插入位置
数据结构·算法·leetcode
aqiu1111117 小时前
【C++算法打怪专栏】LeetCode 165. 比较版本号(双指针与字符串流法)
c++·算法·leetcode
黄金龙PLUS7 小时前
如何基于置换算法来设计对称加密算法
算法·网络安全·密码学·哈希算法·同态加密
不会就选b7 小时前
算法日常・每日刷题--<动态规划>14
算法
赛博守夜人7 小时前
跨境业务与出海合规之九:海外买量投放与营销虚假流量(Ad Fraud):跨国机房群控与归因欺诈识别算法
算法·安全