迷宫问题

一、迷宫问题
1、打印迷宫。(打印二维数组)
2、简单迷宫,找出其中的通路(①迭代法。②递归法)。
单条通路试探过程
3、多条通路迷宫,找出所有的通路。
多条通路试探过程
4、多条通路和带环通路迷宫,求最短通路。
二、函数代码:
1、打印迷宫地图:

void MazePrint()  //打印迷宫
  {
      size_t i =0,j=0;
      for (i = 0; i<N; i++)
      {
          for (j=0; j<N; j++)
          {
              printf("%d ",maze[i][j]);
          }
          printf("\n");
      }
      printf("\n");
  }

2、简单迷宫,找出其中的通路(①迭代法。②递归法)。
①迭代法

int MazeGetPath(Pos entry) //迭代法找迷宫通路
  {
      Pos cur = entry;
      Pos next = cur;
      Stack s;
      StackInit(&s);
      StackPush(&s,cur);

      while (StackEmpty(&s))
      {
          cur = StackTop(&s); //栈顶为当前位置
          maze[cur.row][cur.col]=2; //注释掉当前坐标
          if (cur.col==N-1)  //迷宫出口
          {
              printf("出口坐标:(%d,%d)\n",cur.row,cur.col);
              return 1;
          }

          next = cur; //next置到当前位置
          next.row+=1;  //向下试探
          if(CheckMazeAssess(next))
          {
              StackPush(&s,next);
              continue;
          }

          next = cur;//next置到当前位置  
          next.row-=1; //向上试探
          if(CheckMazeAssess(next))
          {
              StackPush(&s,next);
              continue;
          }

          next = cur;  //next置到当前位置
          next.col+=1;  //向右试探
          if(CheckMazeAssess(next))
          {
              StackPush(&s,next);
              continue;
          }

          next = cur;   //next置到当前位置
          next.col-=1;  //向左试探
          if(CheckMazeAssess(next))
          {
              StackPush(&s,next);
              continue;

          }
          StackPop(&s);  //遇到死胡同,回溯
      }
      return 0;  //此迷宫没有出口
  }

②、递归法

void MazeGetPathR(Pos entry)  //递归法解决简单迷宫问题
  {
      Pos cur = entry;
      Pos next = cur;
      if (next.col>N-1)  //递归结束条件
      {
          printf("找到出口:%d,%d \n",next.row,next.col);
          return;
      }
      maze[entry.row][entry.col] = 2;  //标记当前位置

      next = cur;
      next.row+=1;  //if (CheckMazeAssess(next))  
      {
          MazeGetPathR(next);  //子问题
          return;
      }

      next = cur;
      next.col-=1;  //if (CheckMazeAssess(next))
      {
          MazeGetPathR(next);  //子问题
          return;
      }

      next = cur;
      next.col+=1; //if (CheckMazeAssess(next))
      {
          MazeGetPathR(next);  //子问题
          return;
      }
  } 

3、多条通路迷宫,找出所有的通路(①迭代法。②递归法)。
①迭代法

 void MazeGetPath(Pos entry) //迭代法找迷宫通路
  {
      Pos cur = entry;
      Pos next = cur;
      Stack s;
      StackInit(&s);
      StackPush(&s,cur);

      while (StackEmpty(&s))
      {
          cur = StackTop(&s); //栈顶为当前位置
          maze[cur.row][cur.col]=2; //注释掉当前坐标
          if (cur.col==N-1)  //迷宫出口
          {
              printf("出口坐标:(%d,%d)\n",cur.row,cur.col);
          }

          next = cur; //next置到当前位置
          next.row+=1;  //向下试探
          if(CheckMazeAssess(next))
          {
              StackPush(&s,next);
              continue;
          }

          next = cur;//next置到当前位置  
          next.row-=1; //向上试探
          if(CheckMazeAssess(next))
          {
              StackPush(&s,next);
              continue;
          }

          next = cur;  //next置到当前位置
          next.col+=1;  //向右试探
          if(CheckMazeAssess(next))
          {
              StackPush(&s,next);
              continue;
          }

          next = cur;   //next置到当前位置
          next.col-=1;  //向左试探
          if(CheckMazeAssess(next))
          {
              StackPush(&s,next);
              continue;

          }
          StackPop(&s);  //遇到死胡同,回溯
      }
  }

