迷宫问题-四个方向dfs

这篇文章介绍了一个使用C语言实现的深度优先搜索(DFS)算法来解决迷宫问题。程序通过读取迷宫的长宽和地图,以及起始和结束坐标,利用栈来存储路径,遍历迷宫寻找从起点到终点的路径。当找到路径时,会将其打印出来。如果找不到路径,则输出-1。
摘要由CSDN通过智能技术生成

第一行输入:迷宫的长和宽

第二行输入:整个迷宫,1代表可以通行,0代表障碍,不要有其他数字

第三行输入:起始坐标和结束坐标 直接依次输入四个数字即可

代码如下

借鉴了其他博主的一部分代码,侵删。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 20
/*  *建立一个二维数组存迷宫
    *要是四个方向能有位置则压入栈,要是下一步没有则弹出栈回溯
    *直到找到终点为止
*/
int direction[4][2]={{0,-1},{-1,0},{0,1},{1,0}};  //定义一个数组存四个方向操作数
//x竖 0 -1 0 1 
//y横 -1 0 1 0
//i=1向左走; i=2向上走; i=3向右走; i=4向下走;
int maze[MAXN][MAXN];
int flag=0;
 
//栈中存位置以及遍历时所走的方向,打印时可以显示出来
typedef struct Node{
    int x;
    int y;
    //  int dir;           //-1为左上右下对应 '\' 0为上下对应'|'  1为左右对应'——' 2为左下右上对应'/'
    struct Node *next;
}Node;
 
typedef Node* Stack;     //定义数据结构栈 Stack
 
//-----------创建一个空栈--------------
Stack creakEmptyStack(){
    Stack p;
    p=(Stack)malloc(sizeof(Node));    //申请一个空间
    if(p){
        p->next=NULL;
        return p;
    }
    else{
        printf("No space!\n");    //申请空间失败则提示并返回空
        return NULL;
    }
}
 
//------------将元素压入栈----------------
void push(int x,int y,Stack s){
    Stack p;
    p=(Stack)malloc(sizeof(Node));
    if(p){                   //如果申请空间成功则用头插法将元素压入
        p->x=x;
        p->y=y;
        if(!s->next) p->next=NULL;  //如果此时栈里还没有任何元素,则p此时为第一个结点
        else p->next=s->next;  //否则将p插入头结点之后
        s->next=p;
    }
    else{
        printf("No space!\n");
    }
}
//-------------检测栈是否为空--------------
int isEmpty(Stack s){           //为空则返回1,不为空返回0
    if(s->next==NULL) return 0;
    else return 1;
}
//--------------将元素弹出栈----------------
void pop(Stack s){
    Stack p;
    p=s->next;
    if(p->next){
        s->next=p->next; //s p p1 将p弹出,将指针指向p1
        free(p);//释放p节点的空间
    }
    else return;
}
//------------取栈顶元素------------------
Node top(Stack s){
    Node t;
    t=*(s->next);//取头指针下一位置的节点坐标
    return t;
}
 
void mazePath(int x,int y,int endx,int endy,int n,int m,Stack s);
void printPath(Stack s,int n,int m);
 
int main()
{
    //freopen("7.in", "r", stdin);
    //freopen("1.txt", "w", stdout);
    int n,m,i,j,xa,xb,ya,yb,ox;
    //--------------建立迷宫--------------
    scanf("%d%d",&n,&m);
    if(n<=14&&m<=14&&n>=2&&m>=2){
        for(i=0;i<n;i++){
            for(j=0;j<m;j++){
                scanf("%d",&maze[i][j]);
            }
        }
         printf("\n");
        //----------输出构建迷宫-------------
 
        scanf("%d%d%d%d",&xa,&ya,&xb,&yb);
        //标记起点
        maze[xa-1][ya-1]=2;                        
        //创建一个空栈
        Stack s=creakEmptyStack();
        push(xa-1, ya-1, s);//压入第一个点的位置
        //创建一个空队列
        //QueueLink q=creakEmptyQueue();
        mazePath(xa-1,ya-1,xb-1,yb-1,n,m,s);
        //起点坐标,终点坐标,迷宫的长和宽,栈的头指针
        if(!flag) {
            printf("-1");
        }
    }
    else printf("迷宫非法输入\n");
}
 
//-----------遍历迷宫寻找路径(dfs)------------
void mazePath(int x,int y,int endx,int endy,int n,int m,Stack s){
    int newx,newy,i;
    Node t;
    for(i=0;i<4;i++){
        //遍历四个方向
        newx=x+direction[i][0];
        newy=y+direction[i][1];
        if(newx>=0&&newx<n&&newy>=0&&newy<m&&maze[newx][newy]==1){    //走到出口
            //如果下一步不是地图外(不是小于0的数或者超过地图边界的数),同时走的位置可以通过。
            push(newx,newy,s);
            maze[newx][newy]=2;//标记该位置走过
            if(newx==endx&&newy==endy){
                flag++;
                printPath(s,n,m);
                maze[newx][newy]=1;
                pop(s);
            }
            else{
                mazePath(newx,newy,endx,endy,n,m,s);
            }
        }
        //循环如果有一次四个方向都不满足,跳出循环将自己锁在的位置设置为0,将所在位置的元素从栈中弹出,然后回到上一步换个方向继续走。
//        else if(!isEmpty(s)) pop(s);
    }
    maze[x][y]=1;   //遍历完四个方向之后回溯前将自己赋为空
    pop(s);
}
 
//-------------打印迷宫路径-----------------
void printPath(Stack s,int n,int m){
    int cont =0;    //计算路径长度
    s=s->next;
    Stack c=creakEmptyStack();
    int i=0,j=0;
        //push(s->x,s->y,c);
    while(s->next){                          //将栈中的元素存入另一个栈,以便于顺序输出
        push(s->x,s->y,c);
        s=s->next;//指针指向下一个
    }
    push(s->x,s->y,c); //修bug,我也不知道为什么这样
    c=c->next;
    while(c->next){                          //将栈中的元素输出为直观路径
        printf("(%d,%d)->",c->x+1,c->y+1);
        c=c->next;//指针指向下一个
        cont++;
    }
    printf("(%d,%d)",c->x+1,c->y+1);//输出最后一个元素
    printf("\n");
    cont++;     //最后一个元素也记数
  //最后一个元素也记数
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值