迷宫问题的DFS解决和BFS解决

迷宫问题
定义一个二维数组:
int maze[5][5]
0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
Input
一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。
Output
左上角到右下角的最短路径,格式如样例所示。
Sample Input
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
Sample Output
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)

1.DFS解法如下:

#include<iostream>
#include<stdlib.h>
#include<map> 
#include<cmath>//数学
#include<queue>//队列
#include<stack>//栈
#include<iomanip>//精度控制
#include<string>//字符串
#include<vector>//容器 
#include<algorithm>//算法
using namespace std;
int count=0;
int a[100][100]; //迷宫大小
int min=INT_MAX;//用来找到最短路径
typedef struct
{
	int x;
	int y;
}Box;//定义一个Box类来存放x,y点
Box b1[10000];//用来存储当前路径
Box b2[10000];//用来存储最短路径
int nums=0;//走的步数
bool c=false;//判断是否能走到终点
void dfs(Box cur,int count,int hang ,int lie){
    int x1=cur.x;
    int y1=cur.y;
    if(x1==hang-1 && y1==lie-1 && min>count){//找到最短路径
        c=true;//找到出口
        min=count;
		nums=count;//走的步数
        for(int i = 0;i <=count;i++)	//存路径给b2 
		{
			b2[i].x = b1[i].x;
			b2[i].y = b1[i].y;
		}
	}
    else{
        if(x1-1>=0 && a[x1-1][y1]==0){//上
            a[x1][y1]=2;//将这个点标记
            b1[count+1].x=x1-1;
            b1[count+1].y=y1;
            dfs(b1[count+1],count+1,hang,lie);
            a[x1][y1]=0;//恢复现场,因为迷宫往往不只有一条路可以走,在dfs完成之后进行恢复
        }
        if(x1+1<hang && a[x1+1][y1]==0){//下
            a[x1][y1]=2;
            b1[count+1].x=x1+1;
            b1[count+1].y=y1;
            dfs(b1[count+1],count+1,hang,lie);
			a[x1][y1]=0;
        }
        if(y1-1>=0 && a[x1][y1-1]==0){//左
            a[x1][y1]=2;
            b1[count+1].x=x1;
            b1[count+1].y=y1-1;
            dfs(b1[count+1],count+1,hang,lie);
			a[x1][y1]=0;
        }
        if(y1+1<lie && a[x1][y1+1]==0){//右
            a[x1][y1]=2;
            b1[count+1].x=x1;
            b1[count+1].y=y1+1;
            dfs(b1[count+1],count+1,hang,lie);
			a[x1][y1]=0;
        }
    }
}
int main(){
	int hang,lie;
	cin>>hang>>lie;
	for(int i=0;i<hang;i++){
        for(int j=0;j<lie;j++){
            cin>>a[i][j];//输入行列数
        }
    }
    b1[0].x=0;//起点设置为0,0
    b1[0].y=0;
    dfs(b1[0],0,hang,lie);
	if(c==1){
    for(int k = 0;k <=nums;k++)
		cout<<b2[k].x<<","<<b2[k].y<<endl;}
	else{
		cout<<"这个迷宫没有出口"<<endl;
	}
}

2.BFS解法:
第一版:只能判断是否能走出迷宫,不能输出如何走的坐标

#include<iostream>
#include<stdlib.h>
#include<map> 
#include<cmath>//数学
#include<queue>//队列
#include<stack>//栈
#include<iomanip>//精度控制
#include<string>//字符串
#include<vector>//容器 
#include<algorithm>//算法
using namespace std;
int a[100][100]; 
typedef struct		//若要记录路径,则应该运用结点数组,每遍历一次,就往结点存当前坐标值,最后按顺序将结点输出即可得到路径 
{
	int x;
	int y;
}Box;
Box b1[10000];//用来存储当前路径
Box b2[10000];//用来存储最短路径
int nums=0;//走的步数
bool c=false;//判断是否能走到终点
void bfs(Box cur,int hang ,int lie){
	Box location;
	Box temp;//用来存合格的值并返回
    queue<Box> A;//创建一个以Box对象为载体的队列
    A.push(cur);
    while(!A.empty()){
        location=A.front();//location也是Box对象
        if(location.x==hang-1 && location.y==lie-1){//已经到达出口
        c=true;//找到出口
        break;
        }
        A.pop();
        if(location.x-1>=0 && a[location.x-1][location.y]==0){//上
        a[location.x][location.y]=2;
        temp.x=location.x-1;
		temp.y=location.y;
		A.push(temp);
        }
        if(location.x+1<hang && a[location.x+1][location.y]==0){//下
        a[location.x][location.y]=2;
        temp.x=location.x+1;
		temp.y=location.y;
		A.push(temp);
        }
        if(location.y-1>=0 && a[location.x][location.y-1]==0){//左
        a[location.x][location.y]=2;
        temp.x=location.x;
		temp.y=location.y-1;
		A.push(temp);
        }
        if(location.y+1<lie && a[location.x][location.y+1]==0){//右
        a[location.x][location.y]=2;
        temp.x=location.x;
		temp.y=location.y+1;
		A.push(temp);
        }
    }
}
int main(){
	int hang,lie;
	cin>>hang>>lie;
	for(int i=0;i<hang;i++){
        for(int j=0;j<lie;j++){
            cin>>a[i][j];//输入行列数
        }
    }
    b1[0].x=0;
    b1[0].y=0;
	bfs(b1[0],hang,lie);
	if(c==1){
		cout<<"有出口"<<endl;
	}
	else{
		cout<<"这个迷宫没有出口"<<endl;
	}
}

