平衡二叉树(AVL)平衡化旋转详解

一、平衡二叉树

1、为什么要引入平衡二叉树
平衡二叉树的全称是平衡二叉排序树,也称为AVL树,这是因为该树结构是由Adelson-Velskii和Landis在1963年提出的。AVL树是BST树的改进结构,使得平均查找长度得到了减少,进而提高了查找的效率。
BST树是一种查找效率较高的二叉树结构,但不是所有的BST树都能保证高效率的查找,其平均查找长度和树的深度有关。
例如有一组数据{5,4,3,2,1},在创建二叉排序树时,得到如下结果:
在这里插入图片描述
该树的深度是5,平均查找长度ASL=(1+2+3+4+5)/ 5 = 3。此时想查找元素3,需要比较3次才可找到,想查找元素2,需要比较4次才可以找到,查找效率很低。为了改进这个问题,Adelson-Velskii和Landis提出了改进的BST树,即平衡二叉排序树,结果如下:
在这里插入图片描述
该树的深度是3,平均查找长度ASL=(1+2x2+2x3)/ 5 = 2.2。此时想查找元素3,需要比较1次即可找到,想查找元素2,需要比较2次可以找到,查找效率得到了提高。

2、平衡因子与平衡二叉树

为了方便定义平衡二叉树,引入了平衡因子的概念。对某一个结点而言,该结点的平衡因子就是其左子树与右子树的深度差。

当BST树上的所有结点的平衡因子的取值为-1、 0 或者 1时,该树就是平衡二叉树。

下面的图中所示的二叉树均是平衡二叉树,这也是常见的平衡二叉树的基本型。
在这里插入图片描述
图(1)的平衡因子为1,(2)的平衡因子为0,(3)的平衡因子为-1。
在图(1)和(3)中,除了根结点,其它结点的平衡因子是0。
在图(2)中,结点8的平衡因子是-1,其它结点的平衡因子是0。

二、平衡化旋转

在创建BST树是,不一定都能保证是平衡二叉树,因此需要通过旋转操作将其转化为平衡二叉树。常见的旋转方法有LL型、RR型、LR型和RL型四种旋转。
2.1)LL型平衡化旋转
LL型旋转主要针对以下形式的BST树。
在这里插入图片描述
图(1)中的二叉树是平衡二叉树,其平衡因子为1。
在图(1)中插入新的结点6,得到图(2)所示的BST树,此时平衡因子是2,不满足平衡二叉树的条件,因此可以通过旋转的方法使其变成平衡二叉树。具体的做法是将二叉树以树根所在位置为旋转轴进行顺时针旋转,得到如图(3)所示的二叉树,即将左子树树根16提升为二叉树的树根,将结点16的右子树连接到原来树根结点25的左子树,以确保新得到的二叉树仍旧是二叉排序树,且平衡因子是0,因此就得到了一个平衡二叉树。
由于是在原来的平衡二叉树的左子树的左分支增加了新结点而导致了不平衡,所以该旋转方法就称为LL(Left-Left)型平衡化旋转,也称为右单旋转方法。
说明:如果在结点10的右子树插入新的结点,平衡化旋转方法也是相同的。
A)引入指针T和p,LL旋转过程如下图所示:
在这里插入图片描述
B)LL平衡化旋转算法如下:

p = T->L;
T->L = p->R;
p->R = T;
T = p;
平衡因子 = 0

2.2)RR型平衡化旋转
RR型和LL型关于树根是对称的,如下图所示。
在这里插入图片描述
图(1)中的二叉树是平衡二叉树,其平衡因子为-1。
在图(1)中插入新的结点60,得到图(2)所示的BST树,此时平衡因子是-2,不满足平衡二叉树的条件,因此可以通过旋转的方法使其变成平衡二叉树。具体的做法是将二叉树以树根所在位置为旋转轴进行逆时针旋转,得到如图(3)所示的二叉树,即将右子树树根40提升为二叉树的树根,将结点40的左子树连接到原来树根结点25的右子树,以确保新得到的二叉树仍旧是二叉排序树,且平衡因子是0,因此就得到了一个平衡二叉树。
由于是在原来的平衡二叉树的右子树的右分支增加了新结点而导致了不平衡,所以该旋转方法就称为RR(Right-Right)型平衡化旋转。
说明:如果在结点50的左子树插入新的结点,平衡化旋转方法也是相同的。
A)引入指针T和p,RR旋转过程如下图所示:
在这里插入图片描述
B)RR平衡化旋转算法如下:

p = T->R;
T->R = p->L;
p->L = T;
T = p;
平衡因子 = 0

2.3)LR型平衡化旋转
LR型平衡化旋转相对于LL型比较麻烦,涉及到两次旋转。第一次旋转是将LR型转化成LL型,第二次旋转则同LL型平衡化旋转相同。
如下图所示,假设有图(1)中所示的平衡二叉树,其平衡因子为1,现插入元素22,得到图(2)中所示的二叉树,此时该二叉树的平衡因子为2,不是平衡二叉树。为了提高查找效率,需要进行平衡化旋转,首先以左子树树根16为旋转轴,逆时针旋转一次,得到图(3)所示的二叉树,平衡因子为2,此时该二叉树和LL型相同,因此绕树根顺时针旋转即可得到图(4)所示的平衡二叉树,平衡因子为0.
该旋转方法由于是在左子树的有分支插入新的结点导致失衡,因此称为LR(Left-Right)型平衡化旋转。
在这里插入图片描述
A)引入指针T、p和q,LR旋转过程如下图所示:

在这里插入图片描述
B)LR平衡化旋转算法如下:

p = T->L;
q = p->R;
q->L = p;
p->R = NULL;
T->L = q->R;
q->R = T;
T = q;
平衡因子 = 0

说明:如果在结点20的左子树插入新的结点,平衡化旋转方法如下:
在这里插入图片描述
2.4)RL型平衡化旋转
LR型平衡化旋转用到两次旋转。第一次旋转是将RL型转化成RR型,第二次旋转则同R型平衡化旋转相同。
如下图所示,假设有图(1)中所示的平衡二叉树,其平衡因子为-1,现插入元素28,得到图(2)中所示的二叉树,此时该二叉树的平衡因子为-2,不是平衡二叉树。为了提高查找效率,需要进行平衡化旋转,首先以右子树树根40为旋转轴,顺时针旋转一次,得到图(3)所示的二叉树,平衡因子为-2,此时该二叉树和RR型相同,因此绕树根逆时针旋转即可得到图(4)所示的平衡二叉树,平衡因子为0.
该旋转方法由于是在左子树的有分支插入新的结点导致失衡,因此称为RL(Right-Left)型平衡化旋转。
在这里插入图片描述
A)引入指针T、p和q,RL旋转过程如下图所示:
在这里插入图片描述
B)RL平衡化旋转算法如下:

p = T->R;
q = p->L;
q->R = p;
p->L = NULL;
T->R = q->L;
q->L = T;
T = q;
平衡因子 = 0

说明:如果在结点30的右子树插入新的结点,平衡化旋转方法如下:
在这里插入图片描述
:平衡化旋转方法是不唯一的,上述只是给出了其中的一类旋转方法。

扫描二维码关注公众号,回复: 15607634 查看本文章

猜你喜欢

转载自blog.csdn.net/sunnyoldman001/article/details/127231432