迷宫问题

来源:互联网 发布:淘宝客鹊桥计划怎么建 编辑:程序博客网 时间:2024/04/28 06:43

         

         给定一个迷宫,入口为左上角,出口为右下角,问是否有路径从入口到出口,若有则输出一条这样的路径。迷宫问题中,在寻找路径时,采用的方法通常是:从入口出发,沿某一方向向前试探,若能走通,则继续向前进;如果走不通,则要沿原路返回,换一个方向再继续试探,直到所有可能的能跟都试探完成为止。为了保证在任何位置上都能沿原路返回(回溯),要建立一个后进先出的栈来保存从入口到当前位置的路径,而且在求解迷宫路径中,所求得的路径必须是简单路径。即在求得的路径上不能有重复的同一块通道。

          为表示迷宫,设置一个数组,其中每个元素表示一个方块的状态,为0时表示对应方块是通道,为1时表示对应方块为墙。


主要程序如下:         

/** @description:初始化迷宫*/Status InitMaze(MazeType *M) {int i,j;char mz[ROW][COLUMN] = {'#',' ','#','#','#','#','#','#','#','#',  '#',' ',' ','#',' ',' ',' ','#',' ','#',  '#',' ',' ','#',' ',' ',' ','#',' ','#',  '#',' ',' ',' ',' ','#','#',' ',' ','#',  '#',' ','#','#','#',' ',' ',' ',' ','#',  '#',' ',' ',' ','#',' ','#',' ','#','#',  '#',' ','#',' ',' ',' ','#',' ',' ','#',  '#',' ','#','#','#',' ','#','#',' ','#',  '#','#',' ',' ',' ',' ',' ',' ',' ',' ',  '#','#','#','#','#','#','#','#','#','#'  };M->maze = (char **) malloc(sizeof(char *) * ROW);M->footprints = (int **) malloc(sizeof(int *) * ROW);if(!M->maze || !M->footprints) exit(OVERFLOW);for(i = 0; i < ROW ; i++ ) {M->maze[i] = (char *) malloc(sizeof(char) * COLUMN);M->footprints[i] = (int *) malloc(sizeof(int) * COLUMN);if(!M->maze[i] || !M->footprints[i])exit(OVERFLOW);}for(i = 0; i < ROW;i++) {for(j = 0; j < COLUMN; j++){M->maze[i][j] = mz[i][j];M->footprints[i][j] = 0;}}M->row = ROW;M->column = COLUMN;return OK;}/** @description:打印迷宫*/void PrintMaze(MazeType *M) {int i,j;for(i = 0; i < M->row; i++) {for(j = 0; j < M->column; j++) {printf("%c",M->maze[i][j]);}printf("\n");}}/** @description:求解迷宫路径  @more: 对于迷宫中每个方块,都有上下左右四个方块相邻,第i行第j列的当前方块的位置为(i,j),规定上方方块为方位0,   按顺时针方向递增编号。假设从方位0到方位3的方向查找下一个可走方块*/Status MazePath(MazeType maze,SqStack *S,PosType start,PosType end) {PosType curpos;int curstep;SElemType elem;InitStack(S);curpos = start;curstep = 1;do {if(Pass(&maze,curpos)) {FootPrint(&maze,curpos);elem = SetElem(curpos,curstep,1);Push(S,elem);if(curpos.x == end.x && curpos.y == end.y )return TRUE;curpos = NextPos(curpos,1);curstep++;}else {if(!StackEmpty(*S)) {Pop(S,&elem);//这种情况是:东南西已经while(elem.di == 4 && !StackEmpty(*S)) {MarkPrint(&maze,elem.seat);  //此路不通,做标记Pop(S,&elem);}if(elem.di < 4) {//按东南西北的方向调整探测elem.di++;Push(S,elem);curpos = NextPos(elem.seat,elem.di);}}}}while(!StackEmpty(*S));return FALSE;}//标记走不通的点Status MarkPrint(MazeType *M,PosType pos) {if(pos.x > M->row || pos.y > M->column )return ERROR;M->footprints[pos.x][pos.y] = 1;return OK;}//标记已经走过的点Status FootPrint(MazeType *M,PosType pos) {if(pos.x > M->row || pos.y > M->column )return ERROR;M->footprints[pos.x][pos.y] = 1;return OK;}//获取下一个探测点PosType NextPos(PosType curpos,int di) {//1,2,3,4 分别代表东南西北switch(di) {case 1:curpos.x++;break;case 2:curpos.y++;break;case 3:curpos.x--;break;case 4:curpos.y--;default:break;}return curpos;}//组装一个栈元素以便进栈SElemType SetElem(PosType curpos,int curstep,int di) {SElemType elem;elem.ord = curstep;elem.seat = curpos;elem.di = di;return elem;}/** @descrption:当前位置是否可以通过*/Status Pass(MazeType *M,PosType pos) {if(pos.x > M->row || pos.y > M->column)return ERROR;if(M->footprints[pos.x][pos.y] == 0 && M->maze[pos.x][pos.y] == ' ')return TRUE;elsereturn FALSE;}//打印结果void PrintFoot(SqStack S,MazeType *M) {int i,j;SElemType *p;for(i = 0; i < M->row ; i++) {for(j = 0; j < M->column ; j++) {M->footprints[i][j] = 0;}}p = S.top;while(p != S.base) {M->footprints[p->seat.x][p->seat.y] = 1;*p--;}for(i = 0; i < M->row ; i++) {for(j = 0; j < M->column; j++) {printf("%d",M->footprints[i][j]);}printf("\n");}}

完整的代码:https://github.com/doodlesomething/doodlesomething/tree/master/DataStruct/stack/MazePath


0 0
原创粉丝点击