#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; //从当前位置走到下一位置的方向
}StackElemType; //栈元素的类型
typedef struct
{
StackElemType *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=(StackElemType*)malloc(MAXSIZE*MAXSIZE*sizeof(StackElemType));
if(!S->elem) return ERROR;
S->top=0; return OK;
}
int Push(Stack *S,StackElemType e) //元素e入栈
{ if(S->top>=MAXSIZE*MAXSIZE) return ERROR;
S->elem[S->top++]=e;
return OK;
}
int Pop(Stack *S,StackElemType *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;
}
/*按照right->down->left->top的顺序*/
Direction nextDir(Direction dir)
{ switch(dir)
{ case RIGHT: return DOWN;
case DOWN : return LEFT;
case LEFT: return UP;
}
}
int findPath(Stack *S,Position start,Position end)
{//若迷宫中存在从入口start到出口end的通道,则求得一条存放在栈S中,并返回TRUE,若迷宫中不存在从入口start到出口end的通道,并返回FALSE
Position curpos;
StackElemType 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;
StackElemType e;
if(createMaze(&startPos,&endPos)==ERROR) return ;
findPath(&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");
}
}
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
在Java中使用二维数组生成迷宫
在Java中使用二维数组生成迷宫
深度优先搜索 Java 二维数组 -
C# OpenCvSharp 实现迷宫解密
C# OpenCvSharp 实现迷宫解密
C#迷宫解密 opencv迷宫解密 System Image 二值化 -
【栈】实现迷宫求解(C++)(详解)
迷宫求解从入口进入开始, 向不同方向试探,走到死胡同就退回。找迷宫通路需要使用回
c++ 数据结构 算法 栈 回溯