二叉查找树,平衡二叉树

2019-04-29 16:35 fengxiaofeng 阅读 (1760) 评论 () 编辑 收藏

二叉树具有以下性质:左子树的键值小于根的键值,右子树的键值大于根的键值。

二叉查找树,平衡二叉树 - fengxiaofeng - 博客园 - 图1

二叉查找树可以任意地构造,也可以按照下图的方式来构造:

二叉查找树,平衡二叉树 - fengxiaofeng - 博客园 - 图2

但是这棵二叉树的查询效率就低了。因此若想二叉树的查询效率尽可能高,需要这棵二叉树是平衡的,从而引出新的定义——平衡二叉树,或称 AVL 树。

平衡二叉树(AVL 树)在符合二叉查找树的条件下,还满足任何节点的两个子树的高度最大差为 1。

二叉查找树,平衡二叉树 - fengxiaofeng - 博客园 - 图3

如果在 AVL 树中进行插入或删除节点,可能导致 AVL 树失去平衡,这种失去平衡的二叉树可以概括为四种姿态:LL(左左)、RR(右右)、LR(左右)、RL(右左)。它们的示意图如下:

二叉查找树,平衡二叉树 - fengxiaofeng - 博客园 - 图4

这四种失去平衡的姿态都有各自的定义:
LL:LeftLeft,也称 “左左”。插入或删除一个节点后,根节点的左孩子(Left Child)的左孩子(Left Child)还有非空节点,导致根节点的左子树高度比右子树高度高 2,AVL 树失去平衡。

RR:RightRight,也称 “右右”。插入或删除一个节点后,根节点的右孩子(Right Child)的右孩子(Right Child)还有非空节点,导致根节点的右子树高度比左子树高度高 2,AVL 树失去平衡。

LR:LeftRight,也称 “左右”。插入或删除一个节点后,根节点的左孩子(Left Child)的右孩子(Right Child)还有非空节点,导致根节点的左子树高度比右子树高度高 2,AVL 树失去平衡。

RL:RightLeft,也称 “右左”。插入或删除一个节点后,根节点的右孩子(Right Child)的左孩子(Left Child)还有非空节点,导致根节点的右子树高度比左子树高度高 2,AVL 树失去平衡。

AVL 树失去平衡之后,可以通过旋转使其恢复平衡。下面分别介绍四种失去平衡的情况下对应的旋转方法。

LL 的旋转。LL 失去平衡的情况下,可以通过一次旋转让 AVL 树恢复平衡。步骤如下:

  1. 将根节点的左孩子作为新根节点。
  2. 将新根节点的右孩子作为原根节点的左孩子。
  3. 将原根节点作为新根节点的右孩子。

LL 旋转示意图如下:
二叉查找树,平衡二叉树 - fengxiaofeng - 博客园 - 图5

RR 的旋转:RR 失去平衡的情况下,旋转方法与 LL 旋转对称,步骤如下:

  1. 将根节点的右孩子作为新根节点。
  2. 将新根节点的左孩子作为原根节点的右孩子。
  3. 将原根节点作为新根节点的左孩子。

RR 旋转示意图如下:
二叉查找树,平衡二叉树 - fengxiaofeng - 博客园 - 图6

LR 的旋转:LR 失去平衡的情况下,需要进行两次旋转,步骤如下:

  1. 围绕根节点的左孩子进行 RR 旋转。
  2. 围绕根节点进行 LL 旋转。

LR 的旋转示意图如下:
二叉查找树,平衡二叉树 - fengxiaofeng - 博客园 - 图7

RL 的旋转:RL 失去平衡的情况下也需要进行两次旋转,旋转方法与 LR 旋转对称,步骤如下:

  1. 围绕根节点的右孩子进行 LL 旋转。
  2. 围绕根节点进行 RR 旋转。

RL 的旋转示意图如下:
二叉查找树,平衡二叉树 - fengxiaofeng - 博客园 - 图8