zoukankan      html  css  js  c++  java
  • 应用栈解决迷宫问题的C语言实现

    题目来自于严蔚敏《数据结构》,参考伪代码实现的程序:

      1 #include <stdio.h>
      2 #include <malloc.h>
      3 //记录通道块在迷宫矩阵当中的横、纵坐标 
      4 struct Position{
      5     int x;
      6     int y;
      7 }; 
      8 //放入栈当中的通道块元素 
      9 struct SElement {
     10     int ord;//记录此通道块在整个通道当中的次序 
     11     Position p;//记录此通道块在矩阵当中的位置 
     12     int di;//记录下一次测试这一路径的临近路径的位置 
     13 }; 
     14 //创建栈数据结构
     15 #define STACK_INIT_SIZE 100
     16 #define STACKINCREMENT 10
     17 struct MyStack{
     18     SElement* base;
     19     SElement* top;
     20     int stacksize;
     21 };
     22 //创建一个栈如果创建成功则返回1,否则就返回0
     23 int InitStack(MyStack* s)
     24 {
     25     s->base=(SElement*)malloc(STACK_INIT_SIZE*sizeof(SElement));//为栈分配初始空间 
     26     if(!s->base) return 0;
     27     s->top=s->base;//设定为空栈 
     28     s->stacksize=STACK_INIT_SIZE;
     29     return 1; 
     30 }
     31 //判断栈是否为空,如果是空的就返回0,否则就返回1 
     32 int IsStackEmpty(MyStack* s)
     33 {
     34     if(s->top==s->base) return true;
     35     return false;
     36 } 
     37 //获取栈顶元素,如果栈为空就返回0 否则就返回1
     38 int GetTop(MyStack* s,SElement* e)
     39 {
     40     if(IsStackEmpty(s)) return 0;
     41     e=s->top-1;
     42     return 1; 
     43 }
     44 //获取栈的长度,并且通过程序返回 
     45 int StackLength(MyStack* s)
     46 {
     47     return s->top-s->base;
     48 }
     49 //插入元素e为新的栈顶元素,插入成功则返回1,否则返回0
     50 int  Push(MyStack* s,SElement e)
     51 {
     52     if(s->top-s->base>=STACK_INIT_SIZE)
     53     {
     54         s->base=(SElement*)realloc(s->base,(s->stacksize+STACKINCREMENT)*sizeof(SElement));
     55         if(!s->base) return 0;
     56         s->top=s->base+s->stacksize;
     57         s->stacksize+=STACKINCREMENT;
     58     }
     59     *(s->top)=e;
     60     s->top++;
     61     return 1;
     62 }
     63 //弹出栈顶元素赋值给e弹出成功返回1,弹出失败返回0
     64 int Pop(MyStack* s,SElement* e)
     65 {
     66     if(IsStackEmpty(s)) return 0;
     67     *e=*(s->top-1);
     68     s->top--;
     69     return 1;
     70 } 
     71 //定义墙元素为2 可走路径为0 已知路径为curStep 不能够通过的路径为-1 
     72 #define MazeScale 10
     73 int Maze[MazeScale][MazeScale]={{2,2,2,2,2,2,2,2,2,2},{2,0,0,2,0,0,0,2,0,2},{2,0,0,2,0,0,0,2,0,2},{2,0,0,0,0,2,2,0,0,2},
     74 {2,0,2,2,2,0,0,0,0,2},{2,0,0,0,2,0,0,0,0,2},{2,0,2,0,0,0,2,0,0,2},{2,0,2,2,2,0,2,2,0,2},{2,2,0,0,0,0,0,0,0,2},{2,2,2,2,2,2,2,2,2,2}};
     75 //辅助函数考察当前路径能否通过 
     76 bool Pass(Position posi)
     77 {
     78     //只有路径所在位置的数字为0的是可以走的 
     79     if(Maze[posi.x][posi.y]==0)
     80     {
     81         return true;
     82     } 
     83     return false; 
     84 }
     85 //按顺时针方向从东开始寻找矩阵当中某一个位置的临近位置 
     86 Position NextPosition(Position now,int direction)
     87 {
     88     Position next;
     89     int x=now.x;
     90     int y=now.y;
     91     switch(direction)
     92     {
     93         //
     94         case 1:{
     95             next.x=x;
     96             next.y=y+1;
     97             break;
     98         }
     99         //
    100         case 2:{
    101             next.x=x+1;
    102             next.y=y; 
    103             break;
    104         }
    105         //西
    106         case 3:{
    107             next.x=x;
    108             next.y=y-1;
    109             break;
    110         }
    111         //
    112         case 4:
    113         {
    114             next.x=x-1;
    115             next.y=y;
    116             break;
    117         } 
    118         default:break;
    119     }
    120     return next;
    121 }
    122 //留下足迹 
    123 void FootPrint(Position p,int step)
    124 {
    125     Maze[p.x][p.y]=step;
    126 }
    127 //路径不可走的话就留下-1的标记 
    128 void MarkPrint(Position p)
    129 {
    130     Maze[p.x][p.y]=-1;
    131 }
    132 int main()
    133 {
    134     //打印出迷宫矩阵 
    135     for(int i=0;i<MazeScale;i++)
    136     {
    137         for(int j=0;j<MazeScale;j++)
    138         {
    139             printf("%d ",Maze[i][j]);
    140         }
    141         printf("
    ");
    142     }
    143     //迷宫程序主体
    144     MyStack  path;//记录路径的栈
    145     InitStack(&path);//初始化路径数组
    146     Position curp;//当前被试位置
    147     //初始化当前位置为矩阵入口 
    148     curp.x=1;
    149     curp.y=1;
    150     int curStep=1;//被探索的步数 
    151     do
    152     {
    153         if(Pass(curp))
    154         {
    155             FootPrint(curp,curStep);//可走就在迷宫里面留下足迹 
    156             //创建一个栈元素,存储可行路径的相关值,将这个元素存储到栈当中
    157             SElement e;
    158             e.di=1;//意味着下一个被试路块为这一个路块的正上方的路块 
    159             e.ord=curStep;
    160             e.p.x=curp.x;
    161             e.p.y=curp.y;
    162             Push(&path,e);//将路径块入栈 
    163             if(curp.x==MazeScale-2 && curp.y==MazeScale-2) break; //如果被压入的路径块到了迷宫的终点就退出循环
    164             //找到下一个被试块
    165             curp=NextPosition(curp,1);//找到前一个被试块东面的路径块作为被试块
    166             curStep++;//被探索的步数加一 
    167         }else//如果当前被试路径不能够通过的话 
    168         { 
    169             if(!IsStackEmpty(&path))
    170             {
    171                 SElement e;
    172                 Pop(&path,&e);
    173                 curStep--;
    174                 //将这一段所有的周围路径都已经被测试过的路径从栈中清除 
    175                 while(e.di==4 && !IsStackEmpty(&path)){
    176                     MarkPrint(e.p); 
    177                     Pop(&path,&e);
    178                     curStep--;
    179                 }
    180                 //如果当前栈顶还有未被测试的路径就测试剩余的周围路径 
    181                 if(e.di<4)
    182                 {
    183                     curp=NextPosition(e.p,e.di+1);
    184                     e.di++;
    185                     curStep++;
    186                     Push(&path,e);
    187                 }
    188             }
    189         } 
    190     }while(!IsStackEmpty(&path));
    191     printf("
    ");
    192     //打印出结果迷宫矩阵 
    193     for(int i=0;i<MazeScale;i++)
    194     {
    195         for(int j=0;j<MazeScale;j++)
    196         {
    197             printf("%d   ",Maze[i][j]);
    198         }
    199         printf("
    ");
    200     }
    201     return 0;
    202 }
  • 相关阅读:
    C#中的委托和事件(续)【来自张子扬】
    C# 中的委托和事件[转自张子扬]
    .NET多线程编程入门
    python——configparser模块
    logger模块
    python——time模块
    os模块
    python——re模块
    selenium环境搭建
    iOS中的三大定时器
  • 原文地址:https://www.cnblogs.com/AlgrithmsRookie/p/5958040.html
Copyright © 2011-2022 走看看