前面的一些类型的定义
#define MAXLENGTH 25 //最大列为25
struct PosType
{
int x;
int y;
};
PosType Begin,End; //入口坐标,出口坐标
//行增量,列增量,分别为东南西北
PosType direc[4]={{0,1},{1,0},{0,-1},{-1,0}};
typedef int MazeType[MAXLENGTH][MAXLENGTH]; //迷宫数组类型
MazeType m; //m是一个[25][25]的二维数组
int x,y; //迷宫的行列数
int curstep=1; //当前足迹(在入口处)为1
typedef struct
{
int ord; //通道快在路径上的序号
PosType seat; //通道块在迷宫中的坐标
int di; //走向下一个通道块的方向
}SElemType;
#include"Stack.h"//栈的基本操作函数
迷宫的创建
void Init()
{
int i,j,x1,y1;
printf("输入迷宫的行数,列数(包括外墙):");
scanf("%d,%d",&x,&y);
for(i=0;i<y;i++)
{
m[0][i]=0; //上面
m[x-1][i]=0; //下面
}
for(i=1;i<x-1;i++)
{
m[i][0]=0; //左边
m[i][y-1]=0; //右边
}
for(i=1;i<x-1;i++)
for(j=1;j<y-1;j++)
m[i][j]=1; //其余都是通道,初值为1
printf("请输入迷宫内墙的单元数(不包括外墙):");
scanf("%d",&j);
printf("请依次输入迷宫内墙的行列数(eg:3,4):\n");
for(i=1;i<=j;i++)
{
scanf("%d,%d",&x1,&y1);
m[x1][y1]=0;
}
printf("迷宫结构如下(1为通路,0为墙):\n");
Print1();
printf("请输入起点的行列数(eg:1,1):");
scanf("%d,%d",&Begin.x,&Begin.y);
printf("请输入终点的行列数(eg:8,8):");
scanf("%d,%d",&End.x,&End.y);
}
核心算法中用到的函数:
1.迷宫m的b点值为1(可通过路径),返回OK,否则返回ERROR
// 定义墙元素值为0,可通过路径为1,经试探不可通过路径为-1,通过路径为足迹
Status Pass(PosType b)
{
if(m[b.x][b.y]==1)
return OK;
else
return ERROR;
}
2.使迷宫m的b点值变为足迹(已经通过的路径标识)curstep(>1)
void FootPrint(PosType b)
{
m[b.x][b.y]=curstep+1; //+1防止开局右边死胡同出现bug
}
3.根据当前位置b和移动方向di,修改b为下一个位置
void NextPos(PosType &b, int di)
{ //0123东南西北
b.x+=direc[di].x;
b.y+=direc[di].y;
//direc[4]={{0,1},{1,0},{0,-1},{-1,0}};
}
4.使迷宫m的b点值变为-1(经试探不能到达终点的路径)
void MarkPrint(PosType b)
{
m[b.x][b.y]=-1;
}
核心算法MazePath,默认往东走,判断这一步会不会撞墙,不会就赋值一个大于1的正数,表示已经走过的路径,入栈;如果撞墙了,退栈到前一个位置,按顺时针方向依次尝试看能否走通,都走不通(遇到0以及大于1的数)标记此路不通(-1),退栈到前一个位置,换一个方向继续尝试
//迷宫中存在一条通路,求得一条放入栈中(栈底->栈顶)并返回TRUE
Status MazePath(PosType start, PosType end)
{
PosType curpos=start; //当前位置在入口
SqStack s; //顺序栈
SElemType e; //栈元素,存储了足迹,位置,方向的信息
InitStack(s); //初始化栈
do
{
if(Pass(curpos)) //当前位置可以通过(未走过的通道块) m[i][j]=1才满足
{
//m[i][j]=0(墙),m[i][j]>1(走过的路径)
FootPrint(curpos); //将大于1的数赋给m[i][j],留下足迹表示已经走过
e.ord=curstep; //栈元素的序号为当前足迹curstep=1
e.seat=curpos; //栈元素的位置为当前位置
e.di=0; //下一个位置向东
Push(s,e); //入栈当前位置及状态
if(curpos.x==End.x&&curpos.y==End.y) return TRUE;
NextPos(curpos,e.di); //当前位置以及移动方向,确定下一个位置
curstep++; //足迹+1
}
else //当前位置不能通过
{
if(!StackEmpty(s)) //栈不空
{
Pop(s,e); //退栈到前一个位置
curstep--;
while(e.di==3&&!StackEmpty(s))
{
MarkPrint(e.seat); //留下不能到达终点的标记(-1)
Pop(s,e);
curstep--;
}
if(e.di<3) //未到最后一个方向(北)
{
e.di++; //换下一个方向探索
Push(s,e);
curstep++;
curpos=e.seat; //确定当前方向
NextPos(curpos,e.di);
}
}
}
}while(!StackEmpty(s));
return FALSE;
}
程序运行结果验证算法: