迷宫问题(dfs)(顺序栈实现)

传送门
其实吧,走迷宫问题我个人觉得,还是bfs更好一些,但是实验题为了联系栈的使用,估计是把数据针对了一手,bfs跑不了,那就dfs吧
跟正常的dfs一样,但是感觉可以剪下枝,具体的看代码吧,dfs思路还是很简单的

#include <cstdio>
#include <cstdlib>
#include <iostream>

const int MAXN = 105,MAX = 1e3;
int maps[MAXN][MAXN],vis[MAXN][MAXN];//maps存储迷宫,vis检测是否在某条线路上,某点是否走过
int m,n;//行列
int beginx,beginy,endx,endy,flag,count;//flag表示是否走到终点,count在后面输出栈的时候计数
int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};//方向

typedef struct
{
    int x;
    int y;
}pos;//记录点

pos p[MAXN];//输出路径的时候将顺序逆转成正确的顺序

typedef struct
{
    int t;
    pos s[MAX];
}Stack;//顺序栈

Stack * creatStack()//建栈
{
    Stack * pstack;
    pstack = (Stack *)malloc(sizeof(Stack));
    if(NULL == pstack){
        printf("malloc error\n");
    }
    else{
        pstack->t = -1;
        return pstack;
    }
}

void push_Stack(pos q,Stack * pstack)//压栈
{
    if(pstack->t > MAX){
        printf("error\n");
        return ;
    }
    pstack->t++;
    pstack->s[pstack->t] = q;
}

int empty_Stack(Stack * pstack)//判断栈是否为空
{
    return pstack->t == -1;
}

void pop_Stack(Stack * pstack)//退栈
{
    if(!empty_Stack(pstack)){
        pstack->t--;
    }
}

pos top_Stack(Stack * pstack)//取栈顶元素
{
    return (pstack->s[pstack->t]);
}


void dfs(int x,int y,Stack * pstack)
{
    if(flag){//直接剪枝,如果找到,后面的路不再查找
        return ;
    }
    if(x == endx&&y == endy){//如果找到终点,直接输出栈
        flag = 1;//标记
        while(!empty_Stack(pstack)){
            pos x = top_Stack(pstack);
            pop_Stack(pstack);
            count++;
            p[count] = x;
        }
        for(int i = count; i >= 1; i--){
            printf("(%d %d)",p[i].x,p[i].y);
        }
        return ;
    }
    for(int i = 0; i < 4; i++){//如果不是终点,继续递归查找
        pos temp;
        temp.x = x + dir[i][0],temp.y = y + dir[i][1];
        if(temp.x >= 0&&temp.x < m&&temp.y >= 0&&temp.y < n&&!vis[temp.x][temp.y]&&!maps[temp.x][temp.y]){
            vis[temp.x][temp.y] = 1;
            push_Stack(temp,pstack);
            dfs(temp.x,temp.y,pstack);
            vis[temp.x][temp.y] = 0;
            pop_Stack(pstack);
        }
    }
    return ;
}

int main()
{
    scanf("%d%d",&m,&n);
    scanf("%d%d%d%d",&beginx,&beginy,&endx,&endy);
    for(int i = 0; i < m; i++){
        for(int j = 0; j < n; j++){
            scanf("%d",&maps[i][j]);
        }
    }
    /*std::cout<<std::endl;
    for(int i = 0; i < m; i++){
        for(int j = 0; j < n; j++){
            std::cout<<maps[i][j]<<' ';
        }
        std::cout<<std::endl;
    }*/
    Stack *  pstack = creatStack();
    pos b;
    b.x = beginx,b.y = beginy;
    vis[beginx][beginy] = 1;
    
    push_Stack(b,pstack);
    dfs(beginx,beginy,pstack);
    if(!flag){
        printf("No Path!");
    }
    /*for(int i = 1; i <= count; i++){
        std::cout<<p[i].x<<' '<<p[i].y<<std::endl;
    }*/
    free(pstack);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值