#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define RIGHT 1
#define ERROR 0
#define sizea 4
#define sizeb 4
#define STACK_INIT_SIZE 16
#define STACKINCREMENT 10
typedef struct
{
int x;
int y;
}PosType;
typedef struct
{
int ord;
PosType seat;
int di;
}SelemType;
typedef struct Stack
{
SelemType* base;
SelemType* top;
int Stacksize;
}SqStack;
int InitStack(SqStack *S);//初始化栈//S不是指针,只是作为参数要用指针
int DestroyStack(SqStack *S);//销毁栈
int ClearStack(SqStack *S);//清空栈
int StackEmpty(SqStack *S);//判断栈是否为空
//int StackLength(SqStack S);
int GetTop(SqStack S,SelemType* e);//提取栈顶元素
int Push(SqStack *S,SelemType e);//插入栈顶元素
int Pop(SqStack *S,SelemType *e);//删除栈顶元素
//迷宫函数
PosType NextPos(PosType seat,int di);//找到当前坐标的di方向坐标并返回
int Pass(PosType seat,int maze[sizea][sizeb]);//判断当前位置能否通过
void MarkPrint(PosType seat,int maze[sizea][sizeb]);//标记当前坐标是死路
void FootPrint(PosType seat,int maze[sizea][sizeb]);//标记当前位置已经走过
int InitStack(SqStack *S)
{
S->base=(SelemType*)malloc(STACK_INIT_SIZE*sizeof(SelemType));
if (S->base == NULL)
{
printf("空间不足!");
exit(-1);
}
S->top=S->base;
S->Stacksize=STACK_INIT_SIZE;
return RIGHT;
}
int DestroyStack(SqStack *S)
{
free(S->base);
S->base = NULL;
return RIGHT;
}
int ClearStack(SqStack *S)
{
SelemType e;
while(S->base!=S->top)
{
Pop(S,&e);
}
return RIGHT;
}
int StackEmpty(SqStack *S)
{
if(S->base==S->top) return RIGHT;
else return ERROR;
}
int Pop(SqStack *S,SelemType *e)
{
if(S->base==S->top) return ERROR;
*e=*(--S->top);
return RIGHT;
}
int Push(SqStack *S,SelemType e)
{
if(S->top-S->base>=S->Stacksize)
{
S->base=(SelemType*)realloc(S->base,(S->Stacksize+STACKINCREMENT)*sizeof(SelemType));
if (S->base == NULL)
{
printf("空间不足!");
exit(-1);
}
S->Stacksize+=STACKINCREMENT;
S->top=S->base+S->Stacksize;
}
*(S->top)=e;
S->top++;
return RIGHT;
}
PosType NextPos(PosType seat,int di)
{
if(di==2)
{
seat.x++;
return seat;
}
else if(di==1)
{
seat.y++;
return seat;
}
else if(di==4)
{
seat.x--;
return seat;
}
else if(di==3)
{
seat.y--;
return seat;
}
else exit(ERROR);
}
int Pass(PosType seat,int maze[sizea][sizeb])
{
if(maze[seat.x-1][seat.y-1]!=0&&maze[seat.x-1][seat.y-1]!=2&&seat.x<=sizea&&seat.y<=sizeb&&seat.x>=1&&seat.y>=1) return RIGHT;
else return ERROR;
}
void MarkPrint(PosType seat,int maze[sizea][sizeb])
{
if(seat.x<=sizea&&seat.y<=sizeb&&seat.x>=1&&seat.y>=1) maze[seat.x-1][seat.y-1]=0;
}
void FootPrint(PosType seat,int maze[sizea][sizeb])
{
if(seat.x<=sizea&&seat.y<=sizeb&&seat.x>=1&&seat.y>=1) maze[seat.x-1][seat.y-1]=2;
}
//主函数:生成迷宫,设置入口出口,生成堆栈,开始找出路
//迷宫为1可以通过,为0不能通过,2为已经走过
int main()
{
int maze[sizea][sizeb];
int i,j,curstep;
PosType start,end,curpos;
SelemType e;
SqStack MazePath;
InitStack(&MazePath);
printf("请输入迷宫0/1\n");
for(i=0;i<sizea;i++)
{
for(j=0;j<sizeb;j++)
{
scanf("%d",&maze[i][j]);
}
}
printf("请输入入口和出口坐标");
scanf("%d%d%d%d",&start.x,&start.y,&end.x,&end.y);
printf("迷宫为\n");
for(i=0;i<sizea;i++)
{
for(j=0;j<sizeb;j++)
{
printf("%d",maze[i][j]);
printf("\t");
}
printf("\n");
}
curpos=start;
FootPrint(curpos, maze);//循环之前起点已经走过,则要给起点走过的标记,否则返回到起点时会以为可经过而重复
curstep=2;
e.seat=curpos;e.ord=1;e.di=1;
Push(&MazePath,e);
curpos=NextPos(curpos,e.di);
do{
if(Pass(curpos,maze)==1)
{
FootPrint(curpos,maze);
e.seat=curpos;e.ord=curstep;e.di=1;
Push(&MazePath,e);
if(curpos.x==end.x&&curpos.y==end.y)
{
printf("成功找到路径!");
break;
}
curpos=NextPos(curpos,e.di);
curstep++;
}
else
{
if (!StackEmpty(&MazePath))
{
Pop(&MazePath, &e);
}
while(e.di==4&&!StackEmpty(&MazePath))
{
MarkPrint(e.seat,maze);
Pop(&MazePath,&e);
curstep--;//若要彻底删除一步,则在堆栈中的步数也要统一
}
if(e.di<4)
{
e.di++;
curpos=NextPos(e.seat,e.di);
Push(&MazePath,e);
}
}
}while(1);
printf("路径坐标依次为");
i=0;
while(i<curstep)
{
printf("(%d,%d)",MazePath.base[i].seat.x,MazePath.base[i].seat.y);
i++;
}
DestroyStack(&MazePath);
return 0;
}
注意,代码中的坐标点(x,y)采用右手坐标系顺时针旋转90度。
下面为运行结果