利用栈实现迷宫求解

利用栈实现迷宫求解

  • 前言:众所周知,栈是(First in last out)先进后出的数据结构,利用这个属性可以实现类似与回溯的方式,比如当前数据满足条件,则入栈,否则出栈返回上一级,依次循环。

  • 在本题中,将每个迷宫路径上的点封装成上下左右四个方向数节点,先入栈迷宫入口节点,如果上下左右没被使用,则将其上下左右的点入栈,否则出栈。如果最终达到迷宫终点则成功,否则失败。

如下是每个节点的数据结构

 1 typedef struct{
 2     int top;
 3     int bottom;
 4     int left;
 5     int right;
 6 }direction;  //方向
 7
 8 typedef struct{
 9    int x;
10    int y;
11 }point;   //位置
12
13
14 typedef struct StackNode{
15     direction direct;
16     point position;
17     struct StackNode *next;//指向下一个节点
18 }*LinkStackPtr;//节点数据结构

链栈及基本操作实现

 1 typedef struct{
 2     LinkStackPtr top;//指向链栈头
 3     int count;//节点个数
 4 }LinkStack;//定义链栈
 5
 6
 7 bool isEmpty(LinkStack L){
 8     if(L.count==1)return true; 1表示迷宫入口
 9     return false;
10 }
11
12 Status createLink(LinkStack &L){
13     L.top=(LinkStackPtr)malloc(sizeof(StackNode));
14     if(!L.top)exit(OVERFLOW);//       L.top=NULL;     //创建链表
15     L.count++;
16     return OK;
17 }
18
19 LinkStackPtr GetTop(LinkStack L){
20     return L.top;             //放回头结点
21 }
22
23
24 Status Push(LinkStack &L,LinkStackPtr s){
25     s->next=L.top;
26     L.top=s;
27     L.count++;      //入栈
28     return OK;
29 }
30
31
32 Status Pop(LinkStack &L){
33     LinkStackPtr p;
34     if(isEmpty(L)){
35         return ERROR;
36     }
37     p=L.top;        //出栈
38     L.top=L.top->next;
39     free(p);
40     L.count--;
41     return OK;
42 }

以下是预定义及用数组实现的迷宫地图:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<malloc.h>
 4
 5
 6 #define OK 1
 7 #define ERROR 0
 8 #define OVERFLOW -2
 9
10 #define size 8
11
12
13 int enterx,entery;//入口坐标
14 int exitx,exity;//出口坐标
15
16
17 int map[size][size]={
18     {1,1,1,0,1,1,1,1},
19     {1,1,1,0,1,1,1,1},
20     {1,0,0,0,1,0,1,1},
21     {1,1,1,0,1,0,1,1},
22     {1,1,1,0,0,0,1,1},
23     {1,1,1,0,1,1,1,1},
24     {1,1,1,0,0,0,0,0},
25     {1,1,1,1,1,1,1,1}
26 };//迷宫地图,1代表墙壁 0代表路
27
28
29 void findMap(int map[][size]){
30     enterx=entery=0;
31     exitx=exity=0;
32     for(int i=0;i<size;i++){
33         for(int j=0;j<size;j++){
34             if((i==0||i==size-1)&&map[i][j]==0){
35                 enterx=i;
36                 entery=j;
37             }
38             if((j==0||j==size-1)&&map[i][j]==0){
39                 exitx=i;
40                 exity=j;
41             }
42         }
43     }//搜寻地图的入口和出口
44     if((enterx==exitx)&&(entery==exity)){//出入口相同或者没有出入口则迷宫无解
45         printf("该迷宫无解");
46         system("pause");
47         exit(ERROR);
48     }
49 }
50
51 void printMap(int a[][size]){
52     for(int i=-0;i<size;i++){
53         for(int j=0;j<size;j++){
54             printf("%d ",a[i][j]);//打印迷宫
55         }
56         printf("\n");//
57     }
58 }

