zoukankan      html  css  js  c++  java
  • 利用栈实现迷宫求解

    利用栈实现迷宫求解

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

    运行结果:

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

  • 相关阅读:
    ASP.NET Core 2.0 : 四. _Layout与_ViewStart
    [ASP.NET MVC 小牛之路]04
    [ASP.NET MVC 小牛之路]03
    [ASP.NET MVC 小牛之路]02
    [ASP.NET MVC 小牛之路]01
    Ext JS 4 的类系统
    生活沉思录 via 哲理小故事(一)
    ExtJS框架基础:事件模型及其常用功能
    ExtJS初探:了解 Ext Core
    ExtJS初探:在项目中使用ExtJS
  • 原文地址:https://www.cnblogs.com/cxyc/p/5322406.html
Copyright © 2011-2022 走看看