BFS实现迷宫最短路径
结合队列的知识利用 广度优先遍历,通过对能走的路径的记录以及对走过路径的标记,进行多条路搜查
一、理论基础
如下图的迷宫:

选取所走方向(针对某一个位置)下,右,上,左,从起点(0,0)开始进行广度搜索,标记(0,1)走过,重复寻路,直到走到终点
如图:

通过一个点找到所有与该顶点相连且能走的顶点,不停寻找,直到找到目的地或走完所有能走的点为止,图中可以看到
任意一个顶点只有一个前驱,可以通过某种方式记录该顶点的前驱,一步步回到原点,并记录移动轨迹,最终得到从起点到终点最短路径的数组
步骤:
1)起点入队
2)队头出队,
3)找到所有与队头相连且为空地的点,将这些点都入队,并记录这些点的前驱
4)重复执行步骤2)3),直到队列为空
5)通过终点一步步回到前驱,最终回到终点,得到最短路径\
二、代码实现
C语言代码实现如下:
① 定义坐标结构体
typedef struct
{int row; //行int col; //列
}Position;
② 定义队列结构及操作
typedef struct
{Position*queue; //队列int front; //头部int rear; //尾部int cap; //队列容量
}MyQueue;//判断队列是否已满
bool IsEmpty(MyQueue*myqueue)
{if(myqueue->front==myqueue->rear)return true;elsereturn false;
}
//弹出队头
Position PopFront(MyQueue*myqueue)
{Position p=myqueue->queue[myqueue->front];myqueue->front=(myqueue->front+1)%myqueue->cap;return p;
}
//插入队尾
void PushRear(MyQueue*myqueue,Postion p)
{myqueue->queue[myqueue->rear]=p;myqueue->rear=(myqueue->rear+1)%myqueue->cap;
}
③ 设置移动方向
//移动方向
int orient[4][2]={{1,0},{0,1},{-1,0},{0,-1}//下 右 上 左
}
④ 开始广度寻路
//0代表空地,1代表墙
void ShortestPath_BFS(int**maze,int maze_row,int maze_col,Position start,Position destination)
{//创建队列MyQueue*myqueue=CreatMyQueue(maze_row*maze*col);/*创建vt数组,标记某些点是否走过,0代表未走过,非0代表走过(1代表该点的前驱在该点下方,2代表该点的前驱在该点右边,3代表上,4代表左)*/int vt[maze_row][maze_col];memset(vt,0,sizeof(vt)); //对所有点初始化标记为未走过PushRear(myqueue,start); //起点入队vt[start.row][start.col]=5; //标记起点已走过,5代表起点位置while(!IsEmpty(myqueue)){Position temp=PopFront(myqueue); //队头出队//找到与出队顶点相连且为空地的所有顶点入队for(int ori=0;ori<4;ori++){//定义试探点int newRow=temp.row+orient[i][0];int newCol=temp.col+orient[i][1];//判断试探点是否能走if(newRow>=0&&newRow<maze_row&&newCol>=0&&newCol<maze_col&&maze[newRow][newCol]==0&&vt[newRow][newCol]==0)//不越界,且为空地,未走过{//该点入队Position p;p.row=newRow;p.col=newCol;PushRear(queue,p);//标记该点走过,记录该点前驱方向vt[newRow][newCol]=(ori+2)%4+1;}}}//定义路径数组Position*path=malloc(sizeof(Position)*maze_row*maze_col);int path_size=0;//通过终点回到前驱,直到回到起点,记录其移动轨迹int curRow=destination.row;int curCol=destination.col;while(vt[curRow][curCol]!=5){path[path_size].row=curRow;path[path_size].col=curCol;path_size++;int ori=vt[curRow][curCol]-1;//前驱点相对于该点的方向在orient数组中的位置curRow+=orient[ori][0]; //前驱点的行curCol+=orient[ori][1]; //前驱点的列}//将起点位置存入路径数组path[path_size].row=start.row;path[path_size].col=start.col;path_size++;//展示从起点开始到终点的路径for(int i=path_size-1;i>=0;i--){printf("(%d,%d)"path[i].row,path[i].col);if(i!=0)printf("->");}
}
相关文章:
BFS实现迷宫最短路径
结合队列的知识利用 广度优先遍历,通过对能走的路径的记录以及对走过路径的标记,进行多条路搜查 一、理论基础 如下图的迷宫: 选取所走方向(针对某一个位置)下,右,上,左࿰…...
Linux IPC解析:匿名命名管道与共享内存
目录 一.IPC机制介绍二.匿名与命名管道1.匿名管道2.命名管道3.日志 三.共享内存三.System V 标准1.System V简介2.IPC在内核的数据结构设计3.信号量 一.IPC机制介绍 IPC(Inter-Process Communication,进程间通信)是计算机系统中不同进程之间交…...
Codeforces Round 964 (Div. 4) A~G
封面原图 画师ideolo A - AB Again? 题意 给你一个两位数,把他的个位和十位加起来 代码 #include <bits/stdc.h> using namespace std; typedef long long ll; typedef double db; typedef pair<int,int> pii; typedef pair<ll,ll> pll;voi…...
单体应用提高性能和处理高并发-使用缓存
要在单体应用中实现高并发,并利用缓存技术来提高性能,需要深入了解缓存的应用场景、选择合适的缓存工具,以及在具体代码中实现缓存策略。以下是详细说明如何在单体应用中使用缓存来处理高并发的内容,包括常见的缓存框架和实际的代…...
ollama教程——使用LangChain调用Ollama接口实现ReAct
ollama入门系列教程简介与目录 相关文章: Ollama教程——入门:开启本地大型语言模型开发之旅Ollama教程——模型:如何将模型高效导入到Ollama框架Ollama教程——兼容OpenAI API:高效利用兼容OpenAI的API进行AI项目开发Ollama教程——使用LangChain:Ollama与LangChain的强强…...
【Bug分析】Keil报错:error: #18:expected a “)“问题解决
【Bug分析】Keil报错:error: #18:expected a “)”问题解决 前言bug查找bug解决方法小结 前言 keil编译时出现一个问题,缺少一个右括号。然后仔细查看代码,并没有括号缺失。 如下,代码括号正常。 bug查找 站内文章…...
MAC上设置快捷打开终端以及如何运用剪切快捷键
在Mac上设置一个快捷键,在当前文件夹中打开终端,你可以使用Automator创建一个服务,然后将其分配给一个快捷键。以下是步骤: 1. 创建Automator服务 打开 Automator(你可以在应用程序文件夹中找到它,或使用…...
linux docker安装 gitlab后忘记root密码如何找回
1. docker ps - a 查看当前gitlab 当前的id2. docker exec -it gitlab /bin/bash 进入docker git 容器中【gitlab 注意可以上图中的name,也可以是id都可以的】,如下图3.gitlab-rails console -e production 输入该指令,启动Ruby on Rails控制台&…...
C语言典型例题27
《C程序设计教程(第四版)——谭浩强》 习题2.4 用下面的scanf函数输入数据 使a3,b7,x8.5,y71.8,c1A,c2a。问在键盘上怎么输入 代码 //《C程序设计教程(第四版)——谭浩强》 //习题2.4 用下面的scanf函数输入数据,使…...
clion开发stm32f4系列(一)————移植rt-thread os系统
前言 本次使用的rt-thread的版本为5.0.2基于rt-thread sudio生成的源码进行拷贝和修改工程基于上次创建工程的项目进行修改。本次工程只是用了serial和pin组件,其他后面用到再进行添加 拷贝rt-thread源码库 通过CMakeLists来进行管理 顶级(rt-thread目录) cmake_minimum_req…...
计算机网络(网络层)
网络层概述 网络层是干什么的? 网络层的主要任务是实现不同异构网络互连,进而实现数据包在各网络之间的传输相比于数据链路层的以太网通信,网络层则是将一个个数据链路层连接的以太网通过路由器连接起来。从而实现不同数据链路层的互联。 这…...
Python3 第六十六课 -- CGI编程
目录 一. 什么是 CGI 二. 网页浏览 三. CGI 架构图 四. Web服务器支持及配置 五. 第一个CGI程序 5.1. HTTP 头部 5.2. CGI 环境变量 六. GET和POST方法 6.1. 使用GET方法传输数据 6.1.1. 简单的url实例:GET方法 6.1.2. 简单的表单实例:GET方法…...
【Unity23种设计模式】之状态模式
首先创建一个项目 打开项目后复制至3个场景 命名为 创建一个空物体 命名为GameLoop 创建一个脚本GameLoop.cs 编写代码如下 将代码挂载至空物体GameLoop 将三个场景拖拽至Scenes In Build 分析下状态模式的类图 我们创新类图中的代码 编写ISceneState.cs 编写三个状态子类继承构…...
二叉树刷题,bfs刷题
有些题目,你按照拍脑袋的方式去做,可能发现需要在递归代码中调用其他递归函数计算字数的信息。一般来说,出现这种情况时你可以考虑用后序遍历的思维方式来优化算法,利用后序遍历传递子树的信息,避免过高的时间复杂度。…...
为什么要用分布式锁
单应用中,如果要确保多线程修改同一个资源的安全性 加synchronized就可以了 但是性能不高 而mybatis-plus的乐观锁就可以很好的解决这类问题 但是这样的锁机制,只在单应用中有效 试想,在分布式下,有没有可能出现多个应用中的线程同时去修改同一个数据资源的并发问题 例如A …...
python游戏开发之五子棋游戏制作
五子棋是一种源自中国的传统棋类游戏,起源可以追溯到古代。它是一种两人对弈的游戏,使用棋盘和棋子进行。棋盘通常是一个 1515 的网格,棋子分为黑白两色,双方轮流在棋盘上落子。游戏的目标是通过在棋盘上落子,使自己的…...
文件上传绕过最新版安全狗
本文来源无问社区,更多实战内容,渗透思路可前往查看http://www.wwlib.cn/index.php/artread/artid/9960.html http分块传输绕过 http分块传输⼀直是⼀个很经典的绕过⽅式,只是在近⼏年分块传输⼀直被卡的很死,很多waf都开始加 …...
常用API_2:应用程序编程接口:ArrayList
文章目录 ArrayList常用方法 案例 :上菜 ArrayList 常用方法 来自黑马程序员学习视频 案例 :上菜 待完善...
【Linux操作系统】进程的基本概念(PCB对象)详解
目录 一、进程的基本概念二、进程的描述组织(PCB对象)1.PCB的基本概念2.为什么要有PCB对象(操作系统对进程的组织管理)3.PCB对象的内部属性(tast_struct结构体) 三、查看进程1.ps指令2.top指令3.通过 /proc…...
曙光宁畅中科可控所有服务器机型出厂默认IPMI用户密码
机型 默认IP 用户名/密码 通用 SG机型 DHCP admin/admin 通用 KK机型 DHCP admin/admin 通用 NC 机型 DHCP Admin/Admin5000 I420-G10、I620-G15、I650-G15、I840-GS、I840-G10、I840-G25、I980-G10、A420r-G、A620r-G、A840-G10、TC4600刀片、TC46…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
