利用栈实现迷宫求解

利用栈实现迷宫求解

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

运行结果:

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

原文地址:https://www.cnblogs.com/cxyc/p/5322406.html