迷宫路径搜索:广度优先搜索(BFS)

迷宫路径搜索:广度优先搜索(BFS)详解


1. 什么是广度优先搜索(BFS)?

广度优先搜索(BFS) 是一种在图或网格结构中逐层扩展节点的搜索算法,适合用于解决最短路径问题。
特点

  1. 逐层扩展:按距离从近到远逐层访问节点。
  2. 最短路径保证:在无权图中,BFS找到的路径总是最短的。
  3. 依赖队列结构:利用队列先进先出的特性来实现节点扩展。

在迷宫中,BFS 的应用如下:

  • 每个格子视为一个节点。
  • 上、下、左、右为节点之间的邻接关系。
  • 起点到终点的最短路径可以通过 BFS 找到。

2. BFS解决迷宫路径问题的步骤
  1. 初始化队列:将起点加入队列。
  2. 标记访问:避免重复访问,记录已访问的节点。
  3. 逐步扩展:从当前节点扩展到其四个方向的邻居,加入队列。
  4. 路径记录:通过辅助数组 prev 记录路径中的前驱节点,用于反推完整路径。
  5. 终止条件:找到终点(出口)时停止搜索。
  6. 路径反推:从终点开始,根据前驱节点反向回溯到起点,得到最短路径。

3. BFS代码实现(完整代码)
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>using namespace std;// 定义方向
const int DIRECTIONS[4][2] = {{0, 1},  // 右{1, 0},  // 下{0, -1}, // 左{-1, 0}  // 上
};// 迷宫状态
const int PATH = 0;     // 可行路径
const int WALL = 1;     // 墙
const int VISITED = 2;  // 已访问// BFS 实现
bool bfsShortestPath(vector<vector<int>>& maze, int rows, int cols, vector<pair<int, int>>& path) {if (maze.empty() || maze[0][0] == WALL || maze[rows - 1][cols - 1] == WALL) {return false; // 起点或终点是墙}// 定义队列,存储当前坐标queue<pair<int, int>> q;q.push({0, 0});// 辅助数组记录前驱节点vector<int> prev(rows * cols, -1); // -1 表示无前驱maze[0][0] = VISITED; // 标记起点已访问// BFS 主循环while (!q.empty()) {auto [x, y] = q.front();q.pop();// 判断是否到达出口if (x == rows - 1 && y == cols - 1) {// 反推路径int idx = x * cols + y;while (idx != -1) {path.push_back({idx / cols, idx % cols});idx = prev[idx];}reverse(path.begin(), path.end()); // 路径从起点到出口return true;}// 扩展四个方向for (auto [dx, dy] : DIRECTIONS) {int nx = x + dx, ny = y + dy;// 检查边界条件和访问状态if (nx >= 0 && nx < rows && ny >= 0 && ny < cols && maze[nx][ny] == PATH) {maze[nx][ny] = VISITED; // 标记已访问q.push({nx, ny});       // 新节点入队prev[nx * cols + ny] = x * cols + y; // 记录前驱}}}return false; // 无法到达出口
}int main() {// 输入迷宫vector<vector<int>> maze = {{0, 0, 1, 0, 0},{0, 1, 0, 1, 0},{0, 0, 0, 0, 1},{1, 1, 1, 0, 0},{0, 0, 0, 1, 0}};int rows = maze.size();int cols = maze[0].size();vector<pair<int, int>> path; // 用于存储路径// 执行 BFSif (bfsShortestPath(maze, rows, cols, path)) {cout << "找到最短路径:" << endl;for (const auto& p : path) {cout << "(" << p.first << ", " << p.second << ") ";}cout << endl;} else {cout << "无法到达终点" << endl;}return 0;
}

4. 代码详解
  1. 初始化数据

    • 迷宫表示maze 是输入的二维数组,0 表示路径,1 表示墙。
    • 起点和终点:起点为 (0, 0),终点为 (rows - 1, cols - 1)
    • 辅助数据结构
      • queue 用于存储待处理的节点。
      • prev 数组记录路径信息。
  2. BFS 主循环

    • 每次从队列中取出一个节点,扩展其四个方向的邻居。
    • 若扩展的节点是可行路径(未访问且不为墙),将其加入队列,并记录前驱节点。
    • 当队列为空或找到终点时,退出循环。
  3. 路径反推

    • 若找到出口,则通过 prev 数组从终点反推到起点,得到完整路径。
    • 使用 reverse 函数将路径反转,从起点到终点输出。
  4. 终止条件

    • 若在扩展过程中找到出口,立即结束搜索。
    • 若队列为空且未找到出口,则无解。

5. 示例运行

输入迷宫:

0 0 1 0 0
0 1 0 1 0
0 0 0 0 1
1 1 1 0 0
0 0 0 1 0

输出结果

找到最短路径:
(0, 0) (0, 1) (1, 2) (2, 2) (2, 3) (3, 3) (4, 3) (4, 4)

6. 时间和空间复杂度
  1. 时间复杂度

    • 每个节点最多访问一次,每次访问最多检查四个方向。
    • 假设迷宫大小为 ( n \times m ),则时间复杂度为 ( O(n \times m) )。
  2. 空间复杂度

    • 队列最多存储 ( O(n \times m) ) 个节点。
    • prev 数组的大小为 ( O(n \times m) )。
    • 总空间复杂度为 ( O(n \times m) )。

7. BFS的优势与改进

优势

  1. 保证最短路径:逐层扩展,路径最短。
  2. 简单高效:使用队列和循环即可实现。

改进方向

  1. 双向 BFS:同时从起点和终点进行搜索,缩短搜索时间。
  2. 启发式搜索:结合 A* 算法,引入代价估计函数(如曼哈顿距离),适合大规模图。

8. 总结

通过 BFS,可以高效解决迷宫路径搜索问题。其核心逻辑是逐层扩展节点,记录访问状态与前驱关系,最终反推路径。完整代码实现了从输入迷宫到输出路径的全过程,便于理解和实践。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/63278.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AIGC 012-Video LDM-更进一步,SD作者将LDM扩展到视频生成任务!

AIGC 012-Video LDM-Stable Video diffusion前身&#xff0c;将LDM扩展到视频生成任务&#xff01; 文章目录 0 论文工作1论文方法实验结果 0 论文工作 Video LDM作者也是Stable diffusion的作者&#xff0c;作者在SD的架构上进行扩展&#xff0c;实现了视频的生成。后续在Vid…

openstack创建浮动IP全过程

1、创建外部网络&#xff0c;即是provider网络&#xff0c;有关provider网络的详细解释请参见我之前的文章openstack中的self-service和provider网络_openstack provider网络不能创建vlan吗-CSDN博客 network create --share --external --provider-physical-network physnet1…

ABAP DIALOG屏幕编程1

一、DIALOG屏幕编程 DIALOG屏幕编程是SAP ABAP中用于创建用户交互界面的一种技术&#xff0c;主要用于开发事务性应用程序。它允许用户通过屏幕输入或操作数据&#xff0c;程序根据用户的操作执行逻辑处理。 1、DIALOG编程的主要组件 a、屏幕 (Screen) DIALOG程序的核心部分…

Anaconda升级的解决方法

文章目录 关于conda升级问题1. 在原Anaconda版本上进行更新升级2. 就是重装Anaconda 镜像源配置的参数解释&#xff1a;1. conda-forge2. bioconda3. menpo 关于conda升级问题&#xff0c; Anaconda各种版本镜像下载地址&#xff1a; 关于conda升级问题 1. 在原Anaconda版本上…

服务路由和服务发现区别是什么?

要快速学习服务路由和服务发现的区别&#xff0c;以下是这个领域最重要的20%的知识&#xff1a; 服务路由&#xff08;Service Routing&#xff09; 定义&#xff1a;服务路由是微服务架构中的一个关键概念&#xff0c;涉及将客户端的请求路由到合适的服务实例上。在分布式系…

青训营-豆包MarsCode技术训练营试题解析二十七

介绍 ‌豆包青训营‌是由字节跳动和稀土掘金社区共同发起的技术培训和人才选拔项目。该项目的目标是培养具有职业竞争力的优秀开发工程师&#xff0c;并提供全程免费的课程&#xff0c;不收取任何费用‌。 课程内容和方向 豆包青训营的课程涵盖前端、后端和AI方向。在这个飞…

网络安全之信息收集

1、大纲 基本信息收集  网站后台查找 域名查找    整站分析 敏感目录    Googlehacker 端口扫描    URL采集 旁站C段    信息分析 CDN绕过方法 2、域名信息 对应IP收集 相关域名对应IP 站长之家-->站长工具 nslookup&#xff08;在cmd里面使用&…

人工智能学习用的电脑安装cuda、torch、conda等软件,版本的选择以及多版本切换

接触人工智能的学习三个月了&#xff0c;每天与各种安装包作斗争&#xff0c;缺少依赖包、版本高了、版本低了、不兼容了、系统做一半从头再来了。。。这些都是常态。三个月把单位几台电脑折腾了不下几十次安装&#xff0c;是时候总结一下踩过的坑和积累的经验了。 以一个典型的…

乐橙云小程序插件接入HbuilderX

乐橙插件使用&#xff1a; 1.配置app.json文件&#xff0c;uniapp中在mainfest.json中配置 https://uniapp.dcloud.net.cn/collocation/manifest.html#mp-weixin ** 2、集成插件页面.json文件 ** uniapp在 pages.json 对应页面的 style -> usingComponents 引入组件&…

华为关键词覆盖应用市场ASO优化覆盖技巧

在我国的消费者群体当中&#xff0c;华为的品牌形象较高&#xff0c;且产品质量过硬&#xff0c;因此用户基数也大。与此同时&#xff0c;随着影响力的增大&#xff0c;华为不断向外扩张&#xff0c;也逐渐成为了海外市场的香饽饽。作为开发者和运营者&#xff0c;我们要认识到…

C#白盒测试(二)

在前两篇关于 C#白盒测试的学习博客中&#xff0c;我们已经对基础概念、常见结构测试以及一些工具的使用有了一定了解。今天&#xff0c;我们将聚焦于白盒测试中的数据驱动测试、测试替身以及如何优化测试套件&#xff0c;进一步提升我们的白盒测试能力。 一、数据驱动测试 在…

K8S疑难概念理解——容器运行时。CRI实现从Docker切为containerd历史

早期版本的k8s直接使用了docker部分功能&#xff0c;比如容器的创建、运行、监控、停止、销毁等&#xff0c;这一些与容器生命周期相关的逻辑实现就可称之为容器运行时。k8s意识到docker过于笨重&#xff0c;如docker-cli,docker swarm等组件k8s都用不上&#xff0c;那么能不能…

Vue+Vite 组件开发的环境配置(超级简单)

vite是什么 Vite 是一个现代化的前端构建工具和开发服务器&#xff0c;它特别适用于构建大型的单页面应用&#xff08;SPA&#xff09;。Vite 旨在提供极快的冷启动速度&#xff0c;并且能够即时地&#xff08;几乎实时地&#xff09;更新模块&#xff0c;这得益于其利用原生 …

vue拖拽图片

这是我封装的组件大家直接用就好 我的gitee仓库地址 拖拽(父子) 刘志辉/vue功能 - 码云 - 开源中国 //使用页面参考文档 //标签内 :imgSrc"../img/tibet-1.jpg" <!-- 设置图片路径 --> dragstart"handleDragStart" <!-- 监听拖拽开始…

GNU/Linux - make 60s介绍

Learn make in 60 seconds. A programmer needs a build system. 想想你要手动输入编译命令编译每一个源文件&#xff0c;而且要正确添加和管理各个option&#xff0c;是很麻烦的。有各种用来帮助你build的工具&#xff0c;比如ant、make、maven、rake等。Make就是最通用的一…

C05S01-Web基础和HTTP协议

一、Web基础 1. Web相关概念 1.1 URL URL&#xff08;Uniform Resource Locator&#xff0c;统一资源定位符&#xff09;&#xff0c;是一种用于在互联网上标识和定位资源的标准化地址&#xff0c;提供了一种访问互联网上特定资源的方法。URL的基本格式如下所示&#xff1a;…

Spring+Mybatis 整合所需准备

文章目录 SpringMybatis SpringMybatis 准备pom.xml 项目所需jar文件 <spring.version>4.0.2.RELEASE</spring.version> <!-- spring框架包 --><dependency><groupId>org.springframework</groupId><artifactId>spring-test</a…

Spring中Bean的作用域深入剖析与技术实践

前言 Spring框架作为Java企业级应用开发中的中流砥柱&#xff0c;提供了强大的依赖注入&#xff08;DI&#xff09;和面向切面编程&#xff08;AOP&#xff09;等功能。在Spring框架中&#xff0c;Bean的作用域&#xff08;Scope&#xff09;是一个非常重要的概念&#xff0c;…

从仪表盘探索 MongoDB 关键指标

这是 MongoDB 监控系列文章的第七篇&#xff0c;前面几篇文章的链接如下&#xff1a; MongoDB 监控&#xff08;一&#xff09;MongoDB 监控&#xff08;二&#xff09;MongoDB 监控&#xff08;三&#xff09;MongoDB 监控&#xff08;四&#xff09;MongoDB 监控&#xff08…

mac安装php和xdebug调试

要在Mac上安装PHP 7.4&#xff0c;你可以通过几种方式来完成&#xff0c;但鉴于PHP7.4官方已不再维护&#xff0c;并且Homebrew默认仓库中不再提供此版本&#xff0c;我们需要从第三方仓库或直接从源代码进行安装。本文以brew方式安装&#xff0c;如果安装的是8.0以上&#xff…