C/C++数据结构栈的应用:迷宫求解核心算法

前面的一些类型的定义

#define MAXLENGTH 25 //最大列为25
struct PosType
{
  int x;
  int y;
};
PosType Begin,End; //入口坐标,出口坐标
//行增量,列增量,分别为东南西北
PosType direc[4]={{0,1},{1,0},{0,-1},{-1,0}};
typedef int MazeType[MAXLENGTH][MAXLENGTH]; //迷宫数组类型
MazeType m; //m是一个[25][25]的二维数组
int x,y; //迷宫的行列数
int curstep=1; //当前足迹(在入口处)为1
typedef struct
{
  int ord; //通道快在路径上的序号
  PosType seat; //通道块在迷宫中的坐标
  int di; //走向下一个通道块的方向
}SElemType;
#include"Stack.h"//栈的基本操作函数

迷宫的创建

void Init()
{
  int i,j,x1,y1;
  printf("输入迷宫的行数,列数(包括外墙):");
  scanf("%d,%d",&x,&y);
  for(i=0;i<y;i++)
  {
    m[0][i]=0; //上面
    m[x-1][i]=0; //下面
  }
  for(i=1;i<x-1;i++)
  {
    m[i][0]=0; //左边
    m[i][y-1]=0; //右边
  }
  for(i=1;i<x-1;i++)
   for(j=1;j<y-1;j++)
    m[i][j]=1; //其余都是通道,初值为1
  printf("请输入迷宫内墙的单元数(不包括外墙):");
  scanf("%d",&j);
  printf("请依次输入迷宫内墙的行列数(eg:3,4):\n");
  for(i=1;i<=j;i++)
  {
    scanf("%d,%d",&x1,&y1);
    m[x1][y1]=0;
  }
  printf("迷宫结构如下(1为通路,0为墙):\n");
  Print1();
  printf("请输入起点的行列数(eg:1,1):");
  scanf("%d,%d",&Begin.x,&Begin.y);
  printf("请输入终点的行列数(eg:8,8):");
  scanf("%d,%d",&End.x,&End.y);
}

核心算法中用到的函数:
1.迷宫m的b点值为1(可通过路径),返回OK,否则返回ERROR

// 定义墙元素值为0,可通过路径为1,经试探不可通过路径为-1,通过路径为足迹
Status Pass(PosType b)
{
  if(m[b.x][b.y]==1)
    return OK;
  else
    return ERROR;
}

2.使迷宫m的b点值变为足迹(已经通过的路径标识)curstep(>1)

void FootPrint(PosType b)
{
  m[b.x][b.y]=curstep+1; //+1防止开局右边死胡同出现bug
}

3.根据当前位置b和移动方向di,修改b为下一个位置

void NextPos(PosType &b, int di)
{ //0123东南西北
  b.x+=direc[di].x;
  b.y+=direc[di].y;
  //direc[4]={{0,1},{1,0},{0,-1},{-1,0}};
}

4.使迷宫m的b点值变为-1(经试探不能到达终点的路径)

void MarkPrint(PosType b)
{
  m[b.x][b.y]=-1;
}

核心算法MazePath,默认往东走,判断这一步会不会撞墙,不会就赋值一个大于1的正数,表示已经走过的路径,入栈;如果撞墙了,退栈到前一个位置,按顺时针方向依次尝试看能否走通,都走不通(遇到0以及大于1的数)标记此路不通(-1),退栈到前一个位置,换一个方向继续尝试

//迷宫中存在一条通路,求得一条放入栈中(栈底->栈顶)并返回TRUE
Status MazePath(PosType start, PosType end)
{
  PosType curpos=start; //当前位置在入口
  SqStack s; //顺序栈
  SElemType e; //栈元素,存储了足迹,位置,方向的信息
  InitStack(s); //初始化栈
  do
  {
    if(Pass(curpos)) //当前位置可以通过(未走过的通道块) m[i][j]=1才满足
    {
      //m[i][j]=0(墙),m[i][j]>1(走过的路径)
      FootPrint(curpos); //将大于1的数赋给m[i][j],留下足迹表示已经走过
      e.ord=curstep; //栈元素的序号为当前足迹curstep=1
      e.seat=curpos; //栈元素的位置为当前位置
      e.di=0; //下一个位置向东
      Push(s,e); //入栈当前位置及状态
      if(curpos.x==End.x&&curpos.y==End.y) return TRUE;
      NextPos(curpos,e.di); //当前位置以及移动方向,确定下一个位置
      curstep++; //足迹+1
    }
    else //当前位置不能通过
    {
      if(!StackEmpty(s)) //栈不空
      {
        Pop(s,e); //退栈到前一个位置
        curstep--;
        while(e.di==3&&!StackEmpty(s))
        {
          MarkPrint(e.seat); //留下不能到达终点的标记(-1)
          Pop(s,e);
          curstep--;
        }
        if(e.di<3) //未到最后一个方向(北)
        {
          e.di++; //换下一个方向探索
          Push(s,e);
          curstep++;
          curpos=e.seat; //确定当前方向
          NextPos(curpos,e.di);
        }
      }
    }
  }while(!StackEmpty(s));
  return FALSE;
}

