目录

算法精讲-树番外平衡世界的四大守护者AVL-vs-红黑树-vs-B树-vs-B树

算法精讲 | 树(番外):平衡世界的四大守护者:AVL vs 红黑树 vs B树 vs B+树

🌲 算法精讲 | 树(番外):平衡世界的四大守护者:AVL vs 红黑树 vs B树 vs B+树

📅 2025/03/12 || 🌟 推荐阅读时间 30分钟


🚀 开篇:数据结构界的四大天王

想象你是一名图书管理员,面对四种神奇的书架:

  • AVL树书架 :强迫症晚期,每放一本书都要拿水平仪测量 📏
  • 红黑树书架 :时尚弄潮儿,给书架涂红黑条纹 🎨
  • B树书架 :俄罗斯套娃大师,每个隔层能装 100 本书 📚
  • B+树书架 :目录狂魔,把索引刻在每一层 🗂️

今天我们一起破解它们的秘密!


🗺️ 知识导航图

https://i-blog.csdnimg.cn/direct/8ac7625414fb46ee9cddbe65ade7e573.png


一、AVL树:平衡强迫症患者

1.1 旋转手术四部曲

https://i-blog.csdnimg.cn/direct/df21d710c4e24b04b43cd9873ea8688e.png

⚔️ 右旋代码演示
TreeNode rightRotate(TreeNode y) {
    TreeNode x = y.left;   // 抓住左孩子
    TreeNode T2 = x.right; // 寄存右孙子
  
    x.right = y;           // 乾坤大挪移
    y.left = T2;           // 认领新孙子
  
    updateHeight(y);       // 📏 更新身高
    updateHeight(x);       // 📐 精确到毫米
    return x;              // 新掌门登基
}

二、红黑树:染发艺术家

2.1 红黑法典五条

https://i-blog.csdnimg.cn/direct/9ce687e6247847d89aabb14d0fce6387.png

2.2 插入修复三部曲

https://i-blog.csdnimg.cn/direct/28574bd27ecf4188b436bce4a63e2159.png

🎨 染色代码片段
void fixInsertion(Node z) {
    while (z.parent.color == RED) {
        if (uncle.color == RED) {         // 叔叔是红发
            parent.color = BLACK;        // 🔴 → ⚫
            uncle.color = BLACK;         // 🔴 → ⚫
            grandparent.color = RED;     // ⚫ → 🔴
            z = grandparent;             // 向上检查
        } else {
            // 旋转操作...
        }
    }
    root.color = BLACK; // 最终染黑
}

三、B树:图书馆长

3.1 B树结构解剖

https://i-blog.csdnimg.cn/direct/f674639ae10e41ea9960deab793b0e5c.png

📚 节点分裂演示

https://i-blog.csdnimg.cn/direct/1105cf55ca2f41649751195499c3b2b1.png

3.2 实战代码:B树插入

class BTreeNode:
    def __init__(self, t):
        self.keys = []         # 关键码库
        self.children = []     # 子节点库
        self.leaf = True       # 是否叶子

def insert(self, key):
    if len(self.keys) == 2*t - 1:  # 🚨 节点满了!
        new_node = BTreeNode(self.t)
        # 分裂过程...
    # 插入逻辑...

四、B+树:超级目录

4.1 与B树的三大区别

  • 📚 数据只存在叶子节点
  • 🔗 叶子节点形成有序链表
  • 🧲 非叶节点是密集索引

4.2 范围查询演示

https://i-blog.csdnimg.cn/direct/15521be38714486f9ab9a93cea2f638b.png

🚀 查询代码示例
List<Integer> rangeQuery(BPlusTree tree, int start, int end) {
    Node curr = findLeaf(tree.root, start);
    List<Integer> result = new ArrayList<>();
    while (curr != null && curr.keys[0] <= end) {
        for (int key : curr.keys) {
            if (key >= start && key <= end) 
                result.add(key);
        }
        curr = curr.next; // 链表跳跃
    }
    return result;
}

五、华山论剑:四大天王终极PK

https://i-blog.csdnimg.cn/direct/4ae9dc6f196a4844b53a17dc4c232e1d.png

特性AVL树红黑树B树B+树
平衡标准绝对平衡黑高平衡节点填充率节点填充率
插入复杂度O(log n)O(log n)O(log_t n)O(log_t n)
查询速度⚡极快🚀快速🚢稳定✈️极速
适用场景内存敏感综合场景文件系统数据库索引
磁盘友好度✅✅
代码复杂度😫高😣中😌较高😅较高
经典应用内存数据库Java TreeMapNTFS文件系统MySQL索引

六、灵魂拷问室 💬

面试官 :为什么Linux文件系统用B树而不用B+树?

:① 文件系统需要快速定位单个文件 ② B树非叶节点存数据有利小文件 ③ B+树更适合范围扫描

面试官 :红黑树为什么比AVL树应用更广?

:① 插入删除旋转次数少 ② 颜色标记比存储高度节省内存 ③ 综合性能更均衡

面试官 :B+树叶子链表如何维护?

:分裂时更新指针→类似双向链表插入节点,合并时同步调整

面试官 :为什么数据库用B+树不用B树?

:① 查询更稳定(都要到叶子层) ② 范围查询吊打B树 ③ 非叶节点更"苗条"

面试官 :HashMap为什么不用红黑树?

:① 哈希冲突少时链表更快 ② 红黑树适合持久化结构 ③ 达到阈值才树化

面试官 :B树的t值怎么选?

:根据磁盘页大小!比如4KB页,假设key占16B,t≈4KB/(16B+8B)=170


七、实战训练场

7.1 AVL树平衡检测

https://i-blog.csdnimg.cn/direct/4e65b5349197469fb2d8a77c0796fd63.png

7.2 红黑树插入案例

// 插入数字序列:3 → 7 → 2 → 5 → 4
public static void main(String[] args) {
    RedBlackTree tree = new RedBlackTree();
    tree.insert(3); // ⚫
    tree.insert(7); // 🔴 → 触发染色
    tree.insert(2); // 🔴 → 触发旋转
    tree.insert(5); // 🔴 → 叔叔节点处理
    tree.insert(4); // 🔴 → 复杂旋转
}

八、下期预告

《平衡森林的奇妙物语:从2-3树到跳表》 🔥 看点抢先:

  • 🌳 2-3树的柔性平衡之道
  • 🪜 跳表:用概率打破平衡的叛逆者
  • 🧬 B*树:在B树基础上玩出新花样

https://i-blog.csdnimg.cn/direct/60844fc740d549dc8a44aeb0d6dc8624.png


🌟 互动时刻 :四大天王中你最喜欢哪位?是强迫症的AVL,潮流的红黑树,还是磁盘大师B+树?留言区等你故事!