运用栈求解迷宫问题C/C++

用栈解决基本的迷宫问题C/C++

1、问题描述:设置迷宫为m*n的二维数组,起点坐标为(1,1),中点坐标为(m,n),0为通路,1为死路,为防止数组越界将四周设置边界1,即数组变为(m+2)*(n+2)数组,迷宫如下....

    

迷宫
1111111111
1011101111
1101011111
1010000011
1011101111
1100110001
1011001101
1111111111

2、求解思路:

2.1、用数组对迷宫进行定义

#define m 6
#define n 8
int maze[m+2][n+2]
2.2、试探方向

在正常情况下,每个点有八个方向可以进行试探,设点坐标为(x,y)即可对该点的坐标进行加减1进行位置的变换,即加上move数组,定义如下:

typedef struct{
 int x,y;
}item;
item move[8];
//给move进行赋值
void defineMove(item move[8]){
 move[0].x = 0,move[0].y =1;
 move[1].x = 1,move[1].y =1;
 xmove[2].x = 1,xmove[2].y =0;
 move[3].x = 1,move[3].y =-1;
 move[4].x = 0,move[4].y =-1;
 move[5].x = -1,move[5].y =-1;
 move[6].x = 1,move[6].y =0;
 move[7].x = -1,move[7].y =1;
}
移动时进行运算:x = x+move[i].x;  y = y+move[i].y;

2.3、栈的设计:

 
 
 
 
3,6,0(top)
3,5,0
3,4,0
3,3,0
2,2,1
1,1,1
首先将起点压入栈,并且从正右方的点进行寻路,如果为0,即进行压栈,若不通即进行点的回溯,寻找其它方向。

栈的定义:

//点的定义
typedef struct{
int x,y,d;
}point;

//栈定义
typedef struct{
 point data[MAXSIZE];
 int top;
}MazeStack;

2.4、防止重复到达某一点,以免发生死循环,将走过的点初始化为-1,即maze[x][y] = -1。