②递归法

void MazeGetPathR(Pos entry)  //递归法解决简单迷宫问题
  {
      Pos cur = entry;
      Pos next = cur;
      if (next.col>N-1)  //递归结束条件
      {
          printf("找到出口:%d,%d \n",next.row,next.col);
          return;
      }
      maze[entry.row][entry.col] = 2;

      next = cur;
      next.row-=1; //if (CheckMazeAssess(next))
      {
          MazeGetPathR(next); //子问题
      }

      next = cur;
      next.row+=1;  //if (CheckMazeAssess(next))  
      {
          MazeGetPathR(next);  //子问题
      }

      next = cur;
      next.col-=1;  //if (CheckMazeAssess(next))
      {
          MazeGetPathR(next);  //子问题
      }

      next = cur;
      next.col+=1; //if (CheckMazeAssess(next))
      {
          MazeGetPathR(next);  //子问题
      }
  }

4、多条通路和带环通路迷宫,求最短通路。

 void MazeGetShortPath(Pos entry,Stack* path)  //求取最短路径
  {
      Pos cur = entry;
      Pos next = cur;
      if (0==StackEmpty(path)) //入口处
      {
          maze[next.row][next.col] = 2; 
      }
      else  //从入口以后,每次标记的数加一。
      {
          Pos prev = StackTop(path);
          maze[next.row][next.col]=maze[prev.row][prev.col]+1; 
      }

      StackPush(path,next);  
      if (next.col==N-1)
      {
          printf("找到出口:%d,%d \n",next.row,next.col);  
          if(!StackEmpty(&shortPath) || StackSize(path)<StackSize(&shortPath))  //始终保持最短路径在shortPath栈中
          {
              if(shortPath.data)
                 free(shortPath.data);

              shortPath.data = (DataType *)malloc(sizeof(DataType)*path->top);
              memcpy(shortPath.data,path->data,sizeof(DataType)*path->top);
              shortPath.top = path->top;
              shortPath.end = path->top;
          }
      }
      next = entry;
      next.row-=1; //if (CheckMazeShortAssess(next,cur))
      {
          MazeGetShortPath(next,path);
      }

      next = entry;
      next.row+=1;  //if (CheckMazeShortAssess(next,cur))
      {
          MazeGetShortPath(next,path);
      }

      next = entry;
      next.col-=1;  //if (CheckMazeShortAssess(next,cur))
      {
          MazeGetShortPath(next,path);
      }

      next = entry;
      next.col+=1; //if (CheckMazeShortAssess(next,cur))
      {
          MazeGetShortPath(next,path);
      }

      StackPop(path);
  }

三、整体代码及测试结果
1、maze.h

void MazePrint();   //打印迷宫
void MazeGetPath(Pos entry);  //迭代寻找迷宫通路
void MazeGetPathR(Pos entry);  //递归寻找迷宫通路
Stack shortPath; 
void MazeGetShortPath(Pos entry,Stack* path);  //求取最短路径

2、maze.c

