迷宫问题————bfs解决
输入一个nn的矩阵,以0代表道路,以1代表障碍物,实现一个算法,要求能够给出从入口(默认为左上角)到出口(默认为右下角)的路线。
输入
第一行一个n。
第二行开始是一个(n+2)(n+2)的矩阵(四周边框为1)
输出
从左上角(1,1)到右下角(n,n)的序列。
测试用例确保具有通路
迷宫问题,采用bfs算法非递归实现,不仅可以求出通路而且可以求出所有通路中最短通途。
C++非递归实现
/* 测试数据
6
0 1 0 1 0 1
0 1 0 0 0 1
0 1 0 1 0 1
0 1 0 1 0 1
0 1 0 1 0 1
0 0 0 1 0 0
输出
(1,1)
(2,1)
(3,1)
(4,1)
(5,1)
(6,1)
(6,2)
(6,3)
(5,3)
(4,3)
(3,3)
(2,3)
(2,4)
(2,5)
(3,5)
(4,5)
(5,5)
(6,5)
(6,6)
*/
#include "iostream"
using namespace std;
class stay //stay类 记录每一步
{
public:
int x,y,s; // xy为地图中坐标,s为从原点到当前位置的步数 ox oy为上一步的位置
int ox,oy;
};
int dx[4]={0,1,-1,0}; //地图内四个方向
int dy[4]={1,0,0,-1};
int main()
{
stay stay[2500];
int n,nowstay=1,nowtier=1;
int a[50][50]={0},b[50][50]={0}; //地图
int c[1000],m=0; //存储可行路径
int k=0,tier=0;
int tx=0,ty=0;
int end=0,zj=0;
cin>>n;
for(int i=0;i<n;i++) //输入地图
{
for(int j=0;j<n;j++)
{
cin>>a[i][j];
}
}
stay[k].x=0; //初始化
stay[k].y=0;
stay[k].s=0;
b[0][0]=1;
k++;
while(tier<k) //bfs 每次循环为下一步的四种走法
{
for(int i=0;i<4;i++)
{
tx=stay[tier].x+dx[i];
ty=stay[tier].y+dy[i];
if(tx<0||tx>=n||ty<0||ty>=n) //边界
{
continue;
}
if(a[tx][ty]!=1&&b[tx][ty]!=1) //可行路
{
b[tx][ty]=1;
stay[k].x=tx;
stay[k].y=ty;
stay[k].s=stay[tier].s+1;
stay[k].ox=stay[tier].x;
stay[k].oy=stay[tier].y;
k++;
}
if(tx==n-1&&ty==n-1)
{
zj=k-1;
end=1;
break;
}
}
if(end==1)
{
tier++;
break;
}
tier++;
}
c[m]=stay[zj].x ;
m++;
c[m]=stay[zj].y;
m++;
for(int i=stay[tier].s;i>=0;i--) // 通过最后走到终点的这一步去寻找上一步并存放在数组c中,一直找到原点
{
for(int j=0;j<zj;j++)
{
if(stay[j].s==i&&stay[j].x==stay[zj].ox&&stay[j].y==stay[zj].oy)
{
c[m]=stay[j].x ;
m++;
c[m]=stay[j].y;
m++;
zj=j;
}
}
}
for(int i=m-1;i>=0;i=i-2)
{
cout<<"("<<c[i-1]+1<<","<<c[i]+1<<")"<<endl;
}
return 0;
}
Python 非递归实现:
实现注意:
主要维护一个节点数组,节点数组中父节点位置变量和子节点位置变量。
为了返回获取路径,每个节点保存当前节点坐标,到该节点步数,该节点父节点在节点数组中的位置。
map=[[0 ,1 ,0 ,1 ,0, 1],
[0, 1 ,0 ,0 ,0, 1],
[0 ,1 ,0 ,1 ,0 ,1],
[0 ,1, 0 ,1, 0 ,1],
[0 ,1 ,0 ,1 ,0, 1],
[0 ,0 ,0 ,1 ,0 ,0]]
dx,dy=[1,0,-1,0],[0,1,0,-1]
log_map=[]
def norecursion(map):
#初始化
parent=0
child_num=0
s,x,y=0,0,0
map[x][y]=1
log_map.append((x,y,s,parent))
child_num+=1
while parent<child_num: #终止条件 父节点与子节点重合
#大循环读取父节点
x, y,s = log_map[parent][0],log_map[parent][1],log_map[parent][2]
parent+=1
for i in range(4):
#小循环加入子节点
tx,ty=x+dx[i],y+dy[i]
#边界条件
if tx<0 or tx>=len(map) or ty<0 or ty>=len(map[0]) :
continue
if map[tx][ty]!=1:
map[tx][ty]=1
#加入子节点以及步长和父节点
child=(tx,ty,s+1,parent-1)
log_map.append(child)
child_num += 1
#终止条件 到达目的地
if tx==len(map)-1 and ty==len(map[0])-1:
break
#通过保存的父节点位置来读取最短路径
i=len(log_map)-1
way=[]
min_s=log_map[i][2]
while i>0:
way.append((log_map[i][0],log_map[i][1]))
i=log_map[i][3]
way.reverse()
return min_s,way
本文介绍了一种使用广度优先搜索(BFS)算法解决迷宫问题的方法,包括C++和Python两种语言的非递归实现。通过维护节点数组,记录每个节点的坐标、步数和父节点位置,实现了从迷宫入口到出口的最短路径查找。
8273