2.正确版本BFS,可以进行正确的输出

#include<iostream>
#include<stdlib.h>
#include<map> 
#include<cmath>//数学
#include<queue>//队列
#include<stack>//栈
#include<iomanip>//精度控制
#include<string>//字符串
#include<vector>//容器 
#include<algorithm>//算法
using namespace std;
int count=0;
int hang,lie;
int a[100][100]; //迷宫大小
int min=INT_MAX;
typedef struct		//应该运用结点数组,每遍历一次,就往结点存当前坐标值,最后按顺序将结点输出即可得到路径 
{
	int x;
	int y;
	int pre;//指向前方的指针
}Box;
typedef struct{
	Box data[10000];//将Box类型包含在其中
	int head;//头节点
	int tail;//尾结点
}Queue;
bool c=false;//判断是否能走到终点
void print(Queue qu, int cur)//用来找出原来的路径,反向找到这一条路径,因为存入的顺序与输出是相反的
{
	int j=cur,k;
	while(j!=0){
	k=j;
	j=qu.data[k].pre;//将j指向qu.data[k]的前一个
	qu.data[k].pre=-1;//将这个元素的pre设置为-1用来输出,因为我们第一步设置的head就是-1
	}
	while(j<400){//假设的是20*20行
		if(qu.data[j].pre==-1){//如果pre是-1就进行输出
		cout<<qu.data[j].x<<","<<qu.data[j].y<<endl;
		}
		j++;
	}
}
void bfs(int x,int y,int hang,int lie){ 
	Queue l1;	//创建队列
	l1.tail = 0;	//初始化队列
	l1.head = -1;  //因为头指针开始时不应该与tail指向同一位置
	l1.data[0].x = 0;
	l1.data[0].y = 0;
	l1.data[0].pre = -1; 	//初始结点的pre设为-1,作为输出路径的递归出口 
	a[x][y]=2;//将x,y点标记
    while(l1.head != l1.tail && c!=1){
		l1.head++;//head指向出队节点
		int p=l1.data[l1.head].x;//用l1.head作为data数组的下标
		int q=l1.data[l1.head].y;
		if(p==hang-1 && q==lie-1){//已经到达终点
			c=true;
			print(l1,l1.head);
		}
		else{
        if(p-1>=0 && a[p-1][q]==0){//上
        a[p][q]=2;
        l1.tail++;//尾指针后移
		l1.data[l1.tail].x=p-1;//用尾指针来作为data下标
		l1.data[l1.tail].y=q;
		l1.data[l1.tail].pre=l1.head;//将data[l1.tail]的pre指针指向前一个的head
        }
        if(p+1<hang && a[p+1][q]==0){//下
        a[p][q]=2;
        l1.tail++;
		l1.data[l1.tail].x=p+1;
		l1.data[l1.tail].y=q;
		l1.data[l1.tail].pre=l1.head;
        }
        if(q-1>=0 && a[p][q-1]==0){//左
        a[p][q]=2;
        l1.tail++;
		l1.data[l1.tail].x=p;
		l1.data[l1.tail].y=q-1;
		l1.data[l1.tail].pre=l1.head;
        }
        if(q+1<lie && a[p][q+1]==0){//右
        a[p][q]=2;
        l1.tail++;
		l1.data[l1.tail].x=p;
		l1.data[l1.tail].y=q+1;
		l1.data[l1.tail].pre=l1.head;
        }
		}
    }
}
int main(){
	cin>>hang>>lie;
	for(int i=0;i<hang;i++){
        for(int j=0;j<lie;j++){
            cin>>a[i][j];//输入行列数
        }
    }
	bfs(0,0,hang,lie);
	if(c==1){
		cout<<"有出口"<<endl;
	}
	else{
		cout<<"这个迷宫没有出口"<<endl;
	}
}

总结:可以使用这种结构体来储存数据

typedef struct		//应该运用结点数组,每遍历一次,就往结点存当前坐标值,最后按顺序将结点输出即可得到路径 
{
	int x;
	int y;
	int pre;//指向前方的指针
}Box;
typedef struct{
	Box data[10000];//将Box类型包含在其中
	int head;//头节点
	int tail;//尾结点
}Queue;

并且也可以创造以这种数据为载体的队列

typedef struct	
{
	int x;
	int y;
}Box;
queue<Box> A;
发布了70 篇原创文章 · 获赞 39 · 访问量 2257

猜你喜欢

转载自blog.csdn.net/weixin_45221477/article/details/105056594
今日推荐