2.5、迷宫算法的求解思想:
(1)、将栈进行初始化

 (2)、将入口点坐标及到达该点的方向(设为-1)入栈

 (3)、while(栈不为空)

      {栈顶元素=>(x,y,d)

      出栈

     求出下一个要试探的方向d++

     while(还有剩余试探方向时)

     { if(d方向可走)

        则{

           (x,y,d)入栈

            求出新点的坐标(i,j)

             将新点(i,j)切换为当前点(x,y)

             if(x,y)==(m,n)结束

             else 重置d++;

}

}

3、全部代码:

/*
 *运用顺序栈解决迷宫问题
*/
#include<stdio.h>
#include<malloc.h>
#define MAXSIZE 100
#define m 6
#define n 8
//对栈中的元素进行定义,d为方向
typedef struct{
 int x,y,d;
}point;
//对栈的结构进行定义
typedef struct{
 point data[MAXSIZE];
 int top;
}MazeStack;
//对移动数组进行定义,方便进行点的移动
typedef struct{
 int x,y;
}item;
//将栈设置为空栈
void setNULL(MazeStack *s){
 s->top = -1;
}
//判断栈是否为空
bool isEmpty(MazeStack *s){
 if(s->top>=0) return false;
 else return true;
}
//进栈操作
MazeStack * push(MazeStack *s,point x){
 if(s->top>MAXSIZE-1){
    printf("栈上溢出!\n");
    return s;
 }else{
  s->top++;
  s->data[s->top] = x;
  return s;

 }
}
//退栈操作
point * pop(MazeStack *s){
 if(isEmpty(s)){
    printf("栈为空!\n");
    return NULL;
 }else{
  s->top--;
  return &(s->data[s->top+1]);
 }
}
//取栈顶元素
point * getTop(MazeStack *s){
 if(isEmpty(s)){
    printf("栈为空!\n");
    return NULL;
 }else{
  return &(s->data[s->top]);
 }
}
//对移动的位置进行定义
void defineMove(item xmove[8]){
 xmove[0].x = 0,xmove[0].y =1;
 xmove[1].x = 1,xmove[1].y =1;
 xmove[2].x = 1,xmove[2].y =0;
 xmove[3].x = 1,xmove[3].y =-1;
 xmove[4].x = 0,xmove[4].y =-1;
 xmove[5].x = -1,xmove[5].y =-1;
 xmove[6].x = 1,xmove[6].y =0;
 xmove[7].x = -1,xmove[7].y =1;
}
//进行所有操作的测试
int main(){
  //对迷宫进行定义
  int maze[m+2][n+2],x,y,i,j,d;
  //对移动的位置进行定义
  item xmove[8];
  //定义栈的起始点
  point start,*p;
  //对栈进行定义
  MazeStack *s;
  s = (MazeStack*)malloc(sizeof(MazeStack));
  setNULL(s);
  //对移动的位置进行定义
  defineMove(xmove);
  //对迷宫进行输入
  printf("请输入迷宫:\n");
  for(i = 0;i<m+2;i++)
    for(j = 0;j<n+2;j++)
        scanf("%d",&maze[i][j]);
  start.x = 1;
  start.y = 1;
  start.d = -1;
  p = (point*)malloc(sizeof(point));
  //将起点压入栈
  s = push(s,start);
  while(!isEmpty(s)){
    p = pop(s);
    x = p->x;
    y = p->y;
    d = p->d+1;
    while(d<8){
        i = xmove[d].x+x;
        j = xmove[d].y+y;
        if(maze[i][j]==0){
            p->d = d;
            s = push(s,*p);
            x = i;
            y = j;
            maze[x][y] = -1;
            point nw;
            nw.x = x;
            nw.y = y;
            nw.d = -1;
            s = push(s,nw);
            if(x==m&&y==n){
                printf("找到出口!\n");
                while(!isEmpty(s)){
                    p = pop(s);
                    printf("%d %d %d\n",p->x,p->y,p->d);
                }
                return 1;
            }else{
             break;
            }
        }else{
         d++;
        }
    }
  }
 return 0;
}


   
                               





 


  • 28
    点赞
  • 122
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
由于没有给出具体的迷宫问题,下面分别介绍三种解法的基本思路和实现方式。 1. 采用求解迷宫问题 是一种后进先出的数据结构,我们可以利用来记录迷宫中走过的路径。具体实现方式如下: 1)定义一个,用来记录当前位置的坐标(x, y)以及走到该位置的方向(0表示未走过,1表示向上,2表示向右,3表示向下,4表示向左)。 2)从起点开始,将其入,并标记已走过。 3)每次从顶取出一个位置,判断其是否为终点,若是,则输出路径并结束程序;否则,依次判断该位置四周的位置是否可走,若可走,则将其入,并标记已走过。 4)如果四周都走不通,则出,回溯到上一个位置,继续搜索。 2. 采用递归算法求解迷宫问题 递归是一种自我调用的算法,我们可以将迷宫问题转化为一个递归问题,具体实现方式如下: 1)定义一个函数,用来表示从当前位置出发是否能到达终点。 2)在函数中,先判断当前位置是否为终点,若是,则返回true。 3)否则,依次判断该位置四周的位置是否可走,若可走,则递归调用函数判断该位置是否能到达终点。 4)如果四周都走不通,则返回false。 5)在主函数中,从起点开始调用递归函数,若返回true,则输出路径,否则输出无解。 3. 采用队列求解迷宫问题 队列是一种先进先出的数据结构,我们可以利用队列来记录迷宫中走过的路径。具体实现方式如下: 1)定义一个队列,用来记录当前位置的坐标(x, y)以及走到该位置的方向(0表示未走过,1表示向上,2表示向右,3表示向下,4表示向左)。 2)从起点开始,将其入队,并标记已走过。 3)每次从队头取出一个位置,判断其是否为终点,若是,则输出路径并结束程序;否则,依次判断该位置四周的位置是否可走,若可走,则将其入队,并标记已走过。 4)如果四周都走不通,则出队,继续搜索队列中下一个位置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值