二叉平衡树的旋转操作

平衡二叉树简称平衡树,是由Adelson-Velskii和Landis于1962年首先提出的,所以又称为AVL树。他的定义很简单,就是若一棵二叉树的每个左右节点的高度差最多相差1,此二叉树即是平衡二叉树。把二叉树的每个节点的左子树减去右子树定义为该节点的平衡因子。二叉平衡树的平衡因子只能是1、0或者-1。

平衡二叉树是对二叉搜索树(又称为二叉排序树)的一种改进。二叉搜索树有一个缺点就是,树的结构是无法预料的,随意性很大,它只与节点的值和插入的顺序有关系,往往得到的是一个不平衡的二叉树。在最坏的情况下,可能得到的是一个单支二叉树,其高度和节点数相同,相当于一个单链表,对其正常的时间复杂度有O(lb n)变成了O(n),从而丧失了二叉排序树的一些应该有的优点。

当插入一个新的节点的时候,在普通的二叉树中不用考虑树的平衡因子,只要将大于根节点的值插入到右子树,小于节点的值插入到左子树,递归即可。而在平衡二叉树则不一样,在插入节点的时候,如果插入节点之后有一个节点的平衡因子要大于2或者小于-2的时候,他需要对其进行调整,现在只考虑插入到节点的左子树部分(右子树与此相同)。主要分为以下三种情况:

(1)若插入前一部分节点的左子树高度和右子树高度相等,即平衡因子为0,插入后平衡因子变为1,仍符合平衡的条件不用调整。

(2)若插入前左子树高度小于右子树高度,即平衡因子为-1,则插入后将使平衡因子变为0,平衡性反倒得到调整,所以不必调整。

(3)若插入前左子树的高度不等于右子树高度,即平衡因子为1或-1,则插入节点之后会使得平衡因子变为2或者-2,这样的情况下就破坏了平衡二叉树的结构,所以必须对其进行调整,使其平衡;

插入节点会破坏平衡的四种情况:

有四种种情况可能导致二叉查找树不平衡,分别为:

(1)LL:插入一个新节点到根节点的左子树(Left)的左子树(Left),导致根节点的平衡因子由1变为2

(2)RR:插入一个新节点到根节点的右子树(Right)的右子树(Right),导致根节点的平衡因子由-1变为-2

(3)LR:插入一个新节点到根节点的左子树(Left)的右子树(Right),导致根节点的平衡因子由1变为2

(4)RL:插入一个新节点到根节点的右子树(Right)的左子树(Left),导致根节点的平衡因子由-1变为-2
 

调整二叉树首先要明白一个定义,即最小不平衡子树。最小不平衡子树是指以离插入节点最近、且平衡因子绝对值大于1的节点做根的子树。

下面讲解平衡二叉树最基本的4种调整操作,调整的原则是调整后他的搜索二叉树的性质不变,即树的中序遍历是不会改变的。

情况一:LL ->插入F节点导致失衡:

这里失衡的是A的左右子树,很容易就可以想到旋转B-A链,值得注意的是E节点,它原先在B的右子树,现在也依然在B的右子树,它原先在A的左子树,现在也依然在A的左子树。

若插入F节点在D的右子树处,旋转操作依然是上图那样,不谈。

但如果插入F节点是E的孩子就不一样了。

情况二:LR ->插入F节点导致失衡:

插入节点是E的孩子时,如果我们还像上面那样旋转B-A链,旋转后的树依然是不平衡的。事实上,这样的旋转使得B成为了新的根节点,而原图中比B大的节点有4个,比B小的节点只有D,若B为根其左子树只能为D,必定是不平衡的。

我们仔细观察原图,这里E节点是很特殊的节点。首先它是实际执行了插入操作的节点,其次图中比E小的节点有B、D、F,比E大的节点有A、C。如果能够让E节点做新的根节点就很好平衡了,那么怎样让E节点“上位”呢?

方法是进行两次旋转,如下图:

E节点恐成最大赢家……

插入节点是E的右子树的情况与之类似,这里给出旋转图:

F比E大,双旋之后还是在E的右节点。

双旋看图理解起来简单,实际实现时要注意,我们可以判断失衡的是A节点,由A有直接关系的是B和C,那么我们怎么知道新插入的F节点是D的子树还是E的子树呢?这里的方法是比较F节点值与B的大小,大则是E的子树,要左-右共两次旋转,小则是D的子树,要一次右旋转。

当然还要考虑镜像情况:

情况三:RR ->插入 F导致失衡:

进行一次左旋,关注D节点,它比C小,旋转后依然在C的左子树。

情况四:RL ->插入F导致失衡:

这时候左旋失败,理由和之前右旋失败类似,比C节点大的节点只有一个E,C是没法做新的根节点的。这里特殊的是D节点。

进行右-左两次双旋就可以了。D节点:爽到……

插入节点是D的右子树情况类似,RT:



参考:https://blog.csdn.net/saasanken/article/details/80796178 

https://blog.csdn.net/xomlee/article/details/17628681

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值