利用栈实现迷宫求解

霸气de小男生 提交于 2019-12-21 21:17:16

利用栈实现迷宫求解

  •     前言:众所周知,栈是(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 }

运行结果:

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

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!