用深度优先算法递归解决迷宫问题

来源:互联网 发布:对待新事物的态度知乎 编辑:程序博客网 时间:2024/06/05 13:26
////////////////////////注释部分/////////////////////////
任务:
  基于邻接矩阵或邻接表的存储结构,
  利用DFS算法解决迷宫问题:给定一个迷宫,
  要求输出从入口到出口的所有简单路径,所谓的简单路径是指无圈的路径。

算法简析:获得起点与终点,从起点开始对可行的方向进行上右下左
  顺序的路径检索,直到遇到迷宫出口。
  
全局变量:StType st;  //保存现有路径
   SavePath p; //保存所有路径
  
使用结构:box(int i,j,di) //保存节点信息
    StType(boxdata[],int top) //保存路径
    SavePath(StType path[],int length) //线性表保存路径
 
算法优化思路:保存所有路径
 每次找到出口,将记录的栈复制到另一个保存结构中
算法步骤:
mgpath :生成路径
 函数参数:box start,end 起点与终点 
 1.起点进栈
 2.获取栈顶元素
 3.if 栈顶元素为终点
  保存路径栈 
 4.else
  while 栈顶元素四个方向探索
   if存在方向可探索
    递归可探索方向//将可探索方向作为起点
CheckNext :检查方向是否可行
 函数参数 box next;
 if mg[next.i][next.j] = 1;return false
 else return true;
////////////////////注释部分////////////////////////

#include
#define MaxSize 25
typedef struct
{
 inti;  //当前方块的行号
 intj;  //当前方块的列号
 intdi;  //di是下一可走相邻方块的方位号
} Box;  //定义方块类型
typedef struct
{
 Box data[MaxSize];
 inttop;  //栈顶指针
} StType;  //顺序栈类型,保存路径
typedef struct
{
 StType path[10];
 int length;
}SavePath;
StType st;  //保存现有路径
SavePath p; //保存所有路径
bool pathIf = false;//保存是否存在路径
int M = 4,N =4;
int mg[6][6] = {
 { 1, 1, 1, 1, 1, 1 },
 { 1, 0, 0, 0, 1, 1 },
 { 1, 0, 1, 0, 0, 1 },
 { 1, 0, 0, 0, 1, 1 },
 { 1, 1, 0, 0, 0, 1 },
 { 1, 1, 1, 1, 1, 1 } };
 
////////////////////////DFS解迷宫/////////////////////
void mgpath (Box start,Box end);
//////////////////////////////////////////////////////
//输出全部路径
void DisPath ()
{
 int i,j;
 for (i=0; i
 {
  printf ("第%d条路径:",i+1);
  for (j=0; j<=p.path[i].top;j++)
   printf("(%d,%d) ",p.path[i].data[j].i,p.path[i].data[j].j);
  printf ("\n");
 }
}
int main ()
{
 Box start,end;
 start.i = start.j = 1;
 end.i = end.j = 4;
 start.di = end.di = 0;
 p.length = 0;
 st.top = -1;
 
 int i,j;
 printf ("迷宫如下!\n");
 for (i=0; i<6; i++)
 {
  for (j=0; j<6;j++)   
  {
   printf ("%d",mg[i][j]); 
  }
  printf ("\n");
 }
 //printf("start(%d,%d,%d),end(%d,%d,%d)\n",start.i,start.j,start.di,end.i,end.j,start.di);
 
 mgpath (start,end);
 if(!pathIf)
  printf ("迷宫无解!\n");
 else
  DisPath (); //输出 SavePath
 return 0;
}
/////////////////////////////////////////////////////////
bool CheckNext (Box next)
{
 if (mg[next.i][next.j] == 1)
  returnfalse;  
 else
  return true;
}
void mgpath (Box start,Box end)
{
 Box next;
 start.di = 0;
 st.top ++;
 st.data[st.top] = start;
 mg[start.i][start.j] = 1;
 //printf("\n------进栈st.data[%d]:(%d,%d,%d)\n",st.top,st.data[st.top].i,st.data[st.top].j,st.data[st.top].di); 
 if (start.i==end.i && start.j==end.j)//探索到终点保存路径
  
  p.path[p.length] = st;
  p.length ++;
  pathIf = true;
  mg[start.i][start.j] =0;     
  //printf("---出栈st.data[%d]:(%d,%d,%d)mg[%d][%d]=0\n",st.top,st.data[st.top].i,st.data[st.top].j,st.data[st.top].di,start.i,start.j);  
  st.top--;  
  //printf("===========终点!\n");
  return ;
 }
 next  = start;//初始化选择方向根源节点
 while (start.di<4) //当有可探索方向
 {
  //printf("对点(%d,%d)探索\n",start.i,start.j);  
  switch (start.di)//选择探索方向
  {
   case 0:
    //printf("对点(%d,%d)探索上方向\n",start.i,start.j);
    next.i--;
    if(mg[next.i][next.j]!=1)//对上方向检查是否可行
    {
     mgpath(next,end);
     //printf("继续对点(%d,%d)探索右方向\n\n",start.i,start.j);
    
    next.i++;
    break;
   case 1:
    //printf("对点(%d,%d)探索右方向\n",start.i,start.j);
    next.j++;
    if(mg[next.i][next.j]!=1)//对右方向检查是否可行
    {
     mgpath(next,end);
     //printf("继续对点(%d,%d)探索下方向\n\n",start.i,start.j);
    }
    next.j--;
    break;
   case 2:
    //printf("对点(%d,%d)探索下方向\n",start.i,start.j);
    next.i++;
    if(mg[next.i][next.j]!=1)//对下方向检查是否可行
    {
     mgpath(next,end);
     //printf("继续对点(%d,%d)探索左方向\n\n",start.i,start.j);
    
    next.i--;
    break;
   case 3:
    //printf("对点(%d,%d)探索左方向\n",start.i,start.j);
    next.j--;
    if(mg[next.i][next.j]!=1)//对左方向检查是否可行
     mgpath(next,end);
    //printf("对点(%d,%d)探索完毕\n\n",start.i,start.j);
    mg[start.i][start.j]=0;     
    //printf("---出栈st.data[%d]:(%d,%d,%d)mg[%d][%d]=0\n",st.top,st.data[st.top].i,st.data[st.top].j,st.data[st.top].di,start.i,start.j);  
    st.top--;   
    next.j++;
    break;
  }
  start.di ++;
 }
}
用深度优先算法递归解决迷宫问题


0 0