AVL树(二叉平衡树)失衡的旋转方式

3 阅读5分钟

AVL树(Adelson-Velsky and Landis Tree)是一种自平衡二叉搜索树。在AVL树中,任何节点的两个子树的高度最大差别为1。

为了衡量平衡,引入平衡因子(Balance Factor, 简称BF)平衡因子 = 左子树高度 - 右子树高度 在正常AVL树中,所有节点的平衡因子只能是 1、0 或 -1。如果插入或删除节点后,某个节点的平衡因子变成了 2 或 -2,树就失衡了,必须通过旋转来恢复平衡。

根据插入节点相对于失衡节点的位置,失衡分为四种情况,对应四种旋转方法:LL型、RR型、LR型、RL型


为了方便理解图解,图中的代号说明如下:

  • A:最早发现失衡的节点(平衡因子变为 2 或 -2)。
  • B、C:A的子节点或孙节点。
  • T1、T2、T3、T4:代表高度相等的子树(可以是空树)。
  • 括号里的数字代表该节点的平衡因子

1. LL型失衡:单右旋 (Right Rotation)

场景:在节点 A 的左孩子 (L)左子树 (L) 中插入了新节点,导致 A 的平衡因子变成 2。 口诀左左节点,向右单旋。

操作方法: 将 B 向上提,A 向下压,A 变成 B 的右孩子。如果 B 原来有右子树(T2),则将 T2 挂到 A 的左边。

图文演示

       【旋转前 (LL型)】                 【单右旋后 (恢复平衡)】
            A(2)                              B(0)
            /  \                             /   \
          B(1)  T4      -------->          C(0)   A(0)
          /  \          (绕A向右旋转)      / \    /  \
        C(0)  T2                         T0 T1  T2  T4
        / \
      T0   T1 
  (插入的新节点在C下面)

原理解释:因为这是一棵二叉搜索树,大小关系是:C < B < T2 < A < T4。旋转后,B 成为根节点,左边是更小的 C,右边是更大的 A。原本属于 B 右边且小于 A 的 T2,正好可以放在 A 的左边。


2. RR型失衡:单左旋 (Left Rotation)

场景:在节点 A 的右孩子 (R)右子树 (R) 中插入了新节点,导致 A 的平衡因子变成 -2。这是 LL 型的镜像。 口诀右右节点,向左单旋。

操作方法: 将 B 向上提,A 向下压,A 变成 B 的左孩子。如果 B 原来有左子树(T2),则将 T2 挂到 A 的右边。

图文演示

       【旋转前 (RR型)】                 【单左旋后 (恢复平衡)】
            A(-2)                             B(0)
            /  \                             /   \
          T1   B(-1)    -------->          A(0)   C(0)
               /  \     (绕A向左旋转)      /  \   /  \
             T2   C(0)                   T1  T2 T3  T4
                  /  \
                T3    T4 
            (插入新节点)

原理解释:大小关系是:T1 < A < T2 < B < C。旋转后 B 做根节点,左边是比它小的 A,右边是比它大的 C。T2 大于 A 且小于 B,正好挂在 A 的右孩子位置。


3. LR型失衡:先左旋再右旋 (Left-Right Rotation)

场景:在节点 A 的左孩子 (L)右子树 (R) (即节点 C) 中插入了新节点,导致 A 的平衡因子变成 2。 注意:此时如果直接对 A 进行单右旋,树依然是不平衡的。必须经过两次旋转

操作方法

  1. 第一步(转为LL型) :先对 A 的左孩子 B 进行一次单左旋,把 C 提上来,B 压下去。此时树结构变成了 LL 型。
  2. 第二步(恢复平衡) :再对 A 进行一次单右旋,把 C 提上来充当新的根节点,A 压下去。

图文演示

  【状态1:LR型失衡】      【状态2:转换为LL型】       【状态3:最终平衡】
          A(2)                  A(2)                    C(0)
          / \                   / \                    /   \
       B(-1) T4   --左旋B-->  C(1) T4    --右旋A-->  B(0)   A(0)
        / \                   / \                    / \    / \
      T1  C(0)              B(0) T3                T1 T2  T3 T4
          / \               / \
        T2   T3           T1   T2
   (新节点在T2/T3中)

原理解释:大小关系是 T1 < B < T2 < C < T3 < A < T4。C 大小介于 B 和 A 之间。所以最终的形态必须是 C 在中间做父节点,B 在左边,A 在右边。C 原来的左子树 T2 挂给 B 做右孩子,右子树 T3 挂给 A 做左孩子。


4. RL型失衡:先右旋再左旋 (Right-Left Rotation)

场景:在节点 A 的右孩子 (R)左子树 (L) (即节点 C) 中插入了新节点,导致 A 的平衡因子变成 -2。这是 LR 型的镜像。

操作方法

  1. 第一步(转为RR型) :先对 A 的右孩子 B 进行一次单右旋,把 C 提上来,B 压下去。此时树结构变成了 RR 型。
  2. 第二步(恢复平衡) :再对 A 进行一次单左旋,把 C 提上来,A 压下去。

图文演示

  【状态1:RL型失衡】      【状态2:转换为RR型】       【状态3:最终平衡】
         A(-2)                 A(-2)                    C(0)
         / \                   / \                     /   \
       T1  B(1)   --右旋B-->  T1 C(-1)   --左旋A-->   A(0)  B(0)
           / \                   / \                  / \   / \
         C(0) T4               T2  B(0)             T1 T2 T3 T4
         / \                       / \
       T2   T3                   T3   T4

原理解释:大小关系是 A < C < B。最终形态 C 作为父节点,A 作为左子树,B 作为右子树。C 原本的左边 T2 挂在 A 的右边,右边 T3 挂在 B 的左边。


总结与记忆诀窍

  1. 看名字知步骤

    • LLRR 是直线型,只需要一次单旋(方向与名字相反:LL右旋,RR左旋)。
    • LRRL 是折线型,需要两次旋转。名字本身就是旋转方向:LR = 先左旋再右旋RL = 先右旋再左旋
  2. 核心原则(二叉搜索树特性不变) : 无论怎么转,中序遍历(Left -> Root -> Right)的结果绝对不能改变。旋转的本质就是把高度较低的一侧往下压,把高度较高的一侧提上来,同时把断开的子树重新挂载到合适的大小区间位置。