平衡二叉树(AVL树)的旋转操作与平衡因子维护
字数 1364 2025-11-21 18:32:48
平衡二叉树(AVL树)的旋转操作与平衡因子维护
1. 问题背景
平衡二叉树(AVL树)是一种自平衡二叉搜索树,通过维护每个节点的平衡因子(左子树高度减右子树高度)来保证树的高度始终为 \(O(\log n)\),从而确保插入、删除和查找操作的时间复杂度为 \(O(\log n)\)。当平衡因子超出允许范围(-1, 0, 1)时,需要通过旋转操作调整树结构。
2. 核心概念:平衡因子
- 定义:对于任意节点,平衡因子 = 左子树高度 - 右子树高度。
- 合法范围:-1、0、1。若平衡因子为2或-2,则需调整。
- 高度更新:插入或删除节点后,需从操作位置向上更新祖先节点的高度,并重新计算平衡因子。
3. 旋转操作的四种类型
根据失衡节点的平衡因子和子节点的平衡因子,分为以下四种情况:
3.1 左旋(Left Rotation)
- 适用场景:失衡节点的平衡因子为-2,且右子节点的平衡因子为-1或0(右右情况)。
- 操作步骤:
- 以失衡节点A的右孩子B为新的根节点。
- 将B的左子树作为A的右子树。
- 将A作为B的左子树。
- 示例(右右情况):
左旋后:A (平衡因子=-2) \ B (平衡因子=-1) \ CB / \ A C
3.2 右旋(Right Rotation)
- 适用场景:失衡节点的平衡因子为2,且左子节点的平衡因子为1或0(左左情况)。
- 操作步骤:
- 以失衡节点A的左孩子B为新的根节点。
- 将B的右子树作为A的左子树。
- 将A作为B的右子树。
- 示例(左左情况):
右旋后:A (平衡因子=2) / B (平衡因子=1) / CB / \ C A
3.3 左右旋(Left-Right Rotation)
- 适用场景:失衡节点A的平衡因子为2,且左孩子B的平衡因子为-1(左右情况)。
- 操作步骤:
- 先对B执行左旋(将B的右孩子C提升为B的父节点)。
- 再对A执行右旋(将C提升为新的根节点)。
- 示例:
先左旋B:A (平衡因子=2) / B (平衡因子=-1) \ C
再右旋A:A / C / BC / \ B A
3.4 右左旋(Right-Left Rotation)
- 适用场景:失衡节点A的平衡因子为-2,且右孩子B的平衡因子为1(右左情况)。
- 操作步骤:
- 先对B执行右旋(将B的左孩子C提升为B的父节点)。
- 再对A执行左旋(将C提升为新的根节点)。
- 示例:
先右旋B:A (平衡因子=-2) \ B (平衡因子=1) / C
再左旋A:A \ C \ BC / \ A B
4. 插入操作中的平衡维护流程
- 标准BST插入:按二叉搜索树规则插入新节点。
- 向上更新高度:从新节点开始向上遍历祖先节点,更新每个节点的高度。
- 检查平衡因子:若某个节点的平衡因子变为2或-2,根据子节点平衡因子选择旋转类型:
- 左左 → 右旋
- 右右 → 左旋
- 左右 → 左右旋
- 右左 → 右左旋
- 调整后更新高度:旋转后重新计算相关节点的高度。
5. 实例演示
插入序列:[10, 5, 15, 3, 7, 12, 20, 1]
- 插入10、5、15:树平衡。
- 插入3:
节点10的平衡因子=1,节点5的平衡因子=1,仍平衡。10 / \ 5 15 / 3 - 插入7:
节点10的平衡因子=2(左子树高2,右子树高0),且节点5的平衡因子=0(左右情况),需左右旋:10 / \ 5 15 / \ 3 7- 先左旋节点5:
10 / \ 7 15 / 5 /
- 再右旋节点10:
3 157 / \ 5 10 / \最终树恢复平衡。 - 先左旋节点5:
6. 总结
- AVL树的旋转操作是维护平衡的核心,分为左旋、右旋及其组合。
- 每次插入或删除后,需从操作点向上检查平衡因子,最多需要 \(O(\log n)\) 次调整。
- 旋转操作的时间复杂度为 \(O(1)\),整体插入/删除操作保持 \(O(\log n)\)。