当前位置: 首页 > news >正文

深入解析BFS算法:C++实现无权图最短路径的高效解决方案

        在无权图中,广度优先搜索(BFS)是解决最短路径问题的高效算法。接下来博主从专业角度深入探讨其实现细节,并给出C++代码示例:


目录

一、核心原理

二、算法步骤

三、C++实现关键点

1. 数据结构

2. 边界检查

3. 路径回溯(可选)

四、代码实现

五、路径回溯实现

六、复杂度分析

七、适用场景与限制


一、核心原理

BFS按层遍历节点,确保首次到达目标节点的路径是最短的。其核心特性为:

  • 队列管理:先进先出(FIFO)保证按层扩展。

  • 访问标记:避免重复访问,防止环路。

  • 距离记录:每个节点的距离为父节点距离加1。


二、算法步骤

  1. 初始化:起点入队,标记距离为0。

  2. 遍历队列:逐层处理节点,遍历所有合法邻居。

  3. 终止条件:到达终点时返回距离;队列为空则表示不可达。


三、C++实现关键点

1. 数据结构

  • 队列:存储待处理节点,使用queue<pair<int, int>>

  • 距离矩阵:记录每个节点的最短距离,初始化为-1表示未访问。

  • 方向数组:定义移动方向(如4方向或8方向)。

int dx[] = {-1, 1, 0, 0};  // 上下左右
int dy[] = {0, 0, -1, 1};

2. 边界检查

确保新坐标在网格范围内,且节点可访问(非障碍、未访问)。

3. 路径回溯(可选)

通过父节点矩阵记录路径,回溯时从终点反向追踪至起点。


四、代码实现

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int bfsShortestPath(vector<vector<int>>& grid, pair<int, int> start, pair<int, int> end) {
    int n = grid.size();
    if (n == 0) return -1;
    int m = grid[0].size();
    
    queue<pair<int, int>> q;
    vector<vector<int>> dist(n, vector<int>(m, -1));
    int dx[] = {-1, 1, 0, 0};
    int dy[] = {0, 0, -1, 1};
    
    // 初始化起点
    q.push(start);
    dist[start.first][start.second] = 0;
    
    while (!q.empty()) {
        auto curr = q.front();
        q.pop();
        
        // 到达终点
        if (curr.first == end.first && curr.second == end.second) {
            return dist[curr.first][curr.second];
        }
        
        // 遍历四个方向
        for (int i = 0; i < 4; ++i) {
            int x = curr.first + dx[i];
            int y = curr.second + dy[i];
            
            // 检查新坐标是否合法
            if (x >= 0 && x < n && y >= 0 && y < m && grid[x][y] == 0 && dist[x][y] == -1) {
                dist[x][y] = dist[curr.first][curr.second] + 1;
                q.push({x, y});
            }
        }
    }
    
    return -1;  // 不可达
}

// 示例用法
int main() {
    vector<vector<int>> grid = {
        {0, 1, 0, 0},
        {0, 0, 0, 1},
        {1, 1, 0, 0},
        {0, 0, 0, 0}
    };
    pair<int, int> start = {0, 0};
    pair<int, int> end = {3, 3};
    
    int shortest = bfsShortestPath(grid, start, end);
    if (shortest != -1) {
        cout << "最短路径长度: " << shortest << endl;
    } else {
        cout << "无法到达终点!" << endl;
    }
    return 0;
}

五、路径回溯实现

扩展代码以记录路径:

vector<pair<int, int>> getPath(vector<vector<pair<int, int>>>& parent, pair<int, int> start, pair<int, int> end) {
    vector<pair<int, int>> path;
    pair<int, int> curr = end;
    while (curr != start) {
        path.push_back(curr);
        curr = parent[curr.first][curr.second];
    }
    path.push_back(start);
    reverse(path.begin(), path.end());
    return path;
}

// 在BFS函数中添加父节点记录
vector<vector<pair<int, int>>> parent(n, vector<pair<int, int>>(m, {-1, -1}));
// ...
if (条件满足) {
    parent[x][y] = curr;
}
// 找到终点后调用getPath

六、复杂度分析

  • 时间复杂度:O(N×M),每个节点处理一次。

  • 空间复杂度:O(N×M),队列和距离矩阵的开销。


七、适用场景与限制

  • 适用:无权图、网格迷宫、社交网络层级关系。

  • 限制:仅处理无权图,带权图需改用Dijkstra或A*算法。

        通过以上实现,BFS能够高效解决无权图中的最短路径问题。正确管理队列和状态标记是保证算法正确性的关键。

相关文章:

  • bboss v7.3.5来袭!新增异地灾备机制和Kerberos认证机制,助力企业数据安全
  • DeepSeek 助力 Vue 开发:打造丝滑的 键盘快捷键(Keyboard Shortcuts)
  • 鸿蒙5.0实战案例:基于自定义注解和代码生成实现路由框架
  • P1055 [NOIP 2008 普及组] ISBN 号码(java)【AC代码】
  • 【CXX】5 桥接模块参考
  • SQL Server导出和导入可选的数据库表和数据,以sql脚本形式
  • netcore libreoffice word转pdf中文乱码
  • Vue 3 和 Vite 从零开始搭建项目的详细步骤
  • JavaWeb-Tomcat服务器
  • 一周学会Flask3 Python Web开发-客户端状态信息Cookie以及加密
  • 鸿蒙-canvas-画时钟
  • vue从入门到精通(十一):条件渲染
  • VLM(视觉语言模型)与DeepSeek R1(奖励机制)如何结合
  • springboot的 nacos 配置获取不到导致启动失败及日志不输出问题
  • 回溯算法——77,216
  • 合理建模--最短路径
  • open webui 部署 以及解决,首屏加载缓慢,nginx反向代理访问404,WebSocket后端服务器链接失败等问题
  • 《机器学习实战》专栏 No12:项目实战—端到端的机器学习项目Kaggle糖尿病预测
  • 第十五届蓝桥杯:爬山
  • 物联网+人工智能的无限可能
  • aws 虚机wordpress教程/佛山百度提升优化
  • 政府部门网站建设内容/企业培训课程分类