二叉平衡树(AVL树)详细理解

二叉平衡树(AVL树)

AVL树插入元素结论

单旋转:

在这里插入图片描述

双旋转:

在这里插入图片描述

如果看到后面会发现,我下面举得列子,类型一和类型三和我结论里面的有点不一样,那是因为类型一的节点4和类型三的节点14无论以何种方式都能达到平衡状态,为了减少我们的代码分类次数,于是可以归到旋转两次里面

二叉平衡树的定义

(1)左右子树深度之差的绝对值不超过1;

(2)左右子树仍然为平衡二叉树.

推导过程

添加元素:

​ 链表,添加元素就有两种方法,第一是往尾部直接添加元素,第二是往中间某个节点添加,而第二种方法添加需要遍历到相应的位置才可以添加,时间复杂度O(n)

​ 于是我思考,平衡树其实也是链表,也可以往中间添加元素,但是这样岂不是得不偿失,顾此失彼了,反而让平衡树添加变得更加慢了,因为不但要调整该节点的位置,还要旋转树,考虑的更多了,于是便有了直接添加到尾部,不满足再旋转,简单粗暴

在这里插入图片描述

什么时候旋转?怎么旋转?

​ 平衡树如果左子树和右子树高度一致,那么无论怎么添加都是平衡的,只有左右子树差一的情况才需要改变树

​ 于是有了以下2种情况,每种又分为两类,一种四类

情况一左子树高于右子树:

  • 类型一:左子树高于右子树,添加到左子树最外面,也就是添加到3的左或者右,情况都是一样的,

在这里插入图片描述

右旋(就是右子树长高):到到下面的效果,树平衡了我们把叫做右旋,只需要旋转一次,往后面想是不是右子树的最外面也是一样的呢?我们可以试一试,后面解答

在这里插入图片描述

把节点5当做根节点,旋转后因为根节点是5了,7必须要到右边去,于是把7放到9的左边,后面所有的都差不多,如果连这个都看不懂,建议先看看二叉查找树,自己好好想想,后面不再解释

  • 类型二:里层添加元素,无论是添加节点8还是节点10,都是一样对待

在这里插入图片描述

第一步依然找最外层的节点7,左旋

在这里插入图片描述

第二步:原始最外层节点7的右孩子(节点9)右旋

在这里插入图片描述

于是平衡了

情况二右子树高于左子树:

  • 类型三:右子树的最外层添加,无论是节点15的左叶子还是右叶子,最外层的是节点15

在这里插入图片描述

左旋(左子树长高):发现依然是一次旋转,我们的树便平衡了,我们叫做左旋
在这里插入图片描述

又再次平衡了

  • 类型四:里层添加元素,依然是无论在节点11的左叶子还是右叶子添加都一样
    在这里插入图片描述

我们试着右旋转一次:于是得到下面这个样子,还是不平衡,怎么办呢?(再次说明,添加节点10或者节点12,我只是懒,不想拆开再画了,效果一样,不要纠结,就害怕看错了)

第一步依然是找到最外层的节点13,右旋,发现依然不平衡

在这里插入图片描述

第二步,原始树最外层节点13的左孩子(节点11),左旋

在这里插入图片描述

于是平衡了

复杂例子训练

上面的例子都是过于简单的,于是我们添加一个比较复杂的列子来再次试验,随便添加一个节点(红色表示)

在这里插入图片描述

这次我没有标注大小,相信也能识别出来,特别注意我标注的根节点(绿色,如果不是绿色,代表…什么你知道吧),紫色的右子树节点,红色的添加节点和黄色的一般节点,之前我一直强调最外层节点和他的孩子,现在就能看到效果了

根据我们的结论右旋一次:

在这里插入图片描述

然后再左旋一次

在这里插入图片描述

达到平衡,发现什么规律了吗?

=分隔线===

没关系我们换个节点再来一次,再换叶子添加

在这里插入图片描述

再来旋转,一样先右旋

在这里插入图片描述

再左旋:

在这里插入图片描述

我相信你已经发现什么了

添加元素的时候,如果高度超过了平衡树的规则就会旋转,先找到添加节点的最外层节点和最外层节点的子节点,然后旋转两次就可以达到平衡,赶快练习下吧

多思考多练习,思考下删除操作又该如何实现呢?转载请标明出处谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值