vlambda博客
学习文章列表

第八章 查找(4)——动态表查找之平衡二叉树



平衡二叉树



二叉排序树的查找效率与二叉树的形状有关,对于按给定序列建立的二叉排序树,若其左、右子树均匀分布,则查找过程类似于有序表的二分查找,时间复杂度变为O(log2n)。但若给定序列原来有序,则建立的二叉排序树就蜕化为单链表,其查找效率同顺序查找一样,时间复杂度变为O(n)。因此,在构造二叉排序树的过程中,当出现左、右子树分布不均匀时,若能对其进行调整,使其依然保持均匀,则就能有效地保证二叉排序树仍具有较高的查找效率。下面给出平衡二叉树的概念。

平衡二叉树(Balanced Binary Tree)又称为AVL树,它或是一棵空树,或是一棵具有下列性质的二叉树:它的左子树和右子树都是平衡二叉树,且左子树和右子树深度之差的绝对值不超过1。

若将二叉树中某个结点的左子树深度与右子树深度之差称为该结点的平衡因子(或平衡度),则平衡二叉树也就是树中任意结点的平衡因子的绝对值小于等于1的二叉树。在AVL树中的结点的平衡因子可能有3种取值:-1、0和1。下图给出了两棵二叉排序树,二叉树种的每一个结点旁边标注的数字就是该结点的平衡因子。由平衡二叉树的定义可知,图(a)所示是一棵平衡二叉排序树,而如图(b)所示的是一棵不平衡的二叉排序树。

在平衡二叉树上插入或删除结点后,可能使二叉树失去平衡。因此,需要对失去平衡的二叉树进行调整,以保持平衡二叉树的性质。本节中主要介绍如何动态地使一棵二叉排序树保持平衡,即对失去平衡的二叉排序树进行平衡化调整。下面具体讨论在AVL树上因插入新结点而导致失去平衡时的调整方法。

为叙述方便,假设在AVL树上因插入新结点而失去平衡的最小子树的根结点为A(即A为距离插入结点最近的,平衡因子不是-1、0和1的结点)。失去平衡后的操作可依据失去平衡的原因归纳为下列4种情况分别进行。

(1)LL型平衡旋转(单向右旋):由于在A的左孩子的左子树上插入新结点,使A的平衡度由1增至2,致使以A为根的子树失去平衡,如下图(a)所示。此时应进行一次向右的顺时针旋转操作,“提升”B(即A的左孩子)为新子树的根结点,A下降为B的右孩子,同时将B原来的右子树BR调整为A的左子树。

第八章 查找(4)——动态表查找之平衡二叉树

(2)RR型平衡旋转(单向左旋):由于在A的右孩子的右子树上插入新结点,使A的平衡度由-1变为-2,致使以A为根的子树失去平衡,如上图(b)所示。此时应进行一次向左的逆时针旋转操作,“提升”B(即A的右孩子)为新子树的根结点,A下降为B的左孩子,同时将B原来的左子树BL调整为A的右子树。

(3)LR型平衡旋转(先左旋后右旋):由于在A的左孩子的右子树上插入新结点,使A的平衡度由1变为2,致使以A为根的子树失去平衡,如下图(c)所示。此时应进行两次旋转操作(先逆时针,后顺时针),“提升”C(即A的左孩子的右孩子)为新子树的根结点;A下降为C的右孩子;B变为C的左孩子;C原来的左子树CL调整为B现在的右子树;C原来的右子树CR调整为A的左子树。

第八章 查找(4)——动态表查找之平衡二叉树

(4)RL型平衡旋转(先右旋后左旋):由于在A的右孩子的左子树上插入新结点,使A的平衡度由-1变为-2,致使以A为根的子树失去平衡,如上图(d)所示。此时应进行两次旋转操作(先顺时针,后逆时针),“提升”C(即A的右孩子的左孩子)为新子树的根结点;A下降为C的左孩子;B变为C的右孩子;C原来的左子树CL调整为A现在的右子树;C原来的右子树CR调整为B的左子树。

综上所述,在平衡二叉排序树T上插入一个新记录x的算法描述如下:

(1)若AVL树为空树,则插入一个记录为x的新结点作为T的根结点,树的深度增1。

(2)若x的关键字值和AVL树T的根结点的关键字值相等,则不进行插入操作。

(3)若x的关键字值小于AVL树的根结点的关键字值,则将x插入在该树的左子树上,并且当插入之后的左子树深度增加1时,分别就下列不同情况进行处理:

①若AVL树的根结点的平衡因子为-1(右子树的深度大于左子树的深度),则将根结点的平衡因子调整为0,并且树的深度不变。

②若AVL树的根结点的平衡因子为0(左右子树的深度相等),则将根结点的平衡因子调整为1,树的深度同时增加1。

③若AVL树的根结点的平衡因子为1(左子树的深度大于右子树的深度),则当该树的左子树的根结点的平衡因子为1时需进行LL型平衡旋转;当该树的左子树的根结点的平衡因子为-1时需进行LR型平衡旋转。

(4)若x的关键字值大于AVL树的根结点的关键字值,则将x插入在该树的右子树上,并且当插入之后的右子树深度增加1时,需要就不同情况进行处理。具体操作与(3)中所述相对称,读者可自行补充整理。

下面按一组关键字序列(45,16,22,36,28,60,19,51)的顺序建立一棵平衡二叉树,建立过程如下图所示。

第八章 查找(4)——动态表查找之平衡二叉树

在二叉排序树的插入和删除操作中采用平衡树的优点是:使二叉树的结构更好,从而提高了查找操作的速度。缺点是:使插入和删除操作复杂化,从而降低了插入和删除操作的速度。因此,平衡二叉树适合于二叉排序树一经建立就很少进行插入和删除操作,而主要进行查找操作的应用场合中。

在平衡二叉树上进行查找的过程和在二叉排序树上进行查找的过程相同,在查找过程中和给定值进行比较的关键字个数不超过树的深度。因此,在平衡二叉树上进行查找的时间复杂度为O(log2n)。


第八章 查找(4)——动态表查找之平衡二叉树