迷宫寻路(深度搜索,回溯)找到所有路径和最短路径

问题描述:以一个m×n的长房阵表示迷宫,0和1分别表示通路和障碍,求出一条从入口到出口的通路,或者输出“此迷宫没有通路”

思路:利用栈记录每个单元格的坐标和每次选取的路径方向,对单元格上下左右四个方向依次试探来寻取不同的路径。同时每次找到一条路径就记录路径长度,然后下次找到新的路径比较前者的路径长度从而刷新最短路径(具体见代码)

上代码:

/***
    11.2.17 迷宫问题
                    --2022.5.10.14:41
***/
#include<stdio.h>
#define MAXSIZE 100
#define endX 9   //迷宫行数
#define endY 8   //迷宫列数
typedef struct mg
{
    int x;        //记录每个可走结点的横坐标
    int y;        //记录每个可走结点的纵坐标
    int dir;      //记录每个节点下一次选择路径的方向(0:上,1:右,2:下,3:左)
}Stackmg[MAXSIZE],Pathmg[MAXSIZE];
int top=0;   //栈顶指针(始终指向栈顶元素的下一个空位置),同时看出top也是栈内元素个数
int minlength=MAXSIZE; //minlength记录最短路径
Stackmg maze;          //作为栈,记录访问点的坐标,选路方向
Pathmg shortestPath;   //存储最短路径
int map[endX+2][endY+2]     //迷宫地图信息(9×8的地图)
={
    //这里在原来地图基础上四周加了墙
    {1,1,1,1,1,1,1,1,1,1},
    {1,0,0,1,0,0,0,1,0,1},
    {1,0,0,1,0,0,0,1,0,1},
    {1,0,0,0,0,1,1,0,1,1},
    {1,0,1,1,1,0,0,1,0,1},
    {1,0,0,0,1,0,0,0,0,1},
    {1,0,1,0,0,0,1,0,1,1},
    {1,0,1,1,1,1,0,0,1,1},
    {1,1,1,0,0,0,1,0,1,1},
    {1,1,1,0,0,0,0,0,0,1},
    {1,1,1,1,1,1,1,1,1,1}
};

int findway()   //寻路
{
    int x,y,dir;
    int count=0,i=0;  //记录路径数目
    int find;
    maze[top].x=1,maze[top].y=1,maze[top].dir=-1,top++;
    map[1][1]=-1;   //初始化时,将起点值改为-1,防止下面寻路又找回来,下面的路也会用到
    while(top>0)   //栈不空
    {
        x=maze[top-1].x,y=maze[top-1].y,dir=maze[top-1].dir;
        if(x==endX&&y==endY)  //若找到路
        {
            printf("\n找到第%d条路:\n",++count);
            for(i=0;i<top;i++)
            {
                printf("(%d,%d),",maze[i].x,maze[i].y);
                if((i+1)%5==0)   //输出5个后换行
                    printf("\n");
            }
            if(top<minlength)  //若找到的路,其长度小于已记录的路长,则最短路刷新
            {
                for(i=0;i<top;i++)
                {
                    shortestPath[i]=maze[i];
                }
                minlength=top;
            }
            map[maze[top-1].x][maze[top-1].y]=0;   //终点已被走过,现在重新将终点设置为可走
            top--;
            x=maze[top-1].x,y=maze[top-1].y,dir=maze[top-1].dir;
        }
        find=0;
        while(dir<4&&find==0)
        {
            dir++;
            switch(dir)
            {
                case 0:{x=maze[top-1].x-1,y=maze[top-1].y;}break;
                case 1:{x=maze[top-1].x,y=maze[top-1].y+1;}break;
                case 2:{x=maze[top-1].x+1,y=maze[top-1].y;}break;
                case 3:{x=maze[top-1].x,y=maze[top-1].y-1;}break;
            }
            if(map[x][y]==0)  //若选取的下一个方向未被访问,说明此方向可选,find置1
                find=1;
        }
        if(find==1)
        {
            maze[top-1].dir=dir;  //记录原来栈顶的寻路方向
            maze[top].x=x,maze[top].y=y,maze[top].dir=-1; //原来栈顶选择的一个方向上元素进栈,方向记录初始化为-1
            top++;       //栈顶指针加1
            map[x][y]=-1;  //防止找路又找回来
        }
        else//若四个方向上都不可访问,弹出栈顶元素,对原来栈顶下一个元素进行同样的操作
        {
            map[maze[top-1].x][maze[top-1].y]=0;//原来栈顶元素已被走过,现在重新将其设置为可走来找其他路
            top--;
        }
    }
    return count;
}
void print_shortestPath()
{
    int i=0;
    printf("\n最短长度:%d,最短路径如下:\n",minlength);
    for(i=0;i<minlength;i++)
    {
        printf("(%d,%d),",shortestPath[i].x,shortestPath[i].y);
        if((i+1)%5==0)
            printf("\n");
    }
}
int main()
{
    int havePath=findway();
    if(havePath==0)
        printf("此迷宫不连通\n");
    else
    {
        print_shortestPath();
    }
    return 0;
}

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值