用矩阵(矩阵大小设为8*10,下标从0开始,点(1,1)为起点,点(6,8)为终点)代表地图,矩阵中1代表可以走通,0代表可以走通。假设目前位于(x,y)处,则下一可能位置为(x-1,y-1)(x-1,y)(x-1,y+1)(x,y-1)(x,y+1)(x+1,y-1)(x+1,y)(x+1,y+1)。
(1)将起点压栈并标记为已经历过(可以用-1表示,标记的原因是防止死循环)。
(2)在(x,y)的下一可能位置中选择一个是通路(这里为0)且没走过的点进行压栈,同时标记已经走过。
(3)如果(x,y)附近八个点都不满足条件,就将(x,y)退栈
如果栈不为空,就重复(2)。否则结束,无解。
输入:大小为8*10的矩阵,矩阵中1代表可以走通,0代表可以走通。
输出:由起点走到终点的路线。
代码实现如下:
#include"stdio.h"
#include"stdlib.h"
#include"conio.h"
#define STACKSIZE 2000
#define INCREMENT 20
#define SIZE 10
int maze[SIZE-2][SIZE];
typedef struct{ //位置结构体
int x;
int y;
}PosType;
typedef struct{ //栈的元素类型结构体
int ord;
PosType seat;
int di;
}SElemType;
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
void InitStack(SqStack &S) //创建一个空栈
{
S.base =(SElemType *)malloc(STACKSIZE*sizeof(SElemType));
if(!S.base) printf("储存分配失败!!\n");
else{
S.top=S.base ;
S.stacksize =STACKSIZE;
}
}
void Push(SqStack &S,SElemType e) //向栈顶插入元素
{
if(S.top-S.base>=S.stacksize )
{
S.base=(SElemType *)malloc((S.stacksize+INCREMENT)*sizeof(SElemType));
if(!S.base) printf("追加分配储存空间失败!!!\n");
else{
S.top =S.base +S.stacksize;
S.stacksize +=INCREMENT;
*S.top ++ = e;
}
}
else
{*S.top ++ = e; }
}
void Pop(SqStack S,SElemType &e) //删除栈顶元素,并且将栈顶元素的值用e返回
{
if(S.top!=S.base)
e=*--S.top;
}
int StackEmpty(SqStack S) // 空栈判断
{
if(S.base ==S.top) return 1;
else return 0;
}
int Pass(PosType pos)
{
if(maze[pos.x][pos.y+1]==0||maze[pos.x+1][pos.y+1]==0||maze[pos.x+1][pos.y]==0||maze[pos.x+1][pos.y-1]==0||maze[pos.x][pos.y-1]==0||maze[pos.x-1][pos.y-1]==0||maze[pos.x-1][pos.y]==0||maze[pos.x-1][pos.y+1]==0) return 1;
else return 0;
}
PosType NextPos(PosType pos,int di)
{
int x=pos.x;
int y=pos.y;
switch(di){
case 1: if(maze[x][y+1]==0){
pos.y=y+1;break;
}
case 2: if(maze[x+1][y+1]==0){
pos.x=x+1;pos.y=y+1;break;
}
case 3:if(maze[x+1][y]==0) {
pos.x=x+1;break;
}
case 4:
if(y>0)
if(maze[x+1][y-1]==0){
pos.x=x+1;pos.y=y+1;break;
}
case 5:
if(y>0)
if(maze[x][y-1]==0){
pos.y=y-1;break;
}
case 6:if(y>0&&x>0){
if(maze[x-1][y-1]==0){
pos.x=x-1;pos.y=y-1;break;
}
}
case 7:if(x>0)
if(maze[x-1][y]==0){
pos.x=x-1;break;
}
case 8:
if(x>0)
if(maze[x-1][y+1]==0){
pos.x=x-1;pos.y=y+1;break;
}
}
return pos;
}
void MarkPrint(PosType t)
{
maze[t.x][t.y]=1;
}
void FootPrint(PosType t)
{
printf("%d %d\n",t.x,t.y);
}
void MazePath(int maze[SIZE-2][SIZE],PosType start,PosType end)
{
SqStack S;
InitStack(S);
SElemType e;
PosType curpos=start; //当前位置
int curstep=1; //当前通道块序号
do{
if(Pass(curpos)){ //当前通道块可通
FootPrint(curpos);
e.di=1;
e.ord=curstep;
e.seat=curpos;
Push(S,e);
if(curpos.x==end.x&&curpos.y==end.y) break;
curpos=NextPos(curpos,1);
curstep++;
}
else{ //不通
if(!StackEmpty(S)){
Pop(S,e);
while(e.di==8&&!StackEmpty(S)){
MarkPrint(e.seat);
Pop(S,e);
}
if(e.di<8) {
e.di++;
Push(S,e);
curpos=NextPos(e.seat,e.di);
}
}
}
} while(!StackEmpty(S));
}
int main()
{
int i,j;
PosType start,end;
start.x=1;start.y=1;
end.x=6;end.y=8;
printf("请输入迷宫(大小为8*10):\n");
for(i=0;i<SIZE-2;i++)
for(j=0;j<SIZE;j++)
scanf("%d",&maze[i][j]);
MazePath(maze,start,end);
return 0;
}
我构建的迷宫(矩阵)为:
1 1 1 1 1 1 1 1 1 1
1 0 1 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1
1 1 1 0 0 0 1 1 1 1
1 1 1 1 0 0 0 1 1 1
1 1 1 1 1 1 0 0 0 1
1 1 1 1 1 1 1 1 1 1
运行结果如下: