BFS-迷宫最短路径问题
Posted 桃花涣小鱼干
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BFS-迷宫最短路径问题相关的知识,希望对你有一定的参考价值。
迷宫最短路径问题
完整代码如下:
#include<stdio.h>
struct note
{
int x;//横坐标
int y;//纵坐标
int s;//步数
};
int main()
{
struct note que[2501];
int a[51][51] = { 0 }, book[51][51] = { 0 };
int next[4][2] = { {0,1} ,{1,0} ,{0,-1}, {-1,0} };
int head, tail;//引入队列
int i, j, k, m, n, startx, starty, p, q, tx, ty, flag;
//读入目标迷宫大小
scanf("%d %d", &n, &m);
//读入迷宫
for (i = 1; i <= n; i++)
for (j = 1; j <= m; j++)
scanf("%d", &a[i][j]);
//读入起点和终点
scanf("%d %d %d %d", &startx, &starty, &p, &q);
//队列初始化
head = 0;
tail = 1;
//起点入队
que[1].x = startx;
que[1].y = starty;
que[1].s = 0;
//标记起点
book[startx][starty] = 1;
flag = 0;//标识符
while (head < tail)
{
head++;
for (k = 0; k <= 3; k++)
{
//父单元按规律向4个方向拓展
tx = que[head].x + next[k][0];
ty = que[head].y + next[k][1];
if (tx<1 || tx>n || ty<1 || ty>m)
continue;//越界则重新试探
if (a[tx][ty] == 0 && book[tx][ty] == 0)
{
//拓展成功则标记拓展的点并将其入队,累加步数。
tail++;
book[tx][ty] = 1;
que[tail].x = tx;
que[tail].y = ty;
que[tail].s = que[head].s + 1;
}
//拓展到目标点时结束拓展调用标识符结束拓展
if (tx == p && ty == q)
{
flag = 1;
break;
}
}
//若成功标记则结束while循环
if (flag == 1)
break;
}
printf("%d", que[tail].s);
getchar();
getchar();
return 0;
}
思路详解
第一步:定义note结构体
我们要记录最路径,路径大小和经过的点数有关
顾名思义我们需要在点上做文章
一个点拥有(x,y)坐标
我们定义一个含距离的关于点的结构体
如下:
struct note
{
int x;//横坐标
int y;//纵坐标
int s;//步数
};
点的个数和迷宫大小有关
这里我们取最大值如下:
struct note que[2501];
第二步:引入队列的思维
BFS搜索🔍是由父层向下遍历探索所有可能的子结构
探索成功后之前的子层成为了新的父层继续上述操作
不由可以联想到
父到子 >> head向下试探,成功则 tail++
子成父 >> head++
如下:
while (head < tail)
{
head++;//将1单元成为父单元
for (k = 0; k <= 3; k++)
{
//父单元按规律向4个方向拓展
tx = que[head].x + next[k][0];
ty = que[head].y + next[k][1];
if (tx<1 || tx>n || ty<1 || ty>m)
continue;//越界则重新试探
if (a[tx][ty] == 0 && book[tx][ty] == 0)
{
//拓展成功则标记拓展的点并将其入队,累加步数。
tail++;//扩充队列,将新的点入队
book[tx][ty] = 1;
que[tail].x = tx;
que[tail].y = ty;
que[tail].s = que[head].s + 1;
}
//拓展到目标点时结束拓展调用标识符结束拓展
if (tx == p && ty == q)
{
flag = 1;
break;
}
}
//若成功标记则结束while循环
if (flag == 1)
break;
}
第三步:最小路径
问题1:为什么拓展到终点时必为最短路径?
解答:因为每一层拓展均为步数加1,所以拓展的过程中步数是一样累加的
并没有多走的情况,同步出发,并且只要到终点后while循环便会停止,所得> 一定为最短路径
问题2:输出最短路径时为什么要用 que[tail].s ?
解答:我们刚开始定义tail为1,tail表示队尾位置,成功拓展至终点后 ,终点即为队尾位置即que[tail].s;
summary:
1)本题和BFS-马的遍历异同之处?
本题:将距离s定义在结构体之内,使得每一个节点均含有到此的最小步数
other:马的遍历是将距离放在一个二维数组里面,二维数组的下标为位置坐标,我们需要关注的是起点位置为队列的首位,符合以下对应关系:
坐标:(sx,sy)>>(qun[1].x,qun[1].y)即队列第一单元
步数:a[sx][sy]=0>>a[qun[1].x][qun[1].y]=0即队列第一单元对应0步
以上是关于BFS-迷宫最短路径问题的主要内容,如果未能解决你的问题,请参考以下文章