问题描述:以一个m*n的矩阵表示迷宫,0和1分别表示通路和障碍。设计一个程序对给定的迷宫输入入口和出口,输出路径或是无解。
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 20
#define ERROR -1
#define OK 1
#define FALSE 0
#define TRUE 1
typedef enum{RIGHT,DOWN,LEFT,UP}Direction;
typedef enum{YES,NO}MarkTag;
typedef struct position //迷宫中位置的坐标
{ int x;
int y;
}Position;
typedef struct
{ int order; //当前位置在路径中的序号
Position seat; //当前位置在迷宫中的坐标
Direction di; //从当前位置走到下一位置的方向
}SElemType; //栈元素的类型
typedef struct
{
SElemType *elem;
int top;
}Stack;
char maze[MAXSIZE][MAXSIZE]={
{'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'}
}; //用二维字符数组表示迷宫
int InitStack(Stack *S) //创建一个空栈
{
S->elem=(SElemType*)malloc(MAXSIZE*MAXSIZE*sizeof(SElemType));
if(!S->elem) return ERROR;
S->top=0; return OK;
}
int Push(Stack *S,SElemType e) //元素e入栈
{ if(S->top>=MAXSIZE*MAXSIZE) return ERROR;
S->elem[S->top++]=e;return OK;
}
int Pop(Stack *S,SElemType *e) //栈顶元素出栈,由e带回栈顶元素
{ if(S->top<=0) return ERROR;
*e=S->elem[--S->top]; return OK;
}
int Empty(Stack S) //判断栈是否为空
{ if(S.top==0) return TRUE;
else return FALSE;
}
int createMaze(Position *startpos,Position *endpos)
{ Position start,end;
printf("请输入迷宫入口的位置:");
scanf("%d%d",&start.x,&start.y);
printf("请输入迷宫出口的位置:");
scanf("%d%d",&end.x,&end.y);
*startpos=start; *endpos=end;
return OK;
} //createMaze
int canPass(Position curpos)
{ if(maze[curpos.x][curpos.y]=='0') return TRUE;
return FALSE;
} //canPass
void markPos(Position curpos,MarkTag tag) //为已经探索过的位置加标记
{ switch(tag)
{ case YES: maze[curpos.x][curpos.y]='.'; break; //路径标记
case NO: maze[curpos.x][curpos.y]='#'; break; //死胡同标记
}
}
//根据当前的位置坐标和下一步要探索的方向dir求下一步要走的位置坐标
Position nextPos(Position curpos,Direction dir)
{ Position nextpos;
switch(dir)
{ case RIGHT:nextpos.x=curpos.x ;nextpos.y =curpos.y +1; break;
case DOWN :nextpos.x=curpos.x+1 ;nextpos.y =curpos.y; break;
case LEFT :nextpos.x=curpos.x ;nextpos.y =curpos.y -1; break;
case UP :nextpos.x=curpos.x-1 ;nextpos.y =curpos.y; break;
}
return nextpos;
}
Direction nextDir(Direction dir)
{ switch(dir)
{ case RIGHT: return DOWN;
case DOWN : return LEFT;
case LEFT: return UP;
}
}
int Solve(Stack *S,Position start,Position end)
{//若迷宫中存在从入口start到出口end的通道,则求得一条存放在栈S中,并返回TRUE,若迷宫中不存在从入口start到出口end的通道,并返回FALSE
Position curpos;
SElemType e;
int curstep=1; //共用的步数
if(InitStack(S)==ERROR) return FALSE;
curpos=start;
do{
if(canPass(curpos)){ //当前位置可以通过
markPos(curpos,YES); //留下足迹
e.order=curstep;e.seat=curpos;e.di=RIGHT;
Push(S,e); //当前位置加入路径
if(curpos.x==end.x&&curpos.y==end.y) //当前位置是出口
return TRUE;
curpos=nextPos(curpos,RIGHT);
curstep++;
}
else{ //当前位置不能通过
if(!Empty(*S)){
if(Pop(S,&e)==ERROR) return FALSE;
while(e.di==UP&&!Empty(*S)){
//四个方向都试探过,没有找到通路也不能继续探索,则回溯
curpos=e.seat;markPos(curpos,NO);
if(Pop(S,&e)==ERROR) return FALSE;
}
if(e.di!=UP){ //四个方向还没有试探完
e.di=nextDir(e.di);
Push(S,e); //换下一个方向探索
curpos=nextPos(e.seat,e.di);
}
}
}
}while(!Empty(*S));
return FALSE;
}
void main()
{ Position startPos,endPos;
Stack path;
int i,j;
SElemType e;
if(createMaze(&startPos,&endPos)==ERROR) return ;
Solve(&path,startPos,endPos);
while(!Empty(path)){ //输出出口到入口的路径
Pop(&path,&e);
printf("(%d,%d)",e.seat.x,e.seat.y);
}
//输出迷宫的图形
printf("\n");
for(i=0;i<10;i++)
{for(j=0;j<10;j++)
printf("%c ",maze[i][j]);
printf("\n");
}
}