以栈解决迷宫问题

怎么找到一个迷宫的出口呢。首先要知道迷宫长啥样,之后知道出入口,再之后就是找通路的过程了。

    显然主要的部分是如何找通路。我们就举一个例子:

《以栈解决迷宫问题》

    在这个迷宫中0就是墙,1就是路。那么我们可以用一个二维数组来表示这个迷宫。之后我们需要一种结构来实现我们表示位置的移动。

1 2 3 4 5 struct  Pos {      size_t  line;      size_t  row; };

    这个结构体通过记录行和列来表示现在处在迷宫的哪个位置。

    现在就可以开始进行找通路的过程了。我们很容易想到通过试探当前位置的周围四个或三个位置来找到下一个应该去的位置,直到走到出口就算任务完成了。但是我们在试探的过程中,走到了下个位置,一定要把之前的位置做一个标记,否则我们的程序会一直在两个位置之间走来走去。我们这里通过把之前的位置置为2来防止它走来走去。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24                  if  (pos.row>0 && maze[pos.line * 10 + pos.row - 1] == 1) //左          {              p.push(pos.line * 10 + pos.row);              pos.row--;              maze[(pos.line * 10 + pos.row)] = 2;          }          else  if  (pos.row < 9 && maze[pos.line * 10 + pos.row + 1] == 1) //右          {              p.push(pos.line * 10 + pos.row);              pos.row++;              maze[(pos.line * 10 + pos.row)] = 2;          }          else  if  (pos.line > 0 && maze[(pos.line - 1) * 10 + pos.row] == 1) //上          {              p.push(pos.line * 10 + pos.row);              pos.line--;              maze[(pos.line * 10 + pos.row)] = 2;          }          else  if  (pos.line < 9 && maze[(pos.line + 1) * 10 + pos.row] == 1) //下          {              p.push(pos.line * 10 + pos.row);              pos.line++;              maze[(pos.line * 10 + pos.row)] = 2;          }

    这段代码就是对上下左右四个方向进行试探的过程,其中我们用一个栈记录下了我们走过的位置,因为迷宫里面有岔路,所以我们走错时需要进行回溯。而选用栈是因为栈的后进先出的特性。说到走进岔路进行回溯,当我们发现上面四种试探完成却没有通路时,就是我们已经走到了死胡同的最深处,需要进行回溯了,那末回溯的过程就是进行拿取栈顶元素,之后出栈的过程。

1 2 3 4                          maze[(pos.line * 10 + pos.row)] = 3;              pos.line = p.top() / 10;              pos.row = p.top() - pos.line*10;              p.pop();

    上面的代码就是进行回溯的过程,再加一个是否到达终点的判断就完成了主要部分。

1 2 3 4 5                  if  (pos.line * 10 + pos.row == 91)          {              PrintMaze(maze);              return  1;          }

    上面就是找路径的过程,也就是我们代码的主要逻辑部分。剩下的就是一些注意事项。

    读迷宫图我是通过文件指针,fopen,fgets,fclose来实现的。之后在创建了一个二维数组之后我们给函数传参的时候需要把它转换成一个一级指针来传递。我们操作就把它当作一个一维数组来处理。因为在内存中一维数组和二维数组是一样的,只不过表示方式不一样而已,我们这个迷宫通过二维数组表示比较直观,但是用一维数组一样可以处理。

    下面是完整的代码和运行的结果。

结果:

《以栈解决迷宫问题》

    可以看到上面的是最初的迷宫,经过我们走迷宫的过程,将走过的岔路标记为了3,正确的通路标记为了2。

    完整代码:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 #define _CRT_SECURE_NO_WARNINGS 1   #include<iostream> #include<assert.h> #include<stack> using  namespace  std;   struct  Pos {      size_t  line;      size_t  row; };   void  InitMaze( int  *maze) {      FILE  *p =  fopen ( "maze.txt" "r" );      for  ( int  i = 0; i < 10; i++)      {          for  ( int  j = 0; j < 10;)          {              int  tmp =( int )( fgetc (p))- '0' ;              if  (tmp == 0)                  maze[i*10+j] = 0;                if  (tmp == 1)                  maze[i*10+j] = 1;                if  (tmp == 1 || tmp == 0)                  j++;          }      }        fclose (p); }   void  PrintMaze( int  *maze) {      for  ( int  i = 0; i < 10; i++)      {          for  ( int  j = 0; j < 10; j++)          {              cout << maze[i * 10 + j] <<  " " ;          }          cout << endl;      }      cout << endl; }   int  GoMaze( int  *maze,Pos start) {      assert (maze);      stack< int > p;            Pos pos;      pos.line = start.line;      pos.row = start.row;        while  (1)      {          maze[(pos.line * 10 + pos.row)] = 2;            if  (pos.row>0 && maze[pos.line * 10 + pos.row - 1] == 1) //左          {              p.push(pos.line * 10 + pos.row);              pos.row--;              maze[(pos.line * 10 + pos.row)] = 2;          }          else  if  (pos.row < 9 && maze[pos.line * 10 + pos.row + 1] == 1) //右          {              p.push(pos.line * 10 + pos.row);              pos.row++;              maze[(pos.line * 10 + pos.row)] = 2;          }          else  if  (pos.line > 0 && maze[(pos.line - 1) * 10 + pos.row] == 1) //上          {              p.push(pos.line * 10 + pos.row);              pos.line--;              maze[(pos.line * 10 + pos.row)] = 2;          }          else  if  (pos.line < 9 && maze[(pos.line + 1) * 10 + pos.row] == 1) //下          {              p.push(pos.line * 10 + pos.row);              pos.line++;              maze[(pos.line * 10 + pos.row)] = 2;          }          else          {              maze[(pos.line * 10 + pos.row)] = 3;              pos.line = p.top() / 10;              pos.row = p.top() - pos.line*10;              p.pop();          }            if  (pos.line * 10 + pos.row == 91)          {              PrintMaze(maze);              return  1;          }      }   }   void  Mazetest() {      int  maze[10][10];      Pos p;      p.line = 2;      p.row = 0;      InitMaze(( int  *)maze);      PrintMaze(( int  *)maze);      GoMaze(( int  *)maze,p); }   int  main() {      Mazetest();      return  0; }
    原文作者:迷宫问题
    原文地址: https://blog.csdn.net/A_stupid_dog/article/details/51744642
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