算法基础 -- AVL树初识

AVL树初识

一、AVL树简介

AVL树是一种自平衡二叉搜索树(Binary Search Tree, BST),于1962年由Georgy Adelson-Velsky和Evgenii Landis提出,名字也来自他们两位的姓氏首字母组合。它通过在插入、删除节点后维持平衡性,确保在查找、插入、删除操作上保持 O ( log ⁡ n ) O(\log n) O(logn) 的平均和最坏时间复杂度。


二、AVL树的平衡条件

在普通的二叉搜索树中,树的高度可能因为插入或删除导致严重失衡,从而退化成链表。而AVL树通过维护**平衡因子(Balance Factor)**来保持平衡。

平衡因子的定义:

平衡因子 = 左子树的高度 − 右子树的高度 \text{平衡因子} = \text{左子树的高度} - \text{右子树的高度} 平衡因子=左子树的高度右子树的高度

  • 平衡因子的绝对值不超过1(即 − 1 -1 1、0、1),则该节点视为平衡
  • AVL树要求所有节点的平衡因子绝对值 ≤ 1 \leq 1 1

通过对节点的平衡因子进行检查和旋转操作,AVL树能始终维持其平衡性。


三、AVL树的基本操作

1. 查找(Search)

AVL树本质上是二叉搜索树,查找过程与普通二叉搜索树相同,时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)

2. 插入(Insert)

插入新节点的过程包括以下步骤:

  1. 常规插入: 按照二叉搜索树的规则插入新节点。
  2. 更新平衡因子: 从插入位置向上回溯,更新祖先节点的高度或平衡因子。
  3. 检测并恢复平衡: 如果某节点的平衡因子绝对值超过1,根据具体情况执行旋转操作。
插入导致的失衡类型
类型 条件 解决方法
LL失衡 节点的平衡因子为 +2,且左子节点的平衡因子 ≥ 0 \geq 0 0 单右旋
LR失衡 节点的平衡因子为 +2,且左子节点的平衡因子 < 0 < 0 <0 先左旋后右旋
RR失衡 节点的平衡因子为 -2,且右子节点的平衡因子 ≤ 0 \leq 0 0 单左旋
RL失衡 节点的平衡因子为 -2,且右子节点的平衡因子 > 0 > 0 >0 先右旋后左旋

3. 删除(Delete)

删除操作分以下几种情况:

  1. 删除叶子节点或单子节点:

    • 直接删除节点或用子节点替换。
  2. 删除有两个子节点的节点:

    • 找出该节点的前驱后继节点,用其值覆盖当前节点,并递归删除前驱/后继节点。
  3. 更新并恢复平衡:

    • 从被删除节点的位置向上回溯,更新祖先节点的平衡因子,若失衡则执行旋转操作。

四、旋转操作

AVL树通过旋转操作调整树的结构,从而恢复平衡。旋转分为以下四种:

1. 单右旋(LL失衡)

  • 触发条件:节点的平衡因子为 +2,且左子节点的平衡因子 ≥ 0 \geq 0 0
  • 示例:
        A                          B
       / \                        / \
      B   α     => 右旋         C   A
     / \                        /   / \
    C   β                      γ   β   α

2. 先左旋后右旋(LR失衡)

  • 触发条件:节点的平衡因子为 +2,且左子节点的平衡因子 < 0 < 0 <0
  • 示例:
        A                          A                          C
       / \        => 左旋         / \        => 右旋         / \
      B   α       B   α          C   A
       \          / \               / \
        C        B   γ             β   α
       / \       / \  
      β   γ     β   γ  

3. 单左旋(RR失衡)

  • 触发条件:节点的平衡因子为 -2,且右子节点的平衡因子 ≤ 0 \leq 0 0
  • 示例:
        A                          B
       / \                        / \
      α   B     => 左旋         A   C
         / \                    / \
        β   C                  α   β

4. 先右旋后左旋(RL失衡)

  • 触发条件:节点的平衡因子为 -2,且右子节点的平衡因子 > 0 > 0 >0
  • 示例:
        A                          A                          C
       / \        => 右旋         / \        => 左旋         / \
      α   B       α   C          A   B
         / \         \            / \
        C   γ         B          α   β
       / \          / \
      β   γ        β   γ

五、时间复杂度与特性

  • 高度: AVL树的高度保持在 O ( log ⁡ n ) O(\log n) O(logn) 量级,最坏情况下的高度为 log ⁡ ϕ ( n ) \log_{\phi}(n) logϕ(n) ϕ \phi ϕ 为黄金比例,约为1.618)。
  • 查找: 时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)
  • 插入/删除: 时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)
  • 额外空间: 需要维护每个节点的高度或平衡因子信息。

六、AVL树优缺点

优点:

  1. 查找性能优秀,适用于查找频繁的场景。
  2. 平衡性好,树的高度始终接近最优。

缺点:

  1. 插入和删除操作需要额外的旋转和更新,性能开销相对红黑树更高。
  2. 实现复杂,逻辑较为繁琐。

七、示例

以下为插入数据的过程示例:

插入数据:10, 20, 5, 15, 25, 30

  1. 插入10
   10
  1. 插入20
   10
     \
      20
  1. 插入5
     10
    /  \
   5    20
  1. 插入15
     10
    /  \
   5    20
        /
       15
  1. 插入25
     10
    /  \
   5    20
        /  \
       15   25
  1. 插入30,触发RR失衡,左旋后结果:
        20
       /  \
     10    25
    /  \      \
   5   15      30

八、总结

AVL树是一种高效的自平衡二叉搜索树,适用于对查找效率要求较高的场景,但在插入删除频繁的情况下,其复杂度和性能可能略逊于红黑树。

你可能感兴趣的:(算法,数据结构)