BFS处理迷宫问题

一、实现原理

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值