深度优先迷宫求解实例(C)
//maze.h #define RIGHT 0 #define DOWN 1 #define LEFT 2 #define UP 3 typedef struct Position{ //位置 int x; //行 int y; //列 }Position; //顺时针从右开始寻找临近位置,返回该临近位置 Position NextPos(Position now, int dir){ Position next; int x = now.x; int y = now.y; switch(dir){ case RIGHT: next.x = x; next.y = y+1; break; //向右走一格 case DOWN: next.x = x+1; next.y = y; break; //向下走一格 case LEFT: next.x = x; next.y = y-1; break; //向左走一格 case UP: next.x = x-1; next.y = y; break; //向上走一格 } return next; }
//mazeStack.h #include <stdlib.h> #include <stdio.h> #include "maze.h" #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 #define MAXSIZE 1000 typedef int Status; //存入栈中的元素 typedef struct Ele{ Position pos; //当前位置 int step; //当前步数 int dir; //当前方向 }Ele; typedef struct{ int Stacksize; Ele* top; Ele* base; }Stack; //创建一个栈,返回该栈。创建失败返回NULL Stack* InitStack(void){ Stack* s = (Stack*)malloc(sizeof(Stack)); s->base = (Ele*)malloc(STACK_INIT_SIZE*sizeof(Ele)); if(!s->base){ //内存分配失败 printf("内存分配失败!\n"); return NULL; } else{ s->top = s->base; s->Stacksize = STACK_INIT_SIZE; return s; } } //判断栈是否为空,是返回1,否返回0 int IsStackEmpty(Stack* s){ if(s->top == s->base) return 1; else return 0; } //获取栈的长度,返回长度 int StackLength(Stack* s){ return s->top - s->base; } //将元素e入栈,成功返回1,失败返回0 int Push(Stack* s, Ele e){ if(StackLength(s)>=s->Stacksize){ //栈满,追加存储空间 s->base = (Ele*)realloc(s->base,(s->Stacksize + STACKINCREMENT)*sizeof(Ele)); if(!s->base) return 0; s->top = s->base + s->Stacksize; s->Stacksize += STACKINCREMENT; } *(s->top)++ = e; return 1; } //弹出栈顶元素返回给e。成功返回1,失败返回0。 int Pop(Stack* s, Ele* e){ if(IsStackEmpty(s)) return 0; *e = * --s->top; return 1; } //若栈不空,则用e返回S的栈顶元素,并返回1,否则返回0 int GetTop(Stack* s, Ele* e){ if(IsStackEmpty(s)){ return 0; } *e = *(s->top-1); return 1; }
#include <stdio.h> #include "mazeStack.h" //输出迷宫地图 void PrintMaze(int maze[10][10]){ int i,j; for(i=0;i<10;++i){ for(j=0;j<10;++j){ switch(maze[i][j]){ case 0: printf(" "); break; //0表示可走的格子 case -2: printf("#"); break; //-2表示不可走的障碍物 case -1:printf(" "); break; //-1表示探索过的格子 default:printf("*"); break; //1至正无穷表示迷宫解的顺序对应的格子 } } printf("\n"); } } int main(void){ int exist = 1; //迷宫是否有解.1代表有解,0代表无解。 Stack* path = InitStack();//记录路径 if(path == NULL) exit(-1); Position now; //当前位置 //初始化位置为入口 now.x = 1; now.y = 1; int step=2; //初始步数设为1 int maze[10][10] = {{-2,-2,-2,-2,-2,-2,-2,-2,-2,-2}, //建立迷宫 {-2,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,-2}, {-2,0 ,-2,0 ,-2,0 ,-2,0 ,-2,-2}, {-2,-2,-2,0 ,-2,-2,-2,0 ,0 ,-2}, {-2,0 ,0 ,0 ,-2,0 ,0 ,0 ,-2,-2}, {-2,0 ,-2,0 ,0 ,0 ,-2,0 ,-2,-2}, {-2,0 ,-2,-2,-2,-2,-2,-2,-2,-2}, {-2,0 ,0 ,0 ,0 ,0 ,0 ,0 ,-2,-2}, {-2,-2,0 ,-2,0 ,-2,-2,0 ,0 ,-2}, {-2,-2,-2,-2,-2,-2,-2,-2,-2,-2},}; PrintMaze(maze); //输出迷宫 while(1){ if(maze[now.x][now.y]==0){ //若当前格子可走 maze[now.x][now.y]=step;//走进这个格子 Ele e; //初始化一个e e.dir = RIGHT; //初始方向向右 e.pos.x = now.x; //e的位置即当前格子 e.pos.y = now.y; e.step = step; //e记录的步数即为当前步数 Push(path,e); //将e入栈(当前格子加入路径) if(now.x==8 && now.y==8) break; //若到达终点,则退出循环 now = NextPos(now,e.dir); //试探下一个格子 step++; //步数+1 } else{ //若当前格子不可走 if(!IsStackEmpty(path)){ Ele e; Pop(path,&e); //栈顶元素出栈,赋值给e step--; //步数-1 if(e.dir<UP){ //如果当前方向不为向上(还没有探索完全部方向) now = NextPos(e.pos,e.dir+1); //试探另一个方向的下一个格子 e.dir++; //顺时针旋转一次 step++; //步数+1 Push(path,e); //将e入栈(当前格子加入路径) } while(e.dir==UP){ //如果当前方向为向上(说明已探索完全部方向) maze[e.pos.x][e.pos.y] = -1; //将格子置-1,表示探索完毕 Pop(path,&e); //栈顶元素出栈,赋值给e now.x = e.pos.x; //当前位置变更为e的位置 now.y = e.pos.y; maze[now.x][now.y]=0; //将当前格子设为可探索 step--; //步数-1 } } //若起点周围全部探索过说明迷宫无解 if(maze[1][2]<0 && maze[2][1]<0){ printf("迷宫无解"); exist = 0; break; } } }; printf("\n\n"); if(exist) PrintMaze(maze);//输出迷宫的解 return 0; }
运行截图: