讲师中心 微信公众号
AI工具推荐 视频效率加速

C++如何实现深度优先搜索DFS遍历图_C++递归与非递归版本实现【算法】

酷婷君_8990

酷婷君_8990

发布时间:2026-02-15 12:36:13

|

183人浏览过

|

来源于php中文网

原创

递归版DFS必须在递归调用前标记visited[u]=true,否则在无向图或含环有向图中会无限循环或重复访问;visited[i]表示节点i是否已进入当前DFS树。

c++如何实现深度优先搜索dfs遍历图_c++递归与非递归版本实现【算法】

递归版 DFS 为什么必须用 visited 数组标记访问状态

不标记会导致无限循环或重复访问——尤其在无向图或含环有向图中。visited[i] 表示节点 i 是否已被递归进入过(不是“刚被访问”,而是“当前 DFS 树中已存在”)。常见错误是只在打印/处理时设标记,而应在递归调用前就设:

void dfs(int u) {
    visited[u] = true;  // ✅ 必须在此处标记
    cout << u << " ";
    for (int v : graph[u]) {
        if (!visited[v]) {
            dfs(v);  // ❌ 若这里才标记,v 可能被多个邻居重复压入栈
        }
    }
}
若图用邻接表 vector<vector>></vector> 存储,节点编号从 0 开始,visited 大小需与节点数一致。

非递归 DFS 用 stack 实现时,入栈和出栈顺序决定遍历路径

标准非递归 DFS 应模拟递归的“深度优先”行为:每次取栈顶,立即标记为已访问,并将所有未访问邻接点压栈。关键点:

  • 压栈顺序影响结果:若邻接表是 {1,2,3},先压 3 再压 2 最后压 1,则出栈顺序为 1→2→3(即按原顺序遍历)
  • 不能在出栈时才标记——否则同一节点可能被多次压入;必须在压栈前检查 !visited[v],且压栈即标记
  • 不推荐用 stack<pair bool>></pair> 模拟“是否回溯”,那属于 DFS 迭代器写法,不是基础遍历需求
示例核心逻辑:
stack<int> st;
st.push(start);
visited[start] = true;
while (!st.empty()) {
    int u = st.top(); st.pop();
    cout << u << " ";
    for (int v : graph[u]) {
        if (!visited[v]) {
            visited[v] = true;  // ✅ 压栈前标记
            st.push(v);
        }
    }
}

邻接矩阵 vs 邻接表对 DFS 时间复杂度的影响

使用邻接矩阵(vector<vector>></vector>)时,每次遍历节点 u 都要扫描整行(O(V)),总时间是 O(V²);邻接表只遍历实际边,总时间是 O(V + E)。实际项目中除非图极稠密或节点数

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • vector<vector>></vector> 是主流邻接表,但若频繁删边,可考虑 vector<set>></set>;不过 DFS 不涉及删边,无需过度设计
  • 若图是稀疏的(如社交网络子图),邻接表内存更省,缓存友好性也更好
  • DFS 本身不依赖图存储方式,但写错循环范围(比如把 graph[u].size() 写成 n)会导致越界或漏边
  • 递归太深导致栈溢出?std::stack 非递归版也不是万能解药

    当图节点数超 10⁵ 且深度极大(如链状图),递归 DFS 很容易触发栈溢出;此时非递归版确实能避免函数调用栈问题。但要注意:

    • std::stack 默认用 deque 实现,内存分配较频繁;对超大图,可换用 stack<int vector>></int> 提升连续内存局部性
    • 非递归版仍需 O(V) 空间存 visited 和 stack,空间复杂度没变,只是把栈空间从系统栈挪到了堆上
    • 若需获取路径、回溯状态(如找连通分量中的割点),单纯非递归 DFS 不够,得补全“当前层数”或“父节点”信息,这时递归结构反而更直观
    真正卡住性能的往往不是递归深度,而是邻接表遍历中反复调用 vector::begin()/end() 或未 reserve 容量——这些细节比选递归/非递归更影响实测表现。

    热门AI工具

    更多
    码上飞
    码上飞 Hot

    一款基于自然语言的AI应用开发平台,可根据用户描述自动生成应用程序,帮助个人和团队快速完成应用原型与开发。

    WorkBuddy

    一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

    豆包大模型

    豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

    讯飞绘文

    讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

    火山引擎

    火山引擎是一款面向企业的云计算与AI服务平台。

    Atoms
    Atoms Hot

    Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

    SkildArt
    SkildArt Hot

    SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

    讯飞智文

    一款面向学习和办公场景的AI文档创作工具,可辅助生成PPT与Word文档,提高资料整理和内容制作效率。

    DeepSeek

    DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

    相关专题

    更多
    堆和栈的区别
    堆和栈的区别

    堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

    6687

    2023.07.18

    堆和栈区别
    堆和栈区别

    堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

    2768

    2023.08.10

    堆和栈的区别
    堆和栈的区别

    堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

    6687

    2023.07.18

    堆和栈区别
    堆和栈区别

    堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

    2768

    2023.08.10

    页面置换算法
    页面置换算法

    页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

    6796

    2023.08.14

    Postman身份认证怎么配置
    Postman身份认证怎么配置

    本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

    0

    2026.11.06

    Postman请求头Headers怎么设置
    Postman请求头Headers怎么设置

    围绕Postman HTTP请求头配置展开,讲解Headers选项的具体使用方式,包括Key和Value参数填写、请求头信息添加、常见Header字段设置及请求头修改方法,帮助用户解决接口调试过程中遇到的请求头配置问题。

    0

    2026.11.06

    Postman接口请求发送教程
    Postman接口请求发送教程

    详细介绍Postman接口请求的创建与发送方法,涵盖GET和POST请求、URL配置、请求参数、Headers请求头、Body请求体设置以及响应结果查看,帮助用户掌握Postman接口请求的完整操作流程。

    0

    2026.11.06

    DBeaver怎么导入数据
    DBeaver怎么导入数据

    DBeaver数据导入专题,整理Excel、CSV、SQL、TXT等常见文件的数据导入方法,涵盖目标数据库选择、数据表创建、字段映射、数据类型设置及导入参数配置等操作,帮助用户将本地文件中的数据写入数据库,并了解批量导入、重复数据处理和导入失败等常见问题的解决方法。

    20

    2026.11.05

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    C++ Core Guidelines
    C++ Core Guidelines

    共0课时 | 0人学习

    C++ Reference
    C++ Reference

    共0课时 | 0人学习

    C++ 官方标准说明
    C++ 官方标准说明

    共0课时 | 0人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn