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

【算法通关指南:数据结构与算法篇】树形结构遍历指南:DFS 递归深搜与 BFS 队列广搜实战解析 - 详解

在这里插入图片描述

小龙报:个人主页
作者简介:C++研发,嵌入式,机器人方向学习者
❄️个人专栏:《算法通关指南》
永远相信美好的事情即将发生

在这里插入图片描述

文章目录

  • 前言
  • 一、深度优先遍历-DFS
    • 1.1 vector数组
    • 1.2 链式前向星
    • 1.3 复杂度分析
      • 1.3.1 时间复杂度
      • 1.3.2 空间复杂度
  • 二、宽度优先遍历-BFS
    • 2.1 vector数组
    • 2.2 链式前向星
    • 2.3 复杂度分析
      • 2.3.1 时间复杂度
      • 2.3.2 空间复杂度
  • 总结与每日励志


前言

树的遍历就是不重不漏的将树中所有的点都扫描⼀遍
在之前学过的线性结构中,遍历就很容易,直接从前往后扫描⼀遍即可。但是在树形结构中,如果不按照⼀定的规则遍历,就会漏掉或者重复遍历⼀些结点。因此,在树形结构中,要按照⼀定规则去遍历。常用的遍历方式有两种,一种是深度优先遍历(DFS),另⼀种是宽度优先遍历(BFS)

我们将以一道例题讲解这些遍历方法:
在这里插入图片描述
树的逻辑图
在这里插入图片描述

一、深度优先遍历-DFS

深度优先遍历,英文缩写为DFS,全称是DepthFirstSearch,中文名是深度优先搜索,是一种用于遍历或搜索树或图的算法。所谓深度优先,就是说每次都尝试向更深的节点走,也就是⼀条路走到黑
具体流程:
(1) 从根节点出发,依次遍历每⼀棵子树;
(2) 遍历子树的时候,重复第一步。
因此,深度优先遍历是⼀种递归形式的遍历可以用递归来实现
注:存储树结构的时候,会把相邻的所有结点都存下来,这样在扫描子树的时候会直接扫描到上一层,这不是我们想要的结果。
因此,需要一个数组来标记,哪些结点已经访问过,接下来的时候,就不去遍历那些点。

1.1 vector数组

#include <iostream>#include <vector>using namespace std;const int N = 1e5 + 10;vector<int> edges[N];   // edges[i] 保存着i号结点相连的所有点bool st[N];  // 标记当前结点是否已经被遍历过// 当前遍历到u这棵⼦树void dfs(int u){// 先访问该点cout << u << " ";st[u] = true;  //标记表明该节点已被访问//访问子树for (auto v : edges[u]){if (!st[v])dfs(v);  //如果没有遍历过再去递归}}int main(){int n;cin >> n;for (int i = 1; i < n; i++){int a, b;cin >> a >> b;edges[a].push_back(b);edges[b].push_back(a);}dfs(1);return 0;}

运行结果:
在这里插入图片描述

1.2 链式前向星

#include <iostream>using namespace std;const int N = 1e5 + 10;int h[N],ne[N * 2], e[N * 2],id;bool st[N];void add(int a, int b){id++;e[id] = b;ne[id] = h[a];h[a] = id;}void dfs(int u){cout << u << " ";st[u] = true;for (int i = h[u]; i; i = ne[i]){int v = e[i];if (!st[v])dfs(v);}}int main(){int n;cin >> n;for (int i = 1; i < n; i++){int a, b;cin >> a >> b;add(a, b);add(b, a);}dfs(1);return 0;}

运行结果:
在这里插入图片描述

1.3 复杂度分析

1.3.1 时间复杂度

简单估计一下,在 遍历的整个过程中,会把树中所有的边扫描量两遍。边的数量为n - 1 故时间复杂度为O(N)。

1.3.2 空间复杂度

最差情况下,结点个数为n的树,高度也是n ,也就是变成一个链表。此时递归的深度也是n,故一个时间复杂度O(N);

二、宽度优先遍历-BFS

宽度优先遍历,英文缩写为BFS,全称是BreadthFirstSearch,也叫广度优先遍历。也是⼀种用于遍历或搜索树或图的算法。
所谓宽度优先。就是每次都尝试访问同⼀层的节点。如果同⼀层都访问完 了,再访问下⼀层。
算法过程可以看做是在树和图中,在起点放上一个细菌,每秒向周围的那些干净的位置扩散⼀层,直到把所有位置都感染
具体实现方式借助队列
(1)初始化一个队列;
(2)根节点入队,同时标记该节点已经入队;
(3)当队列不为空时,拿出队头元素,访问,然后将队头元素的所有孩子入队,同时打上标记。
(4)重复过程,直到队列为空。

2.1 vector数组

#include <iostream>#include <vector>#include <queue>using namespace std;const int N = 1e5 + 10;vector<int> edges[N];queue < int> q;bool st[N];void bfs(int u){q.push(u);st[u] = true;while (q.size()){auto u = q.front();cout << u << " ";q.pop();for (auto v : edges[u]){if (!st[v]){q.push(v);st[v] = true;}}}}int main(){int n;cin >> n;for (int i = 1; i < n; i++){int a, b;cin >> a >> b;edges[a].push_back(b);edges[b].push_back(a);}bfs(1);return 0;}

运行结果:
在这里插入图片描述

2.2 链式前向星

#include <iostream>#include <queue>using namespace std;const int N = 1e5 + 10;queue<int> q;int id, h[N], e[N * 2], ne[N * 2];bool st[N];  //st[i]表示那些节点已经入队void add(int a, int b){id++;e[id] = b;ne[id] = h[a];h[a] = id;}void bfs(int u){q.push(u);st[u] = true;while (q.size()){auto v = q.front();cout << v << " ";q.pop();// 让孩子入队for (int i = h[v]; i; i = ne[i]){int x = e[i];if (!st[x]){q.push(x);st[x] = true;}}}}int main(){int n;cin >> n;for (int i = 1; i < n; i++){int a, b;cin >> a >> b;add(a, b);add(b, a);}bfs(1);return 0;}

运行结果:
在这里插入图片描述

2.3 复杂度分析

2.3.1 时间复杂度

有结点只会入队一次,然后出队一次,因此时间复杂度为空间复杂度:O(N)

2.3.2 空间复杂度

最坏情况下,所有的非根结点都在同⼀层,此时队列里面最多有n - 1个元素,故空间复杂度为O(N);

总结与每日励志

本文介绍了树遍历的两种主要方法:深度优先遍历(DFS)和宽度优先遍历(BFS)。DFS采用递归方式,每次尝试向更深节点遍历;BFS借助队列实现,按层次遍历节点。两种方法的时间复杂度均为O(N),空间复杂度在最坏情况下也是O(N)。文章通过示例代码展示了两种遍历的具体实现方式,包括vector数组和链式前向星两种存储结构。最后以"永远相信美好的事情即将发生"作为励志结语。

在这里插入图片描述

http://www.jsqmd.com/news/294669/

相关文章:

  • Vue.js 前端开发实战之 08-Vue 开发环境
  • 英语_阅读_15-year-old teenagers_待读
  • 包围盒加平均分段数 小三角找鼠标 扫描完没找到就是没点到,找到就是点到
  • Linux内核模块开发包含文件设置
  • 高中辅导机构提分效果哪家强?2026最新红榜揭秘与选择指南
  • 基于Simulink的风电变流器SVPWM调制策略仿真
  • 学Simulink——风电电机控制场景实例:基于Simulink的DFIG有功/无功功率解耦控制仿真
  • 别再手动改 YAML 了!用 Go 编写 K8s Operator,实现业务应用的“自动驾驶”
  • 支撑百万级定时任务!深扒 Kafka 与 Netty 的“时间轮”神技 (内附硬核图解)
  • git 本地仓库 删除最近一次commit
  • 【开题答辩全过程】以 民宿预订管理系统的设计与实现为例,包含答辩的问题和答案
  • 【开题答辩全过程】以 母婴店购物系统为例,包含答辩的问题和答案
  • 画面美到心坎里!这部电影的审美,把我们的记忆调成了精准的颜色
  • 【大数据毕设选题】基于Spark的餐饮数据分析与可视化系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习 数据挖掘
  • 大数据毕业设计推荐:基于Hadoop+Spark的上海二手房分析系统 毕业设计 选题推荐 毕设选题 数据分析 机器学习 数据挖掘
  • 汇报PPT一页讲清项目进度?先搞懂PPT单页怎么生成
  • HR面试(2)
  • python学习第七周
  • CF2072E Do You Love Your Hero and His Two-Hit Multi-Target Attacks?
  • 冲刺Day7
  • 微调显存总爆炸?问题往往不在你以为的地方
  • 完整教程:Redis 数据结构(下)ZSet, Hash
  • 《3D视觉核心融合技术:几何先验与深度学习应用手册》
  • 《模型决策因果推理与统计相关性深度区分指南》
  • 【必收藏】RAG知识库质量优化实战:评估指标对比与提升方法全解析
  • 【收藏级干货】RAG架构详解:突破大模型上下文限制,构建万页级知识库
  • 【必看收藏】AI Agent核心技术揭秘:四大核心模块详解,从使用到开发全攻略
  • 救命神器2026 MBA论文工具TOP9:开题报告文献综述全测评
  • 导师推荐8个一键生成论文工具,本科生毕业论文轻松搞定!
  • 2026.1.24