问题描述
从入口出发,按某一方向向前探索,若能走通(未走过的),即某处可以到达,则到达新点,否则试探下一方向;若该点所有的方向均没有通路,则沿原路返回到前一点,换下一个方向再继续试探,直到所有可能的通路都探索到,或找到一条通路,或无路可走又退回到入口点。
退回到的“前一点”正是刚刚才被访问过的,具有“后进先出”的特性,需要用栈保存所能够到达的每一点的下标及从该点前进的方向。
迷宫问题数据结构
用二维数组maze[M][N]来表示迷宫,图中红框内的部分为迷宫,而迷宫的四周的值全部为1(即不通)。这样设计的话,将迷宫中所有点都演变成迷宫中部的某点,可以保证无论哪个点的试探方向都是4个。
方向试探表示
typedef struct{//x,y方向的向量int incX,intcY;
} Direction;
Direction direct[4];
//从某点(x,y)按某一方向v(0<=v<=3)达到新的点(line,col)的坐标
line=x+direct[v].incX;
col=y+direct[v].intcY;
栈中元素的组织
typedef struct{int x,y;//当前访问的迷宫格子的横纵坐标 int direction;//当前方向
}Box;
防止重复到达某点
方案一:
-
另外设置标志数组flag[m][n],其所有元素初始化为0,当达到某一点(i,j)时,将其对应的flag[i][j]设置为1,下次试探到该位置时,就不能选它了。
方案二 -
当到达某点(i,j)后将对应maze[i][j]设置为-1,其它点未到达过的点其值只能是1或0,可与未到达过的点区别开
代码实现
#include<stdio.h>
#define MAXQ 100
#define MAZN 10
//初始化迷宫
int n=8;
char Maze[MAZN][MAZN]={{'0','1','1','1','1','1','1','1'},{'0','0','0','0','0','1','1','1'},{'1','0','1','1','0','0','0','1'},{'1','0','1','1','0','1','1','0'},{'1','0','1','1','1','1','1','1'},{'1','0','1','1','0','0','0','1'},{'1','0','0','0','0','1','0','0'},{'1','1','1','1','1','1','1','0'}
};//方向结构体 struct Direction{int incX,incY;};Direction dir[4]={{0,-1},{1,0},{0,1},{-1,0}}; //当前位置,探索的方向 struct Position{int x,y;int pre;};Position qu[MAXQ];//队头和队尾 int front=-1,rear=-1;//输出迷宫路径 void disppath(int front){int i,j;//之前走过设置为-1的都还原为0 for(i=0;i<n;i++)for(j=0;j<n;j++)if(Maze[i][j]=='-1')Maze[i][j]='0';int k=front;//能走通的路径设置为空 while(k!=-1){Maze[qu[k].x][qu[k].y]=' ';k=qu[k].pre;}//遍历出该路径 for(i=0;i<n;i++){printf(" ");for(int j=0;j<n;j++)printf("%c",Maze[i][j]);printf("\n");}//输出路径具体位置for(i=0;i<n;i++){for(int j=0;j<n;j++)if(Maze[i][j]==' ')printf("(%d,%d)-->",i,j); } printf("End");}//广度优先遍历 void BFS(int x,int y){Position p,p1,p2;p.x=x;p.y=y;p.pre=-1;//走过的位置为-1,下次不能再走了 Maze[p.x][p.y]='-1';//队尾++ rear++;//更新当前解 qu[rear]=p;while(front!=rear){//队头++ front++;p1=qu[front];//找到一条通路,输出路径 if(p1.x==n-1&&p1.y==n-1){disppath(front);return;}//试探上,右,下,左四个方向(0,-1)(1,0)(0,1)(-1,0) for(int k=0;k<4;k++){p2.x=p1.x+dir[k].incX;p2.y=p1.y+dir[k].incY;//满足,不能为负,不能超出迷宫,要是通路 if(p2.x>=0&&p2.y>=0&&p2.x<n&&p2.y<n&&Maze[p2.x][p2.y]=='0'){//该位置走过为-1 Maze[p2.x][p2.y]='-1';//更新方向 p2.pre=front;rear++;//入队 qu[rear]=p2;}}}}int main(){int x=0,y=0;printf("迷宫路径:\n");BFS(x,y);return 0;}
迷宫路径:11111111111111 1111111 1111101 1111111 11 11 11111111(0,0)-->(1,0)-->(1,1)-->(2,1)-->(3,1)-->(4,1)-->(5,1)-->(5,4)-->(5,5)-->(5,6)-->(6,1)-->(6,2)-->(6,3)-->(6,4)-->(6,6)-->(6,7)-->(7,7)-->End