迷宫问题 (代码+思路详解)

题目来源:搜索入门练习

迷宫问题

1、题目内容

【题目描述】
定义一个二维数组:

int maze[5][5] = {
0,1,0,0,0,
0,1,0,1,0,
0,0,0,0,0,
0,1,1,1,0,
0,0,0,1,0,
};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

【输入】
一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。

【输出】
左上角到右下角的最短路径,格式如样例所示。

【输入样例】
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
【输出样例】
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)

2、题目分析

在这个题中,主要考察了C语言数据结构中的图搜索知识。关于解搜索问题的方法,我们常见的有两种,一种是bfs,即广度优先搜索,另一种则是dfs,即深度优先搜索。我们在理解学习这两种搜索方法的时候,其实可以类推树结构的遍历方法,其实,bfs就类似于树的层序遍历(以当前点为依据,找到所有与之相连的点);而dfs则类似于树的后序遍历(以当前点为出发点不断向前,直到无法再次前进再返回)。
由于在此题中需要输出遍历点的顺序,所以我们采用bfs方法来解题,通过使用队列结构来存储路径。

3、代码

#include<stdio.h>
struct node{
    int x; //x坐标 
    int y; //y坐标 
    int pre; //来到此点的出发点 
};
int book[6][6];  //用来记录点是否访问过
int map[6][6];   //记录图
struct node queue[20]; //存储路径的队列
void print(struct node a) //实现路径输出的函数
{
    if(a.pre==-1)  
    {
        printf("(%d, %d)\n",a.x,a.y);
        return ;
    }
    else
    {
        print(queue[a.pre]);
        printf("(%d, %d)\n",a.x,a.y);
    }
}
int main()
{
    int i,j,k,m,n,x,y;
    int head,tail;
    for(i=0;i<5;i++)
    {
        for(j=0;j<5;j++)
        {
            scanf("%d",&map[i][j]);
        }
    }
    head=0;
    tail=0;
    queue[tail].x=0;
    queue[tail].y=0;
    queue[tail].pre=-1;
    book[0][0]=1;
    tail++;
    while(head<tail) //当队列为空时跳出,说明搜索没有找到可行路径
    {
        int next[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; //定义出四个方向
        int flag=0;
        for(i=0;i<4;i++)  //从当前点往四周探索
        {
            int nextx=queue[head].x+next[i][0];
            int nexty=queue[head].y+next[i][1]; //实现移动
            if(nextx<0||nextx>5||nexty<0||nexty>5) //超出了边界则跳出
            {
                continue;
            }
            if(book[nextx][nexty]==0&&map[nextx][nexty]==0) //当点未被访问过且是可行点才入队
            {
                book[nextx][nexty]=1;
                queue[tail].x=nextx;
                queue[tail].y=nexty;
                queue[tail].pre=head;
                tail++;
            }
            if(nextx==4&&nexty==4) //到达了目的地,毫无疑问地跳出结束循环
            {
                flag=1;
                break;
            }
        }
        if(flag) //到达目的地后调用函数输出路径
        {
            print(queue[tail-1]);
            break;
        }
        head++; //出队
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42987451/article/details/81748541