以下是主函数和实现:

  1 bool panduan(int x,int y){
  2     if(map[x][y]==0){
  3         return true;
  4     }return false;
  5 }              //判断是否是没走过的迷宫快
  6
  7
  8
  9 main(){        printMap(map);
 10     bool flag=false;
 11     LinkStack L;
 12     createLink(L);//创建链表
 13
 14
 15     LinkStackPtr p;
 16     p=(LinkStackPtr)malloc(sizeof(struct StackNode));
 17     p->position.x=enterx;
 18     p->position.y=entery;
 19     p->direct.top=1;
 20     p->direct.right=0;
 21     p->direct.left=0;
 22     p->direct.bottom=0;//插入迷宫的入口
 23     map[p->position.x][p->position.y]=2;
 24     Push(L,p);
 25
 26
 27     while(!isEmpty(L)){
 28         LinkStackPtr q;
 29         q=GetTop(L);
 30         if(q->position.x==exitx&&q->position.y==exity){
 31             flag=true;
 32             break;
 33         }      //到达迷宫终点,结束返回
 34
 35
 36
 37         if(q->direct.top==0){//向上走
 38             if(q->position.x-1>=0){//如果在迷宫范围内
 39                 if(panduan(q->position.x-1,q->position.y)){//判断走否是没走过的迷宫快
 40                     q->direct.top=1;//向上置为1,表示已经走过
 41                     LinkStackPtr m=(LinkStackPtr)malloc(sizeof(struct StackNode));
 42
 43                     m->position.x=q->position.x-1;
 44                     m->position.y=q->position.y;
 45
 46                     m->direct.bottom=1;
 47                     m->direct.left=0;
 48                     m->direct.right=0;
 49                     m->direct.top=0;//插入向上的迷宫快
 50
 51                     map[m->position.x][m->position.y]=2;
 52                     Push(L,m);//迷宫快入栈
 53                 }else{
 54                     q->direct.top=1;
 55                 }
 56             }
 57         }
 58         else if(q->direct.right==0){
 59             if(q->position.y+1<8){
 60                 if(panduan(q->position.x,q->position.y+1)){
 61                     q->direct.right=1;
 62                     LinkStackPtr m=(LinkStackPtr)malloc(sizeof(struct StackNode));
 63
 64                     m->position.x=q->position.x;
 65                     m->position.y=q->position.y+1;
 66
 67                     m->direct.bottom=0;
 68                     m->direct.left=1;
 69                     m->direct.right=0;
 70                     m->direct.top=0;
 71
 72                     map[m->position.x][m->position.y]=2;
 73                     Push(L,m);
 74                 }else{
 75                     q->direct.right=1;
 76                 }
 77             }
 78         }
 79         else if(q->direct.bottom==0){
 80             if(q->position.x+1<8){
 81                 if(panduan(q->position.x+1,q->position.y)){
 82                     q->direct.bottom=1;
 83                     LinkStackPtr m=(LinkStackPtr)malloc(sizeof(struct StackNode));
 84
 85                     m->position.x=q->position.x+1;
 86                     m->position.y=q->position.y;
 87
 88                     m->direct.bottom=0;
 89                     m->direct.left=0;
 90                     m->direct.right=0;
 91                     m->direct.top=1;
 92
 93                     map[m->position.x][m->position.y]=2;
 94                     Push(L,m);
 95                 }else{
 96                     q->direct.bottom=1;
 97                 }
 98             }
 99         }
100         else if(q->direct.left==0){
101             if(q->position.y-1>=0){
102                 if(panduan(q->position.x,q->position.y-1)){
103                     q->direct.left=1;
104                     LinkStackPtr m=(LinkStackPtr)malloc(sizeof(struct StackNode));
105
106                     m->position.x=q->position.x;
107                     m->position.y=q->position.y-1;
108
109                     m->direct.bottom=0;
110                     m->direct.left=0;
111                     m->direct.right=1;
112                     m->direct.top=0;
113
114                     map[m->position.x][m->position.y]=2;
115                     Push(L,m);
116                 }else{
117                     q->direct.left=1;
118                 }
119             }
120         }else if(q->direct.left==1&&q->direct.right==1&&q->direct.top==1&&q->direct.bottom==1){
121             map[q->position.x][q->position.y]=0;
122             Pop(L);
123         }
124
125
126
127
128     }
129     //判断是否找到路径
130     if(flag==true){
131
132         printf("成功找到路径,0:未走路径  1:墙壁  2:迷宫路径 \n");
133         printMap(map);
134     }else{
135         printf("未找到路径");
136     }
137
138
139
140
141 }

运行结果:

改进:将数组的长度以及出口和入口的坐标预定义便于改变。

时间: 2024-11-06 23:31:38

利用栈实现迷宫求解的相关文章

数据结构应用:利用栈破解迷宫游戏

最近刚开始学数据结构,发现数据结构真是个神奇的东西哈,很多现实中的问题都可以用不同的数据结 构来解决,比如利用和栈中缀表达式编写一个计算机程序,利用栈破解迷宫游戏,今天我就来跟大家分 享一下如何利用栈来破解迷宫游戏. 学过数据结构的人都知道,栈的特点是:后进先出(First In Last Out);也就是说只能在栈的尾部进 行压栈和出栈,而且出栈的时候只能从最后一个数据开始.如下图: 而我们在破解迷宫游戏的时候采用的方法是"回溯",也就是在寻找通路的时候,每找到一个通路,就将这个数据

