问题如下:
实现如下迷宫的自动寻路,以圆圈为迷宫入口,以五角星为迷宫出口,打印出完整的走迷宫路径。
为了表示迷宫,我们设置一个二维数组mg,其中每个元素代表一个方位的状态,我们定义0为通路,1为墙,-1为已走过的路,通过堆栈保存当前路径,找到一条可行的路径。
算法如下:
将入口(xi,yi)进栈并将其初始方位向量di设置为-1:mg[xi][yi]=-1;
while(栈不空)
{ 取栈顶方块并判断是否为出口
若是出口则打印路径
return true;
free(s);
若不是则查找当前块的下一个相邻可走方块;
if(找到一个)
{
该方块为(i1,j1),栈顶方块对应方位更改为di;
找到的方块进栈;
mg[i1][j1]=-1;
}
if(没有找到)
将当前方块退栈;
//注意退栈后不能将此方块状态置零,否则会陷入死循环
}
return false;
代码实现:
#include<stdio.h>
#include<stdlib.h>//记住这个头文件,malloc函数和free函数都离不开它
#define MaxSize 100//定义顺序栈最大空间
typedef struct{
int i;//当前方块的行号
int j;//当前方块的列号
int di;//方块方向属性
}Box;//定义路径属性
typedef struct{
Box data[MaxSize];//栈保存当前路径
int top;
}sqstack;//顺序栈
int mg[10][10]=//地图
{{1,1,1,1,1,1,1,1,1,1},
{1,0,0,1,0,0,0,1,0,1},
{1,0,0,1,0,0,0,1,0,1},
{1,0,0,0,0,1,1,0,0,1},
{1,0,1,1,1,0,0,0,0,1},
{1,0,0,0,1,0,0,0,0,1},
{1,0,1,0,0,0,1,0,0,1},
{1,0,1,1,1,0,1,1,0,1},
{1,1,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1}};
bool push(sqstack * &s,Box e)//压栈
{
if(s->top==MaxSize-1)
return false;
s->top++;
s->data[s->top]=e;
return true;
}
bool pop(sqstack * &s,Box &e)//退栈
{
if(s->top==-1)
return false;
e=s->data[s->top];
s->top--;
return true;
}
bool mgpath(int xi,int yi,int xe,int ye)//求解路径为(xi,yi)->(xe,ye)
{
sqstack *s;//定义栈s
s=(sqstack * )malloc(sizeof(sqstack));
s->top=-1;//初始化栈顶指针
Box e;
mg[xi][yi]=-1;//将起点压栈并将状态记录为-1(已走)
e.i=xi;e.j=yi;e.di=-1;
push(s,e);
mg[xi][yi]=-1;
while(s->top!=-1)//栈不空时循环
{
e=s->data[s->top];
if(e.i==xe&&e.j==ye)//找到出口,输出该路径
{
printf("这是一条路径:\n");
for(int k=0;k<=s->top;k++)
{
printf("(%d,%d) ",s->data[k].i,s->data[k].j);
if((k+1)%5==0)
printf("\n");
}
free(s);
return true;//输出一条路径后返回true并销毁数据栈
}
int i,j,di;
i=e.i;j=e.j;di=-1;
int x=i,y=j;
while(di<=3)//不是出口则继续查找
{
di++;
if(di==0)
{
x=i-1;
y=j;
}
else if(di==1)
{
x=i;
y=j+1;
}
else if(di==2)
{
x=i+1;
y=j;
}
else
{
x=i;
y=j-1;
}
if(mg[x][y]==0)//找到相邻可走方块
break;
}
if(mg[x][y]==0)
{
s->data[s->top].di=di;//修改原栈顶元素di值
e.i=x;e.j=y;e.di=-1;
push(s,e);//相邻可走方块e进栈
mg[x][y]=-1;//将状态记录为-1(已走),防止重复
}
else
{
pop(s,e);//没有路径可走,将当前方块退栈
//mg[e.i][e.j]=0;//注意这里我专门注释掉的部分,不可以置0
}
}
free(s);
return false;//无路可走,销毁栈
}
int main()
{
if(!mgpath(1,1,8,8))
printf("该迷宫无解!");
return 0;
}