栈的应用——迷宫问题

这里结合了栈+深度优先算法+回溯,难点在搜索迷宫路径

一 搜索迷宫路径思想如下:

从迷宫入口进入之后,从这里开始搜索其上下左右是否有障碍,如不是障碍就移动到这个位置上,并把该位置入栈,并从它开始继续搜索,若是障碍就选择另外一个方向,为了防止出现重复搜索,定义一个与迷宫大小相等的标记数组,将有障碍的和已经走过的位置标记为1(障碍),同时保留搜索的路径痕迹,在搜索下一个位置之前,将当前位置保存在栈中,如果所有相邻的非障碍位置都被搜索过仍未找到通往出口的路径,回退到上次的位置,并把回退前位置标记消除,再查看这个位置的其他方向是否被搜索过,如果所有的回退都被搜索过则表明不存在入口到出口的路径,这就是深入优先搜索算法。
简而言之,搜索路径就是顺着一个方向前进探索,若能走通则继续前进,否则回退到上一个位置。这里就需要使用栈的FILO特性

二 完整代码

[cpp] view plain copy

  1. /*利用深度优先算法+堆栈+回溯算法求解迷宫问题*/  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. #include <string.h>  
  5. #include <memory.h>  
  6. #define MAXLENTH 51  
  7. struct point  
  8. {  
  9.     int x;  
  10.     int y;  
  11. }Point[100];//定义坐标,记录走出迷宫路线  
  12. char Maze[MAXLENTH][MAXLENTH];//定义存储迷宫的数组  
  13. int visited[MAXLENTH][MAXLENTH],top = -1,row,col,flag = 0;  
  14. //visited数组标记是否走过或者有障碍,top为栈顶,row col为迷宫的  
  15. //行列,flag标记是否有通路到达出口  
  16. int direction[4][2]={{0,1},{0,-1},{1,0},{-1,0}};//定义四个行走方向,上下前后  
  17.   
  18. void push(int x,int y)//进栈函数  
  19. {  
  20.     Point[++top].x = x;  
  21.     Point[top].y = y;  
  22. }  
  23.   
  24. void pop()//出栈函数  
  25. {  
  26.     top--;  
  27. }  
  28.   
  29. void Depth_First_Search(int x,int y)//对迷宫进行深度优先搜索  
  30. {  
  31.     int a,b,i;  
  32.     if(Maze[x][y]=='E')  
  33.     {  
  34.         flag = 1;//到达出口,标记为1;  
  35.         return;  
  36.     }  
  37.     for(i=0;i<4;i++)//从该坐标的四个方向进行搜索  
  38.     {  
  39.         a = x + direction[i][0];  
  40.         b = y + direction[i][1];  
  41.         if(a>0&&a<=row&&b>0&&b<=col&&!visited[a][b])  
  42.         {//下一步走的方向需要满足坐标不能超越迷宫范围且没有走过或者有障碍  
  43.             visited[a][b] = 1;//先标记走过  
  44.             push(a,b);  
  45.             Depth_First_Search(a,b);//递归,继续搜索  
  46.             if(flag)  
  47.                 return;//找到入口了  
  48.             visited[a][b] = 0;//当前路不通且没有达到出口,回退,搜索下一个方向  
  49.             pop(); //不是正确路径不保存  
  50.         }  
  51.     }  
  52. }  
  53. void output()//输出函数  
  54. {  
  55.     int i;  
  56.     if(!flag)  
  57.         printf("没有到达出口的通路\n");  
  58.     else  
  59.     {  
  60.         printf("从入口走到出口的路线为;\n");  
  61.         for(i=0;i<=top;i++)  
  62.         {  
  63.             printf("(%d,%d)",Point[i].x,Point[i].y);  
  64.             if(i!=top)  
  65.                 printf("->");  
  66.         }  
  67.         printf("\n");  
  68.     }  
  69. }  
  70.   
  71. int   main()  
  72. {  
  73.     int i,j,x,y;  
  74.     printf("输入迷宫的行数row和列数col:\n");  
  75.     scanf("%d%d",&row,&col);  
  76.     memset(visited,0,sizeof(visited));  
  77.     /*void *memset(void *s, int ch, unsigned n); 
  78.     将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 
  79.   块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 
  80.   其返回值为指向S的指针。*/  
  81.     getchar();  
  82.     printf("输入迷宫分布图S表示入口,E表示出口,1表示障碍,0代表通路\n");  
  83.     for(i=1;i<=row;i++)//输入迷宫分布图  
  84.     {  
  85.         for(j=1;j<=col;j++)  
  86.         {  
  87.             scanf("%c",&Maze[i][j]);  
  88.             if(Maze[i][j]=='1')  
  89.                 visited[i][j] = 1;  
  90.             else if(Maze[i][j]=='S')//找到入口  
  91.             {  
  92.                 x = i;  
  93.                 y = j;  
  94.             }  
  95.         }  
  96.         getchar();  
  97.     }  
  98.     visited[x][y] = 1;//走过的标记为1  
  99.     push(x,y);//坐标入栈  
  100.     Depth_First_Search(x,y); //从入口开始搜索  
  101.     output(); //输出  
  102.     return 0;  
  103. }  

结果

