树与集合结构总览

比较堆、Trie、搜索树、平衡树、多路树和并查集各自维护的不变量与适用问题。

已发布文章计算机基础入门6 分钟阅读发布于 2026年9月1日更新于 2026年9月15日
文章目录
  1. 先分清这些树解决什么问题
  2. 平衡为什么重要
  3. 树的基本术语
  4. 四种基础遍历
  5. 从操作目标选择结构
  6. 从二叉树走向多路树
  7. 并查集为什么也像树
  8. 学习时抓住“不变量”
  9. 建议的实验方法
  10. 我自己的学习顺序
知识目录数据结构与算法:从基础到工程实践60 / 77
LOCAL NOTE高亮并记笔记
0 / 1000 · 只保存在这台设备
READER NOTES树与集合结构总览》的本机笔记

这篇来自我补“树与集合结构总览”基础时的一次复盘。我之前的问题是:树结构的名字越学越多时,我曾经只记规则:左小右大、保持平衡、多路节点,却没把它们解决的存储问题串起来。等我把输入、状态变化和边界条件分别写出来之后,原来看似突然出现的规则就有了来路。

线性结构把元素排成一条序列,树则用层次关系缩小搜索范围。堆、Trie、二叉搜索树、AVL 树、2-3 树、红黑树和并查集看起来差别很大,但都在回答:怎样利用关系和不变量,避免每次都扫描全部数据?

先分清这些树解决什么问题

结构 核心不变量 主要能力
二叉堆 父节点不大于或不小于子节点 快速取得极值、优先队列
Trie 从根到节点的路径代表前缀 字符串前缀检索
二叉搜索树 左子树小、右子树大 有序查找与遍历
AVL 树 任一节点左右高度差不超过 1 更严格的平衡查找
2-3 树 节点可含多个键,叶子同层 绝对平衡的多路搜索
红黑树 颜色规则限制最长路径 较少旋转的近似平衡
并查集 每个集合由代表元组织 判断连通、快速合并集合

“都是树”并不意味着可以互换。堆只保证父子之间的偏序,不能像搜索树一样快速查找任意值;二叉搜索树有全局有序关系,却不保证根节点是极值优先队列的最佳实现;Trie 按字符路径组织,空间模型又与比较型树不同。

平衡为什么重要

一棵含 n 个节点的理想二叉搜索树,高度约为 log₂n,查找沿一条根到叶路径完成。但如果按递增顺序插入普通 BST,它可能退化成链表,高度变为 n

堆、二叉搜索树、Trie 和树遍历关系图

图:不同树结构维护不同不变量,遍历只改变访问顺序

AVL 和红黑树都通过旋转修复结构。AVL 更严格,因此查找路径通常更短;红黑树容许有限的不平衡,插入删除时往往调整更少。选择标准不是“谁绝对更快”,而是读写比例、实现复杂度和库支持。

树的基本术语

  • 根:没有父节点的起点。
  • 叶子:没有孩子的节点。
  • 深度:从根到当前节点经过的边数。
  • 高度:从当前节点到最深叶子的最长路径。
  • 度:节点拥有的孩子数量。
  • 子树:某节点及其全部后代构成的树。

不同资料对“空树高度”和“单节点高度”可能采用不同定义。实现前必须统一:若空节点高度为 0,叶子高度通常为 1;若空节点为 -1,叶子则为 0。AVL 的平衡计算只要前后一致即可。

四种基础遍历

二叉树前序中序后序层序遍历图

图:同一棵树在四种遍历方式下的访问顺序

遍历 顺序 常见用途
前序 根、左、右 复制树、输出结构
中序 左、根、右 BST 得到有序序列
后序 左、右、根 删除树、计算子树信息
层序 按层从上到下 最短层级、序列化、宽度统计

深度优先遍历可以递归或显式栈实现,层序遍历使用队列。遍历时间通常为 O(n),因为每个节点至少访问一次;额外空间取决于树高或最大层宽。

static <E> void levelOrder(Node<E> root) {
    if (root == null) return;
    java.util.ArrayDeque<Node<E>> queue = new java.util.ArrayDeque<>();
    queue.offer(root);
    while (!queue.isEmpty()) {
        Node<E> node = queue.poll();
        System.out.println(node.value);
        if (node.left != null) queue.offer(node.left);
        if (node.right != null) queue.offer(node.right);
    }
}

从操作目标选择结构

  • 只需反复取得最大或最小值:堆。
  • 需要按键排序、范围查询:平衡搜索树。
  • 需要字符串前缀:Trie 或压缩基数树。
  • 需要集合连通与合并:并查集。
  • 数据位于磁盘页:B 树或 B+ 树。
  • 数据静态、查询极多:排序数组加二分查找可能更简单。

树结构的复杂度常写成 O(log n),但必须说明平衡保证。普通 BST 没有保证,堆的任意值查找也不是 O(log n)

从二叉树走向多路树

2-3 树允许一个节点存一个或两个键,并拥有两个或三个孩子。多路节点可以降低树高,也是理解 B 树、B+ 树和数据库索引的入口。磁盘与页存储更关心一次 I/O 能带回多少键,因此真实数据库通常不会直接使用二叉树。

并查集为什么也像树

并查集用父指针把同一集合的元素连接起来。它不关心有序遍历,而关心两个操作:找到集合代表元 find,合并两个集合 union。路径压缩和按秩合并让树保持很浅,连续操作的摊销成本接近常数。

学习时抓住“不变量”

每学一种树,先写出它必须始终成立的条件,再分析插入、删除如何恢复条件:

  1. 节点保存哪些信息?
  2. 父子关系必须满足什么规则?
  3. 哪个操作可能破坏规则?
  4. 用交换、旋转、分裂、合并还是压缩修复?
  5. 修复会影响多大范围?

如果只背旋转步骤,很容易在边界条件中迷失;把旋转看作“保持有序关系的局部重连”,理解会稳定得多。

建议的实验方法

  1. 每次插入后打印树,不只看最终结果。
  2. 编写独立验证器,检查有序性、高度、颜色或黑高。
  3. 使用递增、递减、随机、重复和交错序列构造不同形态。
  4. 与标准库 TreeMap、PriorityQueue 的外部行为对照。
  5. 统计旋转次数、树高和比较次数,观察理论如何反映到运行数据。

图形化很有帮助,但图不能代替验证器。一张画对的示意图无法证明所有输入都正确,自动检查不变量才能持续发现结构损坏。

我自己的学习顺序

堆 → Trie → 普通二叉搜索树 → AVL → 2-3 树 → 红黑树 → 并查集。先看普通 BST 的退化问题,再看不同平衡策略为何出现;先理解 2-3 树,再理解红黑树用二进制颜色编码多路节点会更顺畅。

JARVIS · 当前文章

有哪里没看懂?可以只问这篇。

Jarvis 会限定在《树与集合结构总览》及其公开关联内容中检索,并把引用定位回原文章节。

JARVIS / ARTICLE针对《树与集合结构总览》提问
当前范围树与集合结构总览不会悄悄扩大到全站
0 / 1000

准备好了。当前只会围绕树与集合结构总览回答。

READER SIGNAL

这篇内容对你有帮助吗?

不需要登录。你的反馈会直接进入作者待处理列表。