void MazePrint()  //打印迷宫
  {
      size_t i =0,j=0;
      for (i = 0; i<N; i++)
      {
          for (j=0; j<N; j++)
          {
              printf("%d ",maze[i][j]);
          }
          printf("\n");
      }
      printf("\n");
  }

  int CheckMazeAssess(Pos pos)  //检测该坐标是否可通
  {
      if (pos.row>=0 && pos.row<N 
          && pos.col>=0 && pos.col<N
          && maze[pos.row][pos.col]==1)
      {
          return 1;
      }
      return 0;
  }

  void MazeGetPath(Pos entry) //迭代法找迷宫通路
  {
      Pos cur = entry;
      Pos next = cur;
      Stack s;
      StackInit(&s);
      StackPush(&s,cur);

      while (StackEmpty(&s))
      {
          cur = StackTop(&s); //栈顶为当前位置
          maze[cur.row][cur.col]=2; //注释掉当前坐标
          if (cur.col==N-1)  //迷宫出口
          {
              printf("出口坐标:(%d,%d)\n",cur.row,cur.col);
              //return 1;
          }

          next = cur; //next置到当前位置
          next.row+=1;  //向下试探
          if(CheckMazeAssess(next))
          {
              StackPush(&s,next);
              continue;
          }

          next = cur;//next置到当前位置  
          next.row-=1; //向上试探
          if(CheckMazeAssess(next))
          {
              StackPush(&s,next);
              continue;
          }

          next = cur;  //next置到当前位置
          next.col+=1;  //向右试探
          if(CheckMazeAssess(next))
          {
              StackPush(&s,next);
              continue;
          }

          next = cur;   //next置到当前位置
          next.col-=1;  //向左试探
          if(CheckMazeAssess(next))
          {
              StackPush(&s,next);
              continue;

          }
          StackPop(&s);  //遇到死胡同,回溯
      }
      return 0;  //此迷宫没有出口
  }

 void MazeGetPathR(Pos entry)  //递归法解决简单迷宫问题
  {
      Pos cur = entry;
      Pos next = cur;
      if (next.col>N-1)  //递归结束条件
      {
          printf("找到出口:%d,%d \n",next.row,next.col);
          return;
      }
      maze[entry.row][entry.col] = 2;

      next = cur;
      next.row-=1; //if (CheckMazeAssess(next))
      {
          MazeGetPathR(next); //子问题
      }

      next = cur;
      next.row+=1;  //if (CheckMazeAssess(next))  
      {
          MazeGetPathR(next);  //子问题
      }

      next = cur;
      next.col-=1;  //if (CheckMazeAssess(next))
      {
          MazeGetPathR(next);  //子问题
      }

      next = cur;
      next.col+=1; //if (CheckMazeAssess(next))
      {
          MazeGetPathR(next);  //子问题
      }
  }

  int CheckMazeShortAssess(Pos next,Pos cur)  //检测该坐标是否可通
  {
      if (next.row>=0 && next.row<N 
          && next.col>=0 && next.col<N
          && (maze[next.row][next.col]==1 || 
          maze[next.row][next.col]>maze[cur.row][cur.col]))
      {
          return 1;
      }
      else
      {
          return 0;
      }
  }

  void MazeGetShortPath(Pos entry,Stack* path)  //求取最短路径
  {
      Pos cur = entry;
      Pos next = cur;
      if (0==StackEmpty(path)) //入口处
      {
          maze[next.row][next.col] = 2; 
      }
      else  //从入口以后,每次标记的数加一。
      {
          Pos prev = StackTop(path);
          maze[next.row][next.col]=maze[prev.row][prev.col]+1; 
      }

      StackPush(path,next);  
      if (next.col==N-1)
      {
          printf("找到出口:%d,%d \n",next.row,next.col);  
          if(!StackEmpty(&shortPath) || StackSize(path)<StackSize(&shortPath))  //始终保持最短路径在shortPath栈中
          {
              if(shortPath.data)
                 free(shortPath.data);

              shortPath.data = (DataType *)malloc(sizeof(DataType)*path->top);
              memcpy(shortPath.data,path->data,sizeof(DataType)*path->top);
              shortPath.top = path->top;
              shortPath.end = path->top;
          }
      }
      next = entry;
      next.row-=1; //if (CheckMazeShortAssess(next,cur))
      {
          MazeGetShortPath(next,path);
      }

      next = entry;
      next.row+=1;  //if (CheckMazeShortAssess(next,cur))
      {
          MazeGetShortPath(next,path);
      }

      next = entry;
      next.col-=1;  //if (CheckMazeShortAssess(next,cur))
      {
          MazeGetShortPath(next,path);
      }

      next = entry;
      next.col+=1; //if (CheckMazeShortAssess(next,cur))
      {
          MazeGetShortPath(next,path);
      }

      StackPop(path);
  }

3、test.c

void test()
 {
    Pos entry = {5,2};
    Stack path;
    StackInit(&path);
    StackInit(&shortPath);
    MazePrint();
    MazeGetPath(entry);  //迭代法
    MazeGetPathR(entry);   //递归法
    MazeGetShortPath(entry,&path);
    MazePrint();
    while (StackEmpty(&shortPath))
    {
        printf("%d,%d<-", StackTop(&shortPath).row,StackTop(&shortPath).col);

        StackPop(&shortPath);
    }
    printf("entry\n");
 }

四、涉及到栈的相关操作请戳栈的基本操作

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙跃十二

写的不错,给点鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值