程序运行结果验证算法:
在这里插入图片描述

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/* ****迷宫算法求解************* */ /**计目标:教学演示**************/ #include<stdio.h> #define rows 10 #define cols 10 typedef struct {int row; int col; }PosType;/* //坐标点结构 */ typedef struct {int ord;/*//通道块在路径上的“序号” */ PosType seat;/*//通道块在迷宫中的“坐标位置”*/ int di;/*//从此通道快走向下一通道块的“方向” */ }SElemType;/*//的元素类型 */ typedef struct {SElemType *base; SElemType *top; int stacksize; }SqStack;/*//堆结构 */ void InitStack(SqStack &s)/*//初始化堆 */ { s.base=(SElemType *)malloc(100*sizeof(SElemType)); if(!s.base) return NULL; s.top=s.base; s.stacksize=100; } int StackEmpty(SqStack s)/* //空判别*/ {return(s.top==s.base); } void Pop(SqStack &s ,SelemType &e)/*//弹 */ {e=*--s.top); } void Push(SqStack &s,SElemType e)/*//将元素压入堆*/ { *s.top++=e; } /*static int maze[rows][cols]= {{0,0,0,0,0,0,0,0,0,0}, {0,1,1,0,1,1,1,0,1,0}, {0,1,1,0,1,0,1,0,1,0}, {0,1,1,0,1,0,0,1,1,0}, {0,1,1,0,0,1,1,1,1,0}, {0,1,1,1,0,1,1,1,1,0}, {0,1,0,1,1,1,0,1,1,0}, {0,1,0,0,0,1,0,0,1,0}, {0,0,1,1,1,1,1,1,1,0}, {0,0,0,0,0,0,0,0,0,0}, }; */ /* //初始迷宫数据(1-通,0-不通)*/ static int maze[rows][cols]= {{0,0,0,0,0,0,0,0,0,0}, {0,1,1,0,1,1,1,0,1,0}, {0,1,1,0,1,0,1,1,1,0}, {0,1,1,1,0,0,0,0,1,0}, {0,1,0,0,0,1,1,1,1,0}, {0,1,0,1,0,1,0,0,0,0}, {0,1,0,1,1,1,0,1,1,0}, {0,1,0,1,0,0,0,0,1,0}, {0,0,1,1,1,1,1,1,1,0}, {0,0,0,0,0,0,0,0,0,0}, }; /* //初始迷宫数据(1-通,0-不通)*/ static int foot[10][10]={0};/*//标记某点是否走过(1-走过,0-未走过)*/ void printpath(SqStack &s)/*//打印迷宫通路*/ {int i,j; SElemType e; while(!StackEmpty(s)) { Pop(s,e); foot[e.seat.row][e.seat.col]=1; } for(i=0;i<10;i++) {printf("\n"); for(j=0;j<10;j++) if(foot[i][j]) printf(" # "); else printf(" . "); } } int Pass(PosType pos)/*//判断当前的通道块是否可通*/ { return(maze[pos.row][pos.col]); }; void FootPrint(PosType pos) { maze[pos.row][pos.col]=0; } PosType NextPos(PosType curpos,int dir)/*//取当前通道块的下一个通道块*/ { switch(dir) {case 1: curpos.row++; break; case 2: curpos.col++; break; case 3: curpos.row--; break; case 4: curpos.col--; } return curpos;/*//将下一个通道块变为当前通道块*/ } int END(PosType curpos,PosType end) {return(curpos.row==end.row && curpos.col==end.col); } void MazePath(SqStack &s,PosType start,PosType end) {PosType curpos,nextpos; int curstep; SElemType e; SqStack *s; s=InitStack(); curpos=start; curstep=1; do{ if(Pass(curpos)) {FootPrint(curpos); e.ord=curstep;e.seat=curpos;e.di=1; Push(s,e); if(END(curpos,end)) return s; curpos=NextPos(curpos,1); curstep++; }/* end of if */ else { if(!StackEmpty(s)) { e=Pop(s); while(e.di==4 && !StackEmpty(s)) {FootPrint(e.seat);/* The same fuction as MarkPrint ? */ e=Pop(s); }/* end of while */ if(e.di<4) {e.di++;Push(s,e); curpos=NextPos(e.seat,e.di); } /* end of if */ } /* end of if */ } /* end of else */ }while(!StackEmpty(s)); curstep=0; return NULL; } void main() {SqStack *s; static PosType start={1,1},end={8,8}; s=MazePath(start,end); if(s) printpath(s); else printf("\n NO find the path!"); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值