BFS求解迷宫问题并输出路线(C语言)

1.问题的提出

    用二维矩阵表示一个迷宫,0表示可通行,1表示有障碍,请给出最短路径的路线。

    给出迷宫:

   [0,0,1,0;

    0,0,0,0

    0,1,1,0

    0,1,0,0]

    (0,0)为起始点,(3,3)为终点

2.问题求解的思路

    题目要求求得最短路径,显然要用BFS的方法求解。

3.BFS

    广度优先搜索(也称宽度优先搜索,缩写BFS,以下采用广度来描述)是连通图的一种遍历策略。因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较广的区域,因此得名。一般可以用它做什么呢?一个最直观经典的例子就是走迷宫,我们从起点开始,找出到终点的最短路程,很多最短路径算法就是基于广度优先的思想成立的。

    在广度优先搜索算法中,解答树上结点的扩展是按它们在树中的层次进行的。首先生成第一层结点,同时检查目标结点是否在所生成的结点中,如果不在,则将所有的第一层结点逐一扩展,得到第二层结点,并检查第二层结点是否包含目标结点,……,对层次为n+1的任一结点进行扩展之前,必须先考虑层次完层次为n的结点的每种可能的状态。因此,对于同一层结点来说,求解问题的价值是相同的,可以按任意顺序来扩展它们。通常采用的原则是先生成的结点先扩展。

4.如何存储最短路径

    这也是我在求解BFS问题的中遇到的最大的问题,在查阅资料后,我选择了记录每一个节点的前驱节点,然后再回溯的方法作为我们的解决方案。    

    我选择了用数组的方法记录每一个节点的前驱节点:

     int route[4][4][2];

     (route[i][j][0],route[i][j][1])表示(i,j)的前驱节点。

5.具体代码

#include<stdio.h>
#include<stdlib.h>
#include<stack>
#include<queue>
using namespace std;
 
int record[4][4] = {0};
int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
int maze[4][4] = {{0,0,1,0},
                  {0,0,0,0},
                  {0,1,1,0},
                  {0,1,0,0}};
stack <int> s;



int visit(int a,int b)
{
    if(record[a][b] == 0&&maze[a][b] == 0&&a >= 0&&a <= 3&&b >= 0&&b <= 3)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

/*void traverse()
{
    int len = s.size()/2;
    
    int b[15][2];
    for(int i = len;i > 0;i--)
    {
        b[i][1] = s.top();
        s.pop();
        b[i][0] = s.top();
        s.pop();
    }
    
    for(int i = 1;i < len;i++)
    {
        printf("(%d,%d)->",b[i][0],b[i][1]);
    }
    printf("(%d,%d)",b[len][0],b[len][1]);
    printf("已到达终点!");
}
                  
void DFS(int maze[4][4],int start[2],int end[2])
{
    int p[2];
    p[0] = start[0];
    p[1] = start[1];

    record[start[0]][start[1]] = 1;
    
    if(start[0] == end[0]&&start[1] == end[1])
    {
        
        traverse();
        exit(0);
    }
    
    for(int i = 0;i < 4;i++)
    {
        int x,y;
        
        x = start[0] + dir[i][0];
        y = start[1] + dir[i][1];
        
        if(visit(x,y))
        {
            s.push(x);
            s.push(y);
            p[0] = x;
            p[1] = y;
            DFS(maze,p,end);
        }
    }
    s.pop();
    s.pop();
}*/
void printRoute(int route[4][4][2],int start[2],int end[2])
{
    int i = end[0];
    int j = end[1];
    
    while(1)
    {
        printf("(%d,%d)<-",i,j);
        int a = route[i][j][0];
        int b = route[i][j][1];
        i = a;
        j = b;
        if(i == start[0] && j == start[1])
        {
            break;
        }
    }
    printf("(%d,%d)",i,j);
}

void BFS(int maze[4][4],int start[2],int end[2])
{
    queue<int> que;
    
    que.push(start[0]);
    que.push(start[1]);
    
    int route[4][4][2] = {0};
    
    while(que.empty() == false)
    {
        int i = que.front();
        que.pop();
        int j = que.front();
        que.pop();
            
        if(i == end[0]&&j == end[1])
        {
            printRoute(route,start,end);
            printf("已找到终点!"); 
            break;
        }
        
        if(visit(i+dir[0][0],j+dir[0][1]))
        {
            record[i+dir[0][0]][j+dir[0][1]] = 1;
            que.push(i+dir[0][0]);
            que.push(j+dir[0][1]);
            route[i+dir[0][0]][j+dir[0][1]][0] = i;
            route[i+dir[0][0]][j+dir[0][1]][1] = j;
        }
        
        if(visit(i+dir[1][0],j+dir[1][1]))
        {
            record[i+dir[1][0]][j+dir[1][1]] = 1;
            que.push(i+dir[1][0]);
            que.push(j+dir[1][1]);
            route[i+dir[1][0]][j+dir[1][1]][0] = i;
            route[i+dir[1][0]][j+dir[1][1]][1] = j;
        }            
    }
}

int main()
{
    int start[2] = {0,0};
    int end[2] = {3,3};
    
    /*s.push(start[0]);
    s.push(start[1]);
    DFS(maze,start,end);
    printf("无法到达终点"); */
    
    BFS(maze,start,end);
    return 0;
} 

6.运行结果

 

posted @ 2022-04-21 11:13  嗯嗯魑嗯嗯  阅读(606)  评论(0编辑  收藏  举报