转载:http://blog.csdn.net/xsf50717/article/details/39962211

时间: 2024-10-31 10:22:22

栈的应用——迷宫问题的相关文章

利用栈实现迷宫的求解

问题描述:这时实验心理学中的一个典型的问题,心理学家吧一只老鼠从一个无顶的大盒子的入口处赶进迷宫.迷宫设置很多隔壁,对前进方向形成了许多障碍,心理学家在迷宫的唯一出口处放置了一块奶酪,吸引老鼠仔迷宫中寻找通路以到达出口. 求解思想:回溯法是一种不断试探且及时纠正错误的搜索方法,下面的求解过程采用回溯法.从入口出发,按某一方向向前探索,若能走通(未走过 的),即某处可以到达,则到达一个新点,否则试探下一个方向:若所有的方向均没有通路,则沿原路返回前一点,换下一个方向继续试探,直到所有可能的通路都

数据结构c++语言-数据结构C++语言解决迷宫问题

问题描述 数据结构C++语言解决迷宫问题 标题: 迷宫问题 时 限: 100000 ms 内存限制: 100000 K 总时限: 3000 ms 描述: 迷宫问题 迷宫是一个二维矩阵,其中1为墙,0为路,3为入口,4为出口.要求从入口开始,从出口结束,按照 下,左,上,右 的顺序来搜索路径. 输入: 迷宫宽度w 迷宫高度h 迷宫第一行 迷宫第二行 ... 迷宫第h 行 输出: 入口横坐标1 入口纵坐标1 横坐标2 纵坐标2 横坐标3 纵坐标3 横坐标4 纵坐标4 ... 横坐标n-1 纵坐标n-

迷宫求解非递归 DFS BFS(应用栈和队列)

栈和队列的应用对迷宫问题求解 没有递归 自己手动建的栈和队 并且输出路径 DFS的路径就是 栈中的坐标 BFS的路径在队又开了一个域存上一层的base值 语言还是用的C++ 感觉比C的封装性好很多 充分体会了一下DFS一边比BFS快 但是BFS是最优解而DFS可能不是最优解   #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace

Java中栈.回溯.迷宫问题求解

考虑使用一个二维数组表示迷宫.所有的通路用0表示,墙用1表示,出口用9表示,入口用6表 示,已经过点用3表示.输出走出迷宫的过程. 从这个问题的求解过程中可以简单总结出两个算法,一是探路过程,二是输出路线. 1.探路过程 探路过程算法可归纳为: [1]从入口位置开始,检查东西南北四个方向上的通路,如果发现出口则成功退出,否则将所 有通路坐标压入栈; [2]从栈中取出一个坐标,将其标记为当前位置(标记数字3),再次判断通路情况; [3]如此进行,直到发现出口则成功退出,若栈空而且未发现出口,则失败

c++-运用C++栈,链表等基础知识编写一个可运行的迷宫

问题描述 运用C++栈,链表等基础知识编写一个可运行的迷宫 1.1 问题描述:迷宫求解是实验心理学中的一个经典问题.从一个入口处进入迷宫,在迷宫中设置很多的障碍,前进的方向有上.下.左.右,有一个唯一的出口.给出在迷宫中寻找通路到达出口的过程.1.2 基本要求:1.2.1 设计数据结构存储迷宫1.2.2 设计存储结构存储从入口到出口的通路1.2.3 设计算法完成迷宫的求解1.2.4 分析算法的时间复杂度运用C++栈,链表等基础知识编写一个可运行的迷宫,这是数据结构的一知识迷宫图大致为从左上角走到

数据结构例程——迷宫问题(用栈结构)

本文针对数据结构基础系列网络课程(3):栈和队列中第6课时栈的应用2-迷宫问题. 例:求出从入口到出口的路径 程序实现: #include <stdio.h> #define MaxSize 100 #define M 8 #define N 8 int mg[M+2][N+2]= { {1,1,1,1,1,1,1,1,1,1}, {1,0,0,1,0,0,0,1,0,1}, {1,0,0,1,0,0,0,1,0,1}, {1,0,0,0,0,1,1,0,0,1}, {1,0,1,1,1,0,

用栈实现迷宫问题求解

源程序:   //base.h #include  #include  #include  #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define OVERFLOW -2 typedef int Status;   //stack.h #include "base.h" #define INIT_SIZE 100 //存储空间初始分配量 #define INCREMENT 10  //存储空间分配增量 ty

迷宫问题的研究与实现

[问题描述] 以一个M×N的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍.设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论. (1)根据二维数组,输出迷宫的图形. (2)探索迷宫的四个方向:RIGHT为向右,DOWN向下,LEFT向左,UP向上,输出从入口到出口的行走路径. [算法分析] 主要考查数据结构-栈.栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表.它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的

算法研究:堆栈与深度优先搜索(迷宫问题)

堆栈的访问规则被限制为Push和Pop两种操作,Push(入栈或压栈)向栈顶添加元素,Pop(出栈或弹出)则取出当前栈 顶的元素,也就是说,只能访问栈顶元素而不能访问栈中其它元素. 现在我们用堆栈解决一个有意思的问题,定义 一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫,其中的1表示墙壁,0表示可以走 的路,只能横着走或