一、实现原理
1.队列辅助处理搜寻路线:
原因:利用队列先进先出(FIFO)的原理,用来记住下一步该往哪几个方向移动。
eg:假设地图原点为(1,1)将原点入队,原点出队,查找原点四个方向哪个方向没有阻碍且没走过,找到就入队循环往复,直到找到终点或没有路;
2.二维数组记录已走过的路线;
3.结构体二维数组储存每一步的父节点;
4.搜到终点后,以终点坐标为索引定位结构体二维数组(记录父节点)记录的父节点不断溯源,直到在结构体二位数组记录的坐标为(-1,-1),即回到原点;
二、代码实现
#include<bits/stdc++.h>
using namespace std;
typedef struct point{
int x;
int y;
}Point;//坐标结构体;
queue<Point> q;//队列;
int main(void){
int len_x,len_y;//地图大小;
int x1,x2,y1,y2;//起点与终点坐标;
int gap_x[4]={-1,1,0,0};
int gap_y[4]={0,0,-1,1};//移动间隔;
int count=0;//总步数;
cin>>len_x>>len_y;//读取地图尺寸;
int map[len_x][len_y];//储存地图
int memo[len_x][len_y]={0};//标记路线防止走回头路;
Point parent[len_x][len_y];//记录父节点;
for(int i=0;i<len_x;i++){
for(int j=0;j<len_y;j++){
cin>>map[i][j];
parent[i][j].x=0;
parent[i][j].y=0;//父节点清零
}
}//读取地图;
cin>>x1>>y1>>x2>>y2;//读取 起点终点;
parent[0][0].x=-1;
parent[0][0].y=-1; //起点的父节点没有,默认为(-1,-1);
Point start,end,output,move;
start.x=x1-1;
start.y=y1-1;
end.x=x2-1;
end.y=y2-1;//写入起点终点坐标;
q.push(start);//将起点入队;
memo[start.x][start.y]=1;//路线标记起点;
while(!q.empty()){
output=q.front();
q.pop();//队首元素出队;
if(output.x==end.x&&output.y==end.y){
move=parent[output.x][output.y];
while(move.x!=-1&&move.y!=-1){
cout<<'('<<move.x+1<<','<<move.y+1<<')'<<endl;
move=parent[move.x][move.y];
count++;
}//到达终点,回溯打印路线并数步数;
cout<<count<<endl;//输出步数;
return 0;
}
for(int i=0;i<4;i++){
move.x=output.x+gap_x[i];
move.y=output.y+gap_y[i];//坐标移动;
if(move.x>=0&&move.x<len_x&&move.y>=0&&move.y<len_y&&!memo[move.x][move.y]&&map[move.x][move.y]){
memo[move.x][move.y]=1;
parent[move.x][move.y]=output;
q.push(move);
}//新元素入队;
}//上下左右查找有无出路;
}
cout<<"No";//没有出路;
return 0;
}