目录
算法核心:
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;
}