跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C++算法

图论算法基础:深入理解 DFS 与 BFS 遍历

图论算法核心在于深度优先搜索(DFS)与广度优先搜索(BFS)。DFS 利用栈结构实现回溯,适合全排列、N 皇后等组合问题;BFS 基于队列逐层扩展,常用于求最短路径。两种算法原理,涵盖递归实现、剪枝优化及邻接表存储方式,并通过 C++ 代码演示全排列、迷宫寻路及树图遍历的具体应用,帮助读者建立扎实的图论基础。

FlinkHero发布于 2026/3/22更新于 2026/5/43 浏览
图论算法基础:深入理解 DFS 与 BFS 遍历

图论算法基础

深度优先搜索 (DFS)

DFS 的核心思想是'一条路走到黑',直到无法继续才回溯。从数据结构看,它依赖栈(递归隐式调用栈),空间复杂度为 O(h)。由于它是深度优先的,通常不直接用于求最短路。

全排列问题

通过递归枚举每个位置可选的数字,配合 st 数组标记已选状态。注意回溯时需恢复现场,path 数组无需手动清空,因为下次循环会覆盖。

#include <iostream>
using namespace std;

const int N = 10;
int n;
int path[N];
bool st[N];

void dfs(int u) {
    if (u == n) {
        for (int i = 0; i < n; i++) printf("%d ", path[i]);
        puts("");
        return;
    }
    for (int i = 1; i <= n; i++) {
        if (!st[i]) {
            path[u] = i;
            st[i] = true;
            dfs(u + 1);
            // 恢复现场
            st[i] = false;
        }
    }
}

int main() {
    cin >> n;
    dfs(0);
    return 0;
}
N 皇后问题

引入剪枝优化,利用对角线特性减少无效搜索。正对角线和反对角线的索引计算需注意偏移量,防止越界。

文章配图

#include <iostream>
using namespace std;

const int N = 10;
int n;
char g[N][N];
// 对角线数组需开大一点,防止越界
bool col[N], dg[2 * N], udg[2 * N];

void dfs(int u) {
    if (u == n) {
        for (int i = 0; i < n; i++) puts(g[i]);
        puts("");
        return;
    }
    for (int i = 0; i < n; i++) {
        // 检查列、主对角线、副对角线
        if (!col[i] && !dg[u + i] && !udg[n - u + i]) {
            g[u][i] = 'Q';
            col[i] = dg[u + i] = udg[n + i - u] = true;
            dfs(u + 1);
            // 恢复现场
            g[u][i] = '.';
            col[i] = dg[u + i] = udg[n + i - u] = false;
        }
    }
}

int main() {
    cin >> n;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) g[i][j] = '.';
    }
    dfs(0);
    return 0;
}

广度优先搜索 (BFS)

BFS 像水波一样一层层扩散,依赖队列。它能保证第一次到达终点的路径是最短的。

迷宫寻路

标准框架:入队起点,循环取出队首,扩展邻居。记录前驱节点可还原路径。

文章配图

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

const int N = 1e2 + 10;
typedef pair<int, int> PII;

int n, m;
int g[N][N];
int d[N][N]; // 距离
PII q[N * N], Prev[N][N]; // 队列和前驱

int bfs() {
    int hh = 0, tt = 0;
    q[0] = {0, 0};
    memset(d, -1, sizeof d);
    d[0][0] = 0;
    
    int dx[4] = {-1, 0, 1, 0};
    int dy[4] = {0, 1, 0, -1};
    
    while (hh <= tt) {
        auto t = q[hh++];
        for (int i = 0; i < 4; i++) {
            int x = t.first + dx[i], y = t.second + dy[i];
            if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1) {
                d[x][y] = d[t.first][t.second] + 1;
                Prev[x][y] = t;
                q[++tt] = {x, y};
            }
        }
    }
    return d[n - 1][m - 1];
}

int main() {
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> g[i][j];
        }
    }
    cout << bfs();
    return 0;
}

树与图的存储及遍历

图分为有向和无向,稀疏图常用邻接表(链式前向星)存储,比邻接矩阵更节省空间。

无向图中边是双向的,有向图则是单向的。我们通常统一按有向图处理,只需在存无向边时存两次即可。

代码示例

以下演示使用邻接表进行树的宽度优先遍历,计算节点到根的距离。

文章配图

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

const int N = 1e5 + 10;
int n, m, q[N], d[N]; // d 记录每个节点到节点 1 的距离
int e[N], h[N], idx, ne[N];

void add(int a, int b) {
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx++;
}

int bfs() {
    int hh = 0, tt = 0;
    q[0] = 1;
    memset(d, -1, sizeof d);
    d[1] = 0;
    
    while (hh <= tt) {
        int t = q[hh++];
        for (int i = h[t]; i != -1; i = ne[i]) {
            int j = e[i];
            if (d[j] == -1) {
                d[j] = d[t] + 1;
                q[++tt] = j;
            }
        }
    }
    return d[n];
}

int main() {
    cin >> n >> m;
    memset(h, -1, sizeof h);
    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        add(a, b);
    }
    cout << bfs();
    return 0;
}

目录

  1. 图论算法基础
  2. 深度优先搜索 (DFS)
  3. 全排列问题
  4. N 皇后问题
  5. 广度优先搜索 (BFS)
  6. 迷宫寻路
  7. 树与图的存储及遍历
  8. 代码示例
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • PaddleOCR 文本矫正与排序算法解析
  • Coze 智能体开发指南:从配置到工作流实战
  • OpenClaw 架构解析:单进程应用与插件式扩展设计
  • Windows 本地部署 MinIO 对象存储及 Web 控制台配置指南
  • Windows 通过 Git Bash 安装 SDKMAN 管理 JDK 多版本
  • C++ 核心概念解析:引用、内联函数与 nullptr
  • ArduPilot RemoteID Transmitter:无人机远程识别解决方案
  • AI 数字人:繁荣背后的伦理困境与法律迷局
  • OpenAkita:自我进化的开源 AI 助手框架
  • 6 克 ESP32 微型无人机:手机 Wi-Fi 遥控系统设计与实现
  • 微服务韧性演进史:从 Hystrix 到 Service Mesh
  • Python 基于 Flask 的博物馆文物报修管理系统设计与实现
  • OpenClaw 框架 30+ 真实场景深度解析
  • 深度可分离卷积原理详解及 OPPORTUNITY 数据集实战
  • Python 和 R 语言,数据科学学哪个?
  • Linux 下 C/C++ 调试工具 GDB 实战指南
  • 解决新机型 Copilot 键替代右 Ctrl 键问题
  • 从 0 到 1 打造 RISC-V 智能家居中控:硬件 + 固件 + 通信全链路实战
  • DeepSeek 深度使用指南与高效提示词技巧
  • Llama-3.2V-11B-COT 教育场景解题推理辅助应用实战

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online