迷宫之深度优先算法(递归回溯)

目录

算法核心:

例题:


算法核心:

1.首先将起始位置的坐标先入栈 。

2.当栈未空时执行以下语句:

标记当前单元已被访问,随机选取当前单元的这周围是否有未被访问的单元,把它的坐标先入栈。 (一般情况下选取在周围的单元也是有顺序的,这根据实际情况可以调整)。

把选取的单元作为目前的单元。

3.当目前的单元周围都被访问过时或者是围墙无法访问时,并且栈未空时:

让栈顶的单元出栈,让其成为目前单元。

4. 当目前单元等于出口单元时,标记该单元已被访问,退出循环。

例题:

下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 00 的为可以通行的地方。起始位置为(0,0),出口位置为(5,5),路线用2标记,走不通的死路用4标记。

 输入 :4个整数,分别为起始位置的坐标和出口位置的坐标。

010000
000100
001001
110000
#include<iostream>
#include<stack>
using namespace std;
int main(){
	stack<int>s1,s2; 
    int a[4][6]={{0,1,0,0,0,0},{0,0,0,1,0,0},{0,0,1,0,0,1},{1,1,0,0,0,0}};//构造迷宫图 
    int i,j,c,d;
	//输入起始坐标和出口坐标 
    cin>>i>>j>>c>>d;
    s1.push(i);//让起始坐标入栈 (这里分别用两个栈来储存横,纵坐标。) 
	s2.push(j); 
	while(!s1.empty()){
	if(i+1>=0 && i+1<=3 && a[i+1][j]==0){//选择当前单元的周围未被访问的单元(这里的顺序是下面,右侧,上侧,左侧) 
		a[i][j]=2;//标记当前单元已被访问 
    	s1.push(i+1);//将当前单元的坐标入栈 
    	s2.push(j);
    	i=i+1;//改变当前的坐标 
    	if(i==c && j==d ){//如果当前的坐标为出口时 
    		a[i][j]=2;//标记已被访问 退出循环。 
			break; 
		} 
    	continue;//如果已选出一个单元,就不在选择其它方向的单元。所以不在进行以下操作,如果不加continue,则选择当前单元的周围单元,顺序就不在受控制。 
	}
	if(j+1>=0 && j+1<=5 && a[i][j+1]==0){
	     a[i][j]=2;
		s1.push(i);
		s2.push(j+1);
		j=j+1;
	if(i==c && j==d ){
	 a[i][j]=2; 
	     break ;
	 }
			continue;
	}
	if(i-1>=0 && i-1<=3 && a[i-1][j]==0){
		a[i][j]=2;
		s1.push(i-1);
		s2.push(j);
		i=i-1; 
		if(i==c && j==d ){
		 a[i][j]=2; 
	     break ;
	 }
			continue;
	}
	if(j-1>=0 &&j-1<=5 && a[i][j-1]==0){
		a[i][j]=2;
		s1.push(i);
		s2.push(j-1);
		j=j-1;
		if(i==c && j==d ){
	      a[i][j]=2; 
	     break ;
	 }
    		continue;
	}
			i=s1.top();//当目前单元的的周围都被访问过,或者是围墙无法访问,则栈顶的单元为目前的单元。 
			j=s2.top();
			s1.pop();
			s2.pop();
			a[i][j]=4; //出栈的单元可能是死路的一部分 
	}
	for(int o=0 ;o<=3 ;o++){// 打印迷宫 
		for(int p=0;p<=5 ;p++){
		    cout<<a[o][p]<<" ";
		}
		cout<<endl;
	}
		return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值