迷宫问题求解(一)利用栈与递归求解出口

本文适合于对迷宫问题已有初步研究,或阅读代码能力较强的人. 因此,如果你对迷宫问题一无所知,请参考其他更详细的资料. 迷宫问题,是一个对栈(Stack)典型应用的例子之一. 假如,有如下10X10的迷宫(0代表通路,1代表障碍),我们需要用写程序来找出迷宫的出口. 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 0 0 0 0 1 0 0 0 1 1 1 1 0 1 1 0 1 0 0 1 1 1 0 1 0 0 1 0 1 1 1 1 0 1 1 1 1 0 0

栈实现迷宫求解(c++版)

相信大家都应该听过栈吧,一直想利用栈来实现一个算法,最近有点空,就利用栈的先进后出的特性来完成迷宫求的问题,下面将详细介绍栈的实现和迷宫求解的过程,可以很好的学习栈的使用. 栈有两种实现方法,一种是顺序,即数组形式,一种是线性,即链表形式,个人还是比较喜欢链表形式实现栈的基本功能. 首先弄一个简单的迷宫,如图: 我们很容易看出这个迷宫解的路径,那怎么让计算机帮我们求解出来呢. 首先我们要对迷宫数据化,很容易想到二维数组来表示,0表示通路,1表示障碍,即表示为: int map[4][4]={ {

汉诺塔(Tower of Hanoi)问题的求解——利用栈与递归

汉诺塔(Tower of Hanoi)问题的求解--利用栈与递归 1. 汉诺塔问题的提法 汉诺塔问题是使用递归解决问题的经典范例. 传说婆罗门庙里有一个塔台,台上有3根标号为A.B.C的用钻石做成的柱子,在A柱上放着64个金盘,每一个都比下面的略小一点.把A柱上的金盘全部移到C柱上的那一天就是世界末日. 移动的条件是:一次只能移动一个金盘,移动过程中大金盘不能放在小金盘上面.庙里的僧人一直在移个不停,移动的最少总次数是264?1次,如果每秒移动一次的话,需要500亿年. 2. 求解汉诺塔问题的算

利用栈求解迷宫问题

利用栈求解迷宫问题 源代码: #include<stdio.h> #include<stdlib.h> #define M 8 #define N 8 #define MaxSize M*N typedef struct { int i;//当前方块的行号 int j;//当前方块的列号 int di; //di是下一个可走的相邻方块的方位号 }Box; typedef struct { Box data[MaxSize]; int top;      //栈顶指针 }StType

数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值

一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚,所以很多需要自己揣摩.这也体现了算法和程序设计语言的特点,算法更侧重本质的描述,而任何编程语言都要照顾到实现的细节以及数据类型等语法方面的需求. 表达式求值: [编码中....] 二.头文件 迷宫求解: 1 //3_2_maze.h 2 /** 3 author:zhaoyu 4 email:[em

AI-随机迷宫&amp;迷宫求解

本文记录了,人工智能中简单的搜索策略中的路径搜索策略中的A*算法,来实现迷宫寻路的问题.(这只是一次本人的课外作业) 完整的程序源码已经发送到我的Git.这里只记录了我的思路和感想以及收获. 产生随机迷宫 迷宫求解没有迷宫怎么可以呢.而本人是个懒人,每次都要手动输入迷宫,重复性的工作让我很不爽.你可以在程序中用数组定义一个迷宫啊,有强迫症的我,怎么可以这样随便的要求自己的程序呢.及时求解算法的出来了,但是测试数据有限,还是让我很不爽的,所以,干脆先花一些时间,写个随机迷宫的产生吧. 遇事先搜索,

迷宫求解

1.找出一条迷宫通路 //迷宫求解. #include"stdlib.h" #include"stdio.h" #include<stack> #include<iostream> using namespace std; typedef struct Pseat{ int x; int y; bool operator==(Pseat& rhs) { return x==rhs.x&&y==rhs.y; } //操作

转载:迷宫求解

迷宫求解----递归实现 2010-01-14 14:02:28|  分类: 算法及分析|举报|字号 订阅 一.问题的分析: 本问题的求解,关键是如何找到求解任意两个点间,按照以上基本思想而走出的路线.按照这个路线,我们可以通过图形函数来动态的显示迷宫的搜索过程. 计算机解迷宫解通常用的是“穷举求解”方法,即从入口出发,顺着某一个方向进行探索,若能走通,则继续往前进,否则沿着原路退回,换一个方向继续探索,直至出后位置,求得一条通路.假如所有可能的通路都探索到位能到达出口,则所设定的迷宫没有通路.