迷宫问题是回溯法的典型应用,可以用栈解决,也可以用队列来解决迷宫问题。
下面是小编用栈解决迷宫问题的已经成功运行的代码,提供给大家参考。
#include<iostream>
#include<stdlib.h>
using namespace std;
#define MaxSize 100
typedef struct Box
{ int i; //当前方块的行号
int j; //当前方块的列号
int di; //di是下一可走相邻方位的方位号
}Box;
typedef struct Box T;
//定义方块类型
typedef struct mystack
{ T* data;
int top; //栈顶指针
}mystack; //定义顺序栈类型
//构造一个空的顺序栈
void InitStack(mystack &s)
{
s.data = new T[MaxSize];
s.top=-1;
}
//顺序栈的销毁
void DestroyStack(mystack &s)
{
delete []s.data;
s.top=-1;
}
//判断是否栈满
bool fullstack(mystack &s)
{
if(s.top==MaxSize-1)
return true;
return false;
}
//入栈操作
void Push(mystack &s,T &n)
{
if(fullstack(s))
{
cout<<"full!"<<endl; }
else
{
s.top++;
s.data[s.top].i=n.i;
s.data[s.top].j=n.j; //不能直接赋值,s.data[s.top]=n; ???不明白
}
}
//判断是否栈空
bool StackEmpty(mystack &s)
{
if(s.top==-1)
return true;
return false;
}
//返回顺序栈的长度
int LengthStack(mystack &s)
{
return s.top+1;
}
//出栈操作
T Pop(mystack &s)
{
Box m;
if(s.top==-1)
{
cout<<"出栈失败:下溢"<<endl;
}
else
{
m.i=s.data[s.top].i;
m.j=s.data[s.top].j;
m.di=s.data[s.top].di;
s.top--;
}
return m;
}
//取栈顶元素
T GetTop(mystack &s,Box &t)
{
if(StackEmpty(s))
{
cout<<"栈顶元素已空" <<endl;
}
t=s.data[s.top];
return t;
}
bool mgpath(int xi,int yi,int xe,int ye,int mg[10][10]) //求解路径为:(xi,yi)->(xe,ye)
{
T path[MaxSize],e; // 存储入栈的Box值
int i,j,di,i1,j1,k,t=0;
bool find;
mystack st; //定义栈st
InitStack(st); //初始化栈顶指针
e.i=xi;
e.j=yi;
e.di=-1; //设置e为入口
int p;//首元素入栈
Push(st,e); //方块e进栈
//st.top++;
mg[xi][yi]=-1; //入口的迷宫值置为-1避免重复走到该方块
while (!StackEmpty(st)) //栈不空时循环
{
GetTop(st,e); //取栈顶方块e
i=e.i;
j=e.j;
di=e.di;
if (i==xe && j==ye) //找到了出口,输出该路径
{
cout<<"一条迷宫路径如下:"<<endl;
k=0;
while (!StackEmpty(st))
{
e=Pop(st); //出栈方块e
path[k++]=e; //将e添加到path数组中
}
while (k>=1)
{
k--;
cout<<"("<<path[k].i<<","<<path[k].j<<")"<<" ";
cout<<endl;
}
cout<<endl;
DestroyStack(st);//销毁栈
return true; //输出一条迷宫路径后返回true
}
find=false;
di=-1;
while (di<4 &&find==false ) //找相邻可走方块(i1,j1)
{
di++;
switch(di)
{
//按顺时针旋转
case 0:i1=i-1; j1=j; break;//上
case 1:i1=i; j1=j+1; break;//右
case 2:i1=i+1; j1=j; break;//下
case 3:i1=i; j1=j-1; break;//左
}
if(mg[i1][j1]==0)
{find=true;break;} //找到一个相邻可走方块,设置find为真
}
if (find==true) //找到了一个相邻可走方块(i1,j1)
{
//修改原栈顶元素的di值,记录新的栈顶元素位于那个方位
e.di=di;
e.i=i1;
e.j=j1;
// cout<<"元素进栈:"<<e.i<<" "<<e.j<<endl;
Push(st,e); //相邻可走方块e进栈
mg[i1][j1]=-1; //(i1,j1)迷宫值置为-1避免重复走到该方块
}
else //没有路径可走,则退栈
{
e=Pop(st); //将栈顶方块退栈
// cout<<"退栈元素为:"<<e.i<<"-"<<e.j<<endl;
//让退栈方块的位置变为其他路径可走方块
}
}
DestroyStack(st); //销毁栈
return false; //表示没有可走路径
}
int main()
{
int a[10][10];
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
cin>>a[i][j];
if(!mgpath(1,2,7,8,a))
cout<<"该迷宫问题没有解!"<<endl;
return 0;
}
输入和运行结果如下: