news 2026/9/10 5:41:36

数据结构进阶:树与递归之美

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
数据结构进阶:树与递归之美

树是一个对于我这种小白来说是接触的第一个较复杂的数据结构,不像之前的线性结构,树让人感觉是从一个线到面的进阶。

树的定义是由一个根节点和许多子节点组成,再由子节点成为新的根节点有点像递归的过程,因此树的许多操作都要有递归的参与。

树的基本术语:

节点的度:树中的节点的子节点的个数称为度。

树的度:树中节点最大的度。

树的高度:树的层数或者深度。

路径:两个子结点之间的距离。

树又分为有根树和无根树,无序树指的是树的根是变化的根节点可以是子节点,子节点可以是根节点。有根树的根节点是固定的。树又分为有序树和无序树,有序树中树的子节点不可变化,无序树反之。

树的储存是一个相较于线性结构完全不同的,由于一对多的特性,使得他的存储变得困难。当我们在处理无根树时,由于根的不确定性,所以应在每个节点相互存储两次。对此我们有两种存储方式;vector数组和链式前向星。

vector数组是将以根节点为数组名的数组中存储他的子节点。

#include <iostream> #include <vector> using namespace std; const int N = 1e5 + 10; int n;//节点的个数 vector<int>edges[N]; int main() { cin >> n; for(int i = 1; i < n; i++) { int u, v; cin >> u >> v; edges[u].push_back(v); edges[v].push_back(u);//由于没有固定的根节点,需要相互储存 } return 0; }

链式前向向星指的是用链表进行存储。

#include <iostream> using namespace std; const int N = 1e5 + 10; int h[N], e[2 * N], ne[2 * N]; int n, id; void add(int a, int b) { id++; e[id] = b; ne[id] = h[a]; h[a] = id; } int main() { cin >> n; for(int i; i < n; i++) { int a, b; cin >> a >> b; add(a,b); add(b,a);//要将两种根的情况存储 } return 0; }

树的遍历如果按照之前的方法随便遍历的话,很容易漏掉数据。因此树有它特有的两种遍历方式,深度优先遍历DFS和宽度优先遍历BFS。

深度优先遍历是由根节点为起点一直往子节点的子节点不断遍历,直到找到叶子节点(没有子节点)时,原路返回至其他子节点再进行遍历,直到将所有数据遍历完结束。

#include <iostream> #include <vector> using namespace std; const int N = 1e6 + 10; vector<int>edges[N]; int n; bool st[N];//由于根节点不知,要将历遍过的节点标记防止死循环 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 u, v; cin >> u >> v; edges[u].push_back(v); edges[v].push_back(u); } dfs(1);//以1为根结点的树 }

上述使用的是vector数组储存的树的深度优先遍历,接下来使用链式前向星再来模拟一次。要点:由于根节点的未知,要使用额外的bool 数组来标记已历遍过的数据。

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

现在介绍宽度优先遍历,也叫广度优先遍历,指的是将同一层的节点遍历完后再遍历下一层。所以根据队列的特性,我们可以应用queue来完成这个遍历。

我们还是先用vector数组的存储方法来模拟:(不要忘了将已遍历过了的点标记 ,与之前相同)

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

再来使用链式前向星来储存时的bfs:

#include <iostream> #include <queue> using namespace std; const int N = 1e6 + 10; int h[N], e[N * 2], ne[N * 2]; int n, id; bool st[N]; void add(int a, int b) { id++; e[id] = b; ne[id] = h[a]; h[a] = id; } void bfs() { queue<int>q; q.push(1); while (q.size()) { int u = q.front(); q.pop(); cout << u << " "; for (int i = h[u]; i; i = ne[i]) { int v = e[i]; if (!st[v]) { q.push(v); st[v] = true; } } } } int main() { cin >> n; for (int i = 1; i < n; i++) { int a, b; cin >> a >> b; add(a, b); add(b, a); } bfs(); }#include <iostream> #include <queue> using namespace std; const int N = 1e6 + 10; int h[N], e[N * 2], ne[N * 2]; int n, id; bool st[N]; void add(int a, int b) { id++; e[id] = b; ne[id] = h[a]; h[a] = id; } void bfs() { queue<int>q; q.push(1); while (q.size()) { int u = q.front(); q.pop(); cout << u << " "; for (int i = h[u]; i; i = ne[i]) { int v = e[i]; if (!st[v]) { q.push(v); st[v] = true; } } } } int main() { cin >> n; for (int i = 1; i < n; i++) { int a, b; cin >> a >> b; add(a, b); add(b, a); } bfs(); }

树的种类还有许多可分为N叉树,我认为树的进阶和之后的节点的捆绑就是类似图的数据结构吧,当然纯属个人想法,等到学到该内容再与大家讨论。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 20:40:27

4、数字转型时代的商业模式与高增长企业价值构成

数字转型时代的商业模式与高增长企业价值构成 1. 数字转型时代的商业模式洞察 1.1 数字转型的综合分析 在当今经济环境中,数字转型已成为企业发展的关键议题。通过对相关材料的频率和相关性分析,并与国内外学术文献进行关联,我们能更全面地理解数字转型背景下的商业模式。…

作者头像 李华
网站建设 2026/9/9 3:09:07

智谱AI推出GLM-4.5V-FP8多模态模型,视觉语言理解能力刷新行业标杆

智谱AI推出GLM-4.5V-FP8多模态模型&#xff0c;视觉语言理解能力刷新行业标杆 【免费下载链接】GLM-4.5V-FP8 项目地址: https://ai.gitcode.com/zai-org/GLM-4.5V-FP8 2024年人工智能技术领域迎来重要突破&#xff0c;智谱AI正式对外发布全新一代视觉语言模型GLM-4.5V…

作者头像 李华
网站建设 2026/9/9 20:34:02

谷歌Gemma 3 270M开源:轻量级AI模型如何重塑移动端智能体验

谷歌Gemma 3 270M开源&#xff1a;轻量级AI模型如何重塑移动端智能体验 【免费下载链接】gemma-3-270m-it-qat-GGUF 项目地址: https://ai.gitcode.com/hf_mirrors/unsloth/gemma-3-270m-it-qat-GGUF 在人工智能模型参数规模动辄数十亿甚至千亿的当下&#xff0c;谷歌最…

作者头像 李华
网站建设 2026/9/10 3:22:45

Qwen3-VL-8B深度测评:解锁多模态模型在技术流程图解析中的实战价值

在数字化转型加速推进的今天&#xff0c;技术文档作为传递系统逻辑与业务规则的核心载体&#xff0c;其可视化呈现&#xff08;尤其是流程图&#xff09;的准确解读直接影响开发效率与跨团队协作。传统纯文本大模型&#xff08;LLM&#xff09;在面对包含图形符号、空间布局与逻…

作者头像 李华