广度优先遍历搜索迷宫最短路径
思路分析
由于广度是扩散逐层的方式遍历,相当于是多条路同时跑,最后先到终点就是最短路径了。
广度优先搜索主要使用队列来进行处理
路径用一个单独的vector
存储,每一个点的坐标由二维转为一维,如(2, 3)存储在vector中下标为2*col + 3,这个位置存储到达(2, 3)的节点,即每个位置存储上个节点的位置。
测试用例
请输入迷宫的行列数(例如:10 10):6 6
请输入迷宫的路径信息(0表示可以走,1表示不能走):
0 0 1 1 1 1
1 0 0 0 0 1
1 0 1 1 0 1
1 0 0 0 0 1
1 0 1 1 1 1
1 0 0 0 0 0
结果为:
* * 1 1 1 1
1 * 0 0 0 1
1 * 1 1 0 1
1 * 0 0 0 1
1 * 1 1 1 1
1 * * * * *
如果用深度优先搜索则答案路径不是最短。为
* * 1 1 1 1
1 * * * * 1
1 0 1 1 * 1
1 * * * * 1
1 * 1 1 1 1
1 * * * * *
完整代码
#include <iostream>
#include <stack>
#include <queue>
using namespace std;// 用栈来模拟递归的dfs
// 定义迷宫每个节点的四个方向,从右开始,顺时针
const int RIGHT = 0;
const int DOWN = 1;
const int LEFT = 2;
const int UP = 3;// 迷宫每个节点方向的数量
const int WAY_NUM = 4;// 定义节点向某个方向行走是否可行
const int YES = 4;
const int NO = 5;class Maze
{
public:Maze(int row, int col): _row(row), _col(col){// 二维数组的创建_pMaze = new Node * [_row];for (int i = 0; i < _row; ++i){_pMaze[i] = new Node[_col];}// 将到达(i,j)的节点对象存入 _pPath[i * _row + j]_pPath.resize(_row * _col);}// 初始化迷宫每个节点对象void initNode(int x, int y, int val){_pMaze[x][y]._x = x;_pMaze[x][y]._y = y;_pMaze[x][y]._val = val;// 节点四个方向默认初始化for (int i = 0; i < WAY_NUM; ++i){_pMaze[x][y]._state[i] = NO;}}// 初始化迷宫0节点的四个方向的可达性void setNodeState(){for (int i = 0; i < _row; ++i){for (int j = 0; j < _row; ++j){//cout << "(" << _pMaze[i][j]._x << "," << _pMaze[i][j]._y << ") ";// (i,j) 本身就不可达if (_pMaze[i][j]._val == 1){continue;}//(i, j) 四个方向的可达性设置// 右侧可达性if (j < _col - 1 && _pMaze[i][j + 1]._val == 0){_pMaze[i][j]._state[RIGHT] = YES;}// 下方可达性if (i < _row - 1 && _pMaze[i + 1][j]._val == 0){_pMaze[i][j]._state[DOWN] = YES;}if (j > 0 && _pMaze[i][j - 1]._val == 0){_pMaze[i][j]._state[LEFT] = YES;}if (i > 0 && _pMaze[i - 1][j]._val == 0){_pMaze[i][j]._state[UP] = YES;}}cout << endl;}}// 深度搜索路径void searchMazePath(){if (_pMaze[0][0]._val == 1){return;}_queue.push(_pMaze[0][0]);while (!_queue.empty()){Node front = _queue.front();int x = front._x;int y = front._y;if (x == _row - 1 && y == _col - 1){return;}// 往右寻找if (_pMaze[x][y]._state[RIGHT] == YES){_pMaze[x][y]._state[RIGHT] = NO;// 防止再走回来_pMaze[x][y + 1]._state[LEFT] = NO;// 辅助数组中记录下一节点的行走路径信息_pPath[x * _row + y + 1] = _pMaze[x][y];_queue.push(_pMaze[x][y + 1]);if (check(_pMaze[x][y + 1])){return;}}// 往下寻找if (_pMaze[x][y]._state[DOWN] == YES){_pMaze[x][y]._state[DOWN] = NO;// 防止再走回来_pMaze[x + 1][y]._state[UP] = NO;_pPath[(x + 1) * _row + y] = _pMaze[x][y];_queue.push(_pMaze[x + 1][y]);if (check(_pMaze[x + 1][y])){return;}}// 往左寻找if (_pMaze[x][y]._state[LEFT] == YES){_pMaze[x][y]._state[LEFT] = NO;// 防止再走回来_pMaze[x][y - 1]._state[RIGHT] = NO;// 记录 到(x, y - 1) 的上一个节点_pPath[x * _row + y - 1] = _pMaze[x][y]; _queue.push(_pMaze[x][y - 1]);_queue.push(_pMaze[x][y - 1]);if (check(_pMaze[x][y - 1])){return;}}// 往上寻找if (_pMaze[x][y]._state[UP] == YES){_pMaze[x][y]._state[UP] = NO;// 防止再走回来_pMaze[x - 1][y]._state[DOWN] = NO;_pPath[(x - 1) * _row + y] = _pMaze[x][y];_queue.push(_pMaze[x - 1][y]);if (check(_pMaze[x - 1][y])){return;}}// 四个方向都无法走(可能是走过或者是值为1)_queue.pop();}}// 打印搜索结果void showMazePath(){if (_queue.empty()){cout << "不存在一条迷宫路径!" << endl;}else{// 因为_pPath存储每个节点的前一个节点// !!!从终点位置往前依次遍历找到路径int x = _row - 1;int y = _col - 1;for (;;){_pMaze[x][y]._val = '*';if (x == 0 && y == 0){break;}// 找前一个节点Node node = _pPath[x * _row + y];x = node._x;y = node._y;}for (int i = 0; i < _row; ++i){for (int j = 0; j < _col; ++j){if (_pMaze[i][j]._val == '*'){cout << "* ";}else{cout << _pMaze[i][j]._val << " ";}}cout << endl;}}}
private:// 定义迷宫每个节点的信息struct Node{int _x;int _y;int _val;int _state[WAY_NUM]; // 往四个方向走的可行性};// 检查是否到出口bool check(Node& node){return node._x == _row - 1 && node._y == _col - 1;}Node** _pMaze; // 二维数组存放迷宫int _row;int _col;queue<Node> _queue; // BFS依赖队列vector<Node> _pPath; // 记录BFS节点行走信息//stack<Node> _stack; // 用栈来代替递归进行深度搜索
};int main()
{cout << "请输入迷宫的行列数(例如:10 10):";int row, col, data;cin >> row >> col;Maze maze(row, col); // 创建迷宫对象cout << "输入迷宫的每个位置信息(0表示可以走,1表示不能走):" << endl;for (int i = 0; i < row; ++i){for (int j = 0; j < col; ++j){cin >> data;maze.initNode(i, j, data);}}// 开始设置所有节点四个方向的状态maze.setNodeState();// 从左上角开始搜索路径maze.searchMazePath();// 打印迷宫路径搜索结果maze.showMazePath();return 0;
}
相关文章:
广度优先遍历搜索迷宫最短路径
思路分析 由于广度是扩散逐层的方式遍历,相当于是多条路同时跑,最后先到终点就是最短路径了。 广度优先搜索主要使用队列来进行处理 路径用一个单独的vector存储,每一个点的坐标由二维转为一维,如(2, 3)存储在vector中下标为2*…...
分布式计算基础知识
分布式系统的概念 分布式系统是由多个独立计算机组成的系统,这些计算机通过网络进行通信和协作,共同完成一个任务。分布式系统的特点是具有高可用性、可扩展性和容错性。 在分布式系统中,每个计算机节点都可以独立地执行任务,同…...

Mybatis方式完成CRUD操作
Mybatis方式完成CRUD操作 文章目录 Mybatis方式完成CRUD操作1、java以Mybatis方式操作DB1.1、配置数据源-创建 resources/mybatis-config.xml1.2、创建java bean-Monster1.3、配置Mapper接口声明方法1.4、配置xxMapper,完成SQL配置,实现CRUD操作1.5、Test测试 2、需…...
css背景 background的属性作用和值
当我们在 HTML 中设置背景时,可以使用 background 属性。这个属性有多个值,可以使用不同的值来设置背景图片、背景颜色、背景位置、背景重复等等。以下是用表格列出的常见的 background 属性的值及其作用: 属性值描述background-color设置背…...
六大行文化特色知识(上)
中国六大银行都是综合性大型商业银行,业务涵盖面广泛且多元,代表着中国金融界最雄厚的资本和实力,这也是为什么很多毕业生想进国有行的原因,今天小编就带大家来了解一下关于六大行的特色知识,从如信银行考试中心平台了…...

匿名对象的特性和使用场景你知道吗?
目录 一、匿名对象的概念 二、单参数和多参数构造场景的匿名对象 ①只有一个参数的构造函数 ②多个参数的构造函数 三、使用匿名对象作为函数的参数的缺省值 四、只为调用类中的一个函数时 五、匿名对象的特性 1、匿名对象的生命周期只有一行 2、匿名对象具有常性 3、当匿…...

企业应该如何做到数字化转型成功?
01 成长型企业数字化转型的意义 成长型企业想要实现数字化转型,那么我们需要先弄明白,对于成长型企业而言,数字化转型到底具有什么意义?希望实现哪些目标? 可以归结为以下四点: 提升企业的生产力和效率&…...
PBDB Data Service:Bibliographic references for fossil collections(采集记录参考书目)
Bibliographic references for fossil collections(采集记录参考书目) 描述用法参数以下参数可用于检索与通过各种条件选择的集合关联的引用您可以使用以下参数根据书目参考文献的属性筛选结果集以下参数也可用于筛选选择以下参数可用于根据所选匹配项的…...
浅析图形验证码安全
0x01 前言 验证码的定义: 验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的…...

论文笔记:基于手机位置信息的地图匹配算法
2015计算机应用 整体思路和论文笔记:Hidden Markov Map MatchingThrough Noise and Sparseness_UQI-LIUWJ的博客-CSDN博客 很像,也是应用HMM进行地图匹配 HMMM本文 状态转移矩阵 观测概率矩阵 正态分布均值都是0,唯一不同的是S…...
因果推断系列16-面板数据与固定效应
因果推断系列16-面板数据与固定效应 1.平行趋势2.未观测变量的控制3.固定效应4.固定效应可视化5.时间效应小结加载第三方包 import warnings warnings.filterwarnings(ignore)import pandas as pd import numpy as np from matplotlib import style from matplotlib import...
第三十三章 弹性池塘2(弹城少年歌词)
熟悉的K26,熟悉的漉菽香味,熟悉的絮絮叨叨。 为什么坎迪总有那么多话想说,就算恢复正常,自己应该也找不出如滔滔江水连绵不断的语词洪流吧。 不,不是词汇量的问题。 当你习惯于将金玉良言与废屁空套话区分开来时&#…...
PMP之预测部分
引论 什么是项目 项目是为创造独特的产品、服务或成果而进行的临时性工作。 项目管理是把事办成的方法论,万物皆可项目。 项目的基本要素 项目(独特性、临时性)、驱动变更、启动背景、创造商业价值。 组织级项目管理(OPM&am…...
Node.js 异步流控制
目录 1、简介 2、状态管理 3、控制流 3.1、串联 3.2、完全并行 3.3、有限并行 1、简介 在其核心,JavaScript被设计为在“主”线程上是非阻塞的,这是呈现视图的位置。你可以想象这在浏览器中的重要性。例如,当主线程被阻塞时࿰…...

掌握这些思维技巧,解救996的打工人!
你身边有没有这样的人:面对堆积如山的工作、随时弹出的任务,接二连三的群也能游刃有余地处理。回看自己,旧的任务还在做,新的任务已经从天而降,日程表上满是任务却无从下手…… 明明忙个不停却成果甚微,这…...

【嵌入式Linux】MBR分区表 和 GPT分区表
文章目录 GUID以及分区表MBR分区方案GPT 分区方案GPT分区表结构 GPT分区表LBALBA0(MBR兼容部分)LBA1LBA 2-33python生成GPT分区表gpt分区表实例 gpt分区表查看查看百问网T113-s3固件查看友善之臂nanopi-m1-plus官方固件查看荣品RV1126固件查看f1c200s固件…...
【华为OD机试真题】MVP争夺战(python)100%通过率 超详细代码注释 代码解读
【华为OD机试真题 2022&2023】真题目录 @点这里@ 【华为OD机试真题】信号发射和接收 &试读& @点这里@ 【华为OD机试真题】租车骑绿道 &试读& @点这里@ MVP争夺战 知识点DFS搜索 时间限制:1s 空间限制:256MB 限定语言:不限 题目描述: 在星球争霸篮球赛对…...

实战打靶集锦-019-BTRSys2.1
提示:本文记录了博主的一次普通的打靶经历 目录 1. 主机发现2. 端口扫描3. 服务枚举4. 服务探查4.1 FTP服务探查4.2 Apache服务探查4.2.1 wpscan扫描4.2.2 Metasploit神器4.2.3 手工探查页面4.2.3.1 Appearance Editor4.2.3.2 Plugins Editor 5. 提权5.1 系统信息枚…...
2023中国(苏州)国际电源工业展览会暨高端论坛
时间:2023年11月9~11日 地点:苏州国际博览中心 30000㎡展出面积 500参展商 50000名专业观众 中国电源行业风向标----相约苏州,共襄盛举! ◆展会背景Exhibition background: …...

基于SpringBoot+Vue的校园疫情防控系统(附源码和数据库)
文章目录 第一章2.主要技术第三章第四章 系统设计4.1功能结构4.2 数据库设计4.2.1 数据库E/R图4.2.2 数据库表 第五章 系统功能实现5.1系统功能模块5.2后台功能模块5.2.1管理员功能 源码咨询 第一章 springboot校园疫情防控系统演示录像2022 一个好的系统能将校园疫情防控的管理…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...

ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

五子棋测试用例
一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏,有着深厚的文化底蕴。通过将五子棋制作成网页游戏,可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家,都可以通过网页五子棋感受到东方棋类…...