Skip to content

算法中主要的几种树

  • AVL树追求“高度平衡”,用于快速查找;
  • 红黑树在平衡与插入效率之间做折中,是许多库(如 TreeMapHashMap)的核心结构;
  • 哈夫曼树追求“最优编码”,常用于压缩算法(如 ZIP、JPEG、MP3 等)。

🌳 一、AVL树(平衡二叉搜索树)

1.1 定义

AVL树(Adelson-Velsky and Landis Tree)是最早被提出的自平衡二叉搜索树(BST)。 它在任何节点上都满足以下平衡条件:

对于任意一个节点,其左子树和右子树的高度差(平衡因子)不超过 1。

即:

| height(left) - height(right) | ≤ 1

若插入或删除节点后破坏了平衡性,则通过**旋转(Rotation)**来恢复。


1.2 结构示意

一个 AVL 树既满足 二叉搜索树(BST) 的性质:

左子树 < 根 < 右子树

又保持“尽量平衡”,例如:

      4
    /   \
   2     6
  / \   / \
 1  3  5  7

1.3 平衡调整(旋转)

AVL树的关键是 旋转操作。 共有四种旋转类型,用于恢复平衡:

类型说明图示
LL旋转新节点插入左子树的左侧右旋
RR旋转新节点插入右子树的右侧左旋
LR旋转新节点插入左子树的右侧先左旋再右旋
RL旋转新节点插入右子树的左侧先右旋再左旋

例:LL型(右旋)

插入导致左高:
      5
     /
    3
   /
  2

右旋后变为:

     3
    / \
   2   5

1.4 时间复杂度

操作复杂度
查找O(log n)
插入O(log n)(可能伴随旋转)
删除O(log n)(可能伴随旋转)

1.5 优缺点与应用

✅ 优点:

  • 高度平衡,查找效率高且稳定(接近完美平衡)。

❌ 缺点:

  • 插入/删除频繁时旋转次数多,维护成本高。

📦 适用场景:

  • 读操作远多于写操作的系统(如索引结构、缓存树等)。

🔴 二、红黑树(Red-Black Tree)

2.1 定义

红黑树是一种 近似平衡的二叉搜索树(BST),它在插入和删除时通过“着色 + 局部旋转”来维持平衡。 红黑树不是严格平衡的,但能保证最长路径不超过最短路径的两倍。


2.2 性质(五大约束)

红黑树定义了如下 5 条性质:

  1. 每个节点非红即黑;
  2. 根节点是黑色;
  3. 所有叶子节点(NIL节点)是黑色;
  4. 如果一个节点是红的,则它的两个子节点都是黑的(不允许连续红节点);
  5. 从任意节点到其所有叶子节点的路径上,黑色节点数相同

2.3 示例

一个合法的红黑树:

        10(B)
       /     \
   5(R)       15(R)
  /  \        /   \
2(B) 7(B)   12(B) 18(B)

2.4 插入与删除平衡调整

红黑树的平衡调整方式复杂于 AVL 树,因为需要满足“颜色约束”。 核心手段包括:

  • 重新着色(Recoloring)
  • 左旋(Left Rotate)
  • 右旋(Right Rotate)

例如插入时常见三种情况:

情况说明处理方式
叔叔节点为红重新染色(父叔变黑,祖父变红)
叔叔节点为黑,且是“内侧”插入先旋转成“外侧”结构(双旋)
叔叔节点为黑,且是“外侧”插入单旋并染色

2.5 时间复杂度

操作复杂度
查找O(log n)
插入O(log n)
删除O(log n)

红黑树在最坏情况下高度约为 2 * log2(n+1),性能非常稳定。


2.6 优缺点与应用

✅ 优点:

  • 保证平衡的同时减少旋转次数;
  • 插入/删除效率高于 AVL;
  • 适合频繁修改的场景。

❌ 缺点:

  • 查找效率略低于 AVL(因为不完全平衡)。

📦 应用:

  • Java 的 TreeMapTreeSet
  • Java 8 的 HashMap 冲突链表转红黑树;
  • Linux 的 CFS调度器epoll
  • C++ STL 的 std::map / std::set

🟢 三、哈夫曼树(Huffman Tree)

3.1 定义

哈夫曼树(Huffman Tree)是一种用于最优编码(最短加权路径长度)带权路径树,又称最优二叉树

其主要应用是 数据压缩(Huffman 编码)。


3.2 基本思想

核心目标:

让频率高(权值大)的字符编码更短,频率低的字符编码更长,从而整体平均编码长度最短。


3.3 构造过程

假设有字符及其出现频率:

字符权值
A5
B9
C12
D13
E16
F45

构造步骤:

  1. 将所有字符视为独立节点;
  2. 每次取权值最小的两个节点合并为一个新节点,新节点的权值=两子节点权值之和;
  3. 重复步骤 2,直到只剩下一个根节点。

最终得到的二叉树即为哈夫曼树。


3.4 编码示例

若从根到左子树记为 0,右子树记为 1, 则每个字符的哈夫曼编码如下:

字符编码
F0
C100
D101
A1100
B1101
E111

平均编码长度最小,达到压缩效果。


3.5 应用场景

✅ 优点:

  • 平均码长最小,实现高效压缩。

📦 应用:

  • 文件压缩(ZIP、GZIP、JPEG、MP3 等)
  • 传输编码(如霍夫曼编码通信)

⚖️ 四、三者对比总结

特性AVL树红黑树哈夫曼树
类型平衡二叉搜索树近似平衡二叉搜索树最优二叉树(非搜索树)
平衡性严格平衡近似平衡不要求平衡
调整手段旋转旋转 + 着色合并最小权值节点
查找效率高(O(log n))稍低(O(log n))不用于查找
插入/删除效率较低(频繁旋转)较高(较少旋转)只构建一次
应用场景数据索引、查找树Java TreeMap、HashMap等数据压缩、编码
设计目标查找性能最优插入删除性能与平衡折中编码长度最优

🧠 五、总结

  • AVL树:强调高度平衡,查找快,插入慢。
  • 红黑树:适度平衡,综合性能最好,是现代语言库的首选。
  • 哈夫曼树:用于编码压缩,与搜索无关。

三者分别代表了数据结构三种优化思路:

平衡 → 稳定 → 最优编码。

随便写写的,喜欢就好。 使用VitePress构建