AVL树的C++实现(1)

为什么要AVL
在之前的介绍的二分搜索树中,我们发现它查找、添加、删除元素的复杂度为 O ( l o g n ) O(logn) O(logn)级别,但是在某些特殊情况下,比如在添加1,2,3,4,5,6时,你期望能够添加完成为左边的树,但是如果按顺序添加就会退化成链表,复杂度变为 O ( n ) O(n) O(n)级别。此时这种二叉树就成为一种不平衡二叉树,而AVL树就是解决这种不平衡二叉树一种方法。
在这里插入图片描述
在这里插入图片描述
平衡二叉树从字面上理解就是这棵树要尽量的平衡。但是对于平衡有不同的定义,比如之前说的堆,它是一棵完全二叉树,空缺部分只能出现在右下角,这种平衡二叉树除了最后一层其它层必须是是满二叉树。而AVL中对于平衡二叉树的定义是对于每个节点,它的左右子树高度差不能超过1
在这里插入图片描述
就像这棵树,虽然18节点只有一个叶子节点,但是所有节点的左右子树都是满足高度差不超过1的。此时如果继续往左边添加节点,就会发现不满足上述条件。
在这里插入图片描述
在这里插入图片描述
此时为了判断加入新节点后是否满足上述条件,需要记录每个节点的高度,并且计算左右子树的高度差。假设最底下一层高度为1,如果没有子树则子树高度为0。那么可以得到上述二叉树的高度差,可以发现存在高度差为2的节点,那此时就需要对二叉树进行相应的维护,使其满足平衡二叉树。
在这里插入图片描述
右旋转、左旋转
如果添加的节点处于左侧的左侧,也就是节点一直往左边添加。此时需要采用右旋转对二叉树进行维护。假设在添加元素 z z z时各子树如图所示,各子树与x,y,z的关系如图所示。在进行右旋转时,另 x . r i g h t = y x.right=y x.right=y, y . l e f t = T 3 y.left=T3 y.left=T3,经过旋转后仍然满足二叉搜索树的条件。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面证明此二叉树满足平衡二叉树的条件。因为在加入z节点后才y才出现不平衡情况,那么x,z是平衡的。假设 m a x H e i g h t ( T 1 , T 2 ) = h maxHeight(T1,T2)=h maxHeight(T1,T2)=h,那 h e i g h t ( z ) = h + 1 height(z)=h+1 height(z)=h+1,因为x节点也是平衡的且 0 < = h e i g h t ( x . l e f t , x . r i g h t ) < = 1 0<=height(x.left,x.right)<=1 0<=height(x.left,x.right)<=1,那么 h e i g h t ( T 3 ) = h + 1 或 h height(T3)=h+1或h height(T3)=h+1h。因为节点y左右子树不平衡,所以节点y处的高度差为2,从而 h e i g h t ( T 4 ) = h height(T4)=h height(T4)=h。那么经过右旋转后的高度如右图所示,因为高度差改变的只有y和x节点,所以只需要计算y和x的节点即可。 h e i g h t ( y ) = h + 1 或 h + 2 height(y)=h+1或h+2 height(y)=h+1h+2, h e i g h t ( z ) = h + 1 height(z)=h+1 height(z)=h+1,所以x的高度差是不超过1的,满足AVL平衡二叉树的条件。(这段推理有点麻烦,大家用笔自己算下就可以了)。
在这里插入图片描述
理解了右旋转,那么左旋转也很好理解了。就是在添加元素时一直添加在右子树,通过左旋转就可以维护平衡。
在这里插入图片描述
在这里插入图片描述
感觉东西有点多,就先到这里,剩下的内容和编码实现在下一篇更新了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值