博客
关于我
1455: [蓝桥杯2019初赛]迷宫 【中 / bfs 】
阅读量:106 次
发布时间:2019-02-26

本文共 3178 字,大约阅读时间需要 10 分钟。

C++ BFS 算法实现路径寻找

今天,我在学习如何使用C++实现BFS算法来解决一个典型的路径寻找问题。这是一道非常经典的算法题目,适合用来练习图的遍历算法。让我来一步步分享我的思考过程和实现过程。

问题描述

问题的大意是说,给定一个二维网格,其中某些格子是可以通行的(标记为'0'),而其他格子则是障碍物(标记为'1')。我们的任务是从起点(左下角)出发,找到一条从起点到终点(右上角)的最短路径。路径只能沿着四个方向(上、下、左、右)移动,并且不能穿过障碍物或已经访问过的格子。

我的解决思路

在解决这道题目之前,我回顾了一下BFS算法的基本原理。BFS是一种最短路径算法,采用队列来实现,能够逐层扩展,保证找到最短路径。对于网格路径问题,BFS非常适用,因为网格的每个节点都有明确的上下左右四个邻居,结构比较简单。接下来,我决定按照以下步骤来实现这个算法:

  • 初始化数据结构:使用一个二维数组`dist`来记录每个格子到起点的最短距离。起点的距离设为0,其他格子的距离初始化为-1,表示初始时未被访问。
  • 队列的初始化:将起点的坐标(n-1, m-1)(假设网格的行数是n,列数是m)加入队列。
  • 队列处理:在每次循环中,从队列中取出当前的位置,检查其四个邻居。如果邻居的坐标是有效的、未被访问过且是通行的格子,那么将这个邻居的坐标加入队列,并更新其距离值。
  • 终止条件:当队列为空时,说明已经完成了所有可能的路径搜索。根据距离数组,可以得到从起点到终点的最短路径。
  • C++ 实现代码

    以下是我的C++实现代码:

    #include 
    #include
    #include
    using namespace std;
    int n, m;
    string g[n];
    int dist[n][n];
    int dx[] = {1, 0, 0, -1};
    int dy[] = {0, -1, 1, 0};
    char dir[] = {'D', 'L', 'R', 'U'};
    void bfs() {
    queue
    > q;
    dist[n-1][m-1] = 0;
    q.push({n-1, m-1});
    while (!q.empty()) {
    auto current = q.front();
    q.pop();
    for (int i = 0; i < 4; ++i) {
    int x = current.first + dx[i];
    int y = current.second + dy[i];
    if (x >= 0 && x < n && y >= 0 && y < m) {
    if (dist[x][y] == -1 && g[x][y] == '0') {
    dist[x][y] = dist[current.first][current.second] + 1;
    q.push({x, y});
    }
    }
    }
    }
    }
    int main() {
    cin >> n >> m;
    for (int i = 0; i < n; ++i) {
    cin >> g[i];
    }
    bfs();
    int x = 0, y = 0;
    string path;
    while (x != n-1 || y != m-1) {
    for (int i = 0; i < 4; ++i) {
    int nx = x + dx[i];
    int ny = y + dy[i];
    if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
    if (dist[nx][ny] != -1 && g[nx][ny] == '0') {
    x = nx;
    y = ny;
    path += dir[i];
    break;
    }
    }
    }
    }
    cout << path << endl;
    }

    代码解释

    在这个代码中,我首先包括了必要的头文件,包括了`

    `、`
    `、`
    `等。然后定义了一个二维数组`dist`,用于记录每个格子到起点的最短距离。方向数组`dir`用于表示四个方向的移动(D表示下,L表示左,R表示右,U表示上)。接着,定义了一个`bfs`函数,用于执行BFS算法。最后是`main`函数,用于读取输入、初始化参数、执行BFS算法并输出结果。

    在`bfs`函数中,我使用队列来实现BFS算法。从队列中取出当前的位置,检查其四个邻居。如果邻居是有效的且是通行的格子,则更新其距离并将邻居的位置加入队列。这样可以确保每个格子只被访问一次,保证了最短路径的正确性。

    在`main`函数中,我读取输入参数和网格数据,然后调用`bfs`函数进行路径寻找。最后,我根据`dist`数组构造路径字符串并输出结果。

    优化路径寻找算法的实践总结

    在实现BFS算法的过程中,我注意到以下几点:

  • 队列的使用:BFS算法的核心在于队列的使用。队列的先进先出的特性确保了按层次展开的搜索,能够保证找到最短路径。如果使用栈,则会得到一种深度优先搜索的效果,可能会遗漏一些更短的路径。
  • 邻居的访问顺序:在访问四个方向时,需要注意邻居的访问顺序。虽然访问顺序不影响最终结果,但不同的顺序可能会影响代码的正确性。例如,如果没有正确处理邻居的访问顺序,可能会导致某些路径被遗漏。
  • 边界条件的处理:在网格的边界处理上需要特别注意。例如,在访问邻居时,需要检查坐标是否在网格的有效范围内,避免越界。
  • 路径的重建:在BFS完成后,需要根据`dist`数组重新构造路径。可以采用回溯的方式,从终点逆向遍历到起点,记录路径方向,然后将方向数组反转得到最终的路径字符串。
  • 改进空间

    虽然BFS算法本身已经非常高效,但在实际应用中,还可以通过以下方式进一步优化:

  • 使用更优化的数据结构:对于大规模网格,使用更高效的数据结构来存储邻居信息可以提高性能。例如,可以使用`unordered_map`来存储每个位置的邻居信息,减少查找时间。
  • 多源BFS:如果需要同时从多个起点进行路径寻找,可以使用多源BFS来提高效率。这种方法可以并行处理多个起点,减少总的时间复杂度。
  • 动态网格处理:对于动态变化的网格,可以采用更灵活的数据结构来处理网格边界和路径更新,这样可以更好地适应网格的变化。
  • 总结

    通过这次练习,我对BFS算法有了更深入的理解。在实际编码过程中,我还需要注意代码的边界条件处理、数据结构的选择以及算法的优化。BFS算法在路径寻找、最短路径等问题中具有广泛的应用场景,熟练掌握它对解决实际问题非常有帮助。

    转载地址:http://rgfy.baihongyu.com/

    你可能感兴趣的文章
    MySQL Server 5.5安装记录
    查看>>
    mysql server has gone away
    查看>>
    mysql slave 停了_slave 停止。求解决方法
    查看>>
    MySQL SQL 优化指南:主键、ORDER BY、GROUP BY 和 UPDATE 优化详解
    查看>>
    MYSQL sql语句针对数据记录时间范围查询的效率对比
    查看>>
    mysql sum 没返回,如果没有找到任何值,我如何在MySQL中获得SUM函数以返回'0'?
    查看>>
    mysql Timestamp时间隔了8小时
    查看>>
    Mysql tinyint(1)与tinyint(4)的区别
    查看>>
    mysql union orderby 无效
    查看>>
    mysql v$session_Oracle 进程查看v$session
    查看>>
    mysql where中如何判断不为空
    查看>>
    MySQL Workbench 使用手册:从入门到精通
    查看>>
    mysql workbench6.3.5_MySQL Workbench
    查看>>
    MySQL Workbench安装教程以及菜单汉化
    查看>>
    MySQL Xtrabackup 安装、备份、恢复
    查看>>
    mysql [Err] 1436 - Thread stack overrun: 129464 bytes used of a 286720 byte stack, and 160000 bytes
    查看>>
    MySQL _ MySQL常用操作
    查看>>
    MySQL – 导出数据成csv
    查看>>
    MySQL —— 在CentOS9下安装MySQL
    查看>>
    MySQL —— 视图
    查看>>