平衡二叉树AVL的实现(递归及非递归)

转载于https://www.cnblogs.com/leihui/p/6002418.html

这篇文章用来复习AVL的平衡操作,分别会介绍其旋转操作的递归与非递归实现,但是最终带有插入示例的版本会以递归呈现

下面这张图绘制了需要旋转操作的8种情况。(我要给做这张图的兄弟一个赞)后面会给出这八种情况对应平衡实现。

[1]


情况1-2:

  这种需要旋转的结构一般称之为为LL型,需要右旋(顺时针旋转)。

  我用一个图来抽象一下这两个情况,画的不好,我尽量表达吧。

  

  此时需要对一个进行平衡操作,方法为:

  1.     将甲的左子树换为乙的右子树。
  2.   乙的右子树换为A.
  •   非递归实现的代码为:

复制代码

 
 

复制代码

  非递归的操作在旋转前会充分考虑所有的旋转情况,目的是提早调整甲下面各节点的高度。

  之后再进行旋转操作,这一点与递归的不同,可见递归是平衡完后再进行的高度调整。

  •   递归实现代码为:

复制代码

 
 

复制代码

情况3-4:

  这种需要旋转的结构一般称之为RR型,需要左旋(逆时针旋转)。

  需要对一个进行平衡操作,方法为:

  1.   将甲的右子树换为乙的左子树;
  2.   乙的左子树换为甲

  

  •   非递归的实现为:

复制代码





复制代码

  •   递归实现为:

复制代码

 
 

复制代码

情况5-6: 

  这种需要旋转的结构一般称之为LR型,需要双旋转,即两次单旋。分别为左旋和右旋。

  需要对一个进行平衡操作,方法为:

  1.   对B(A->左)做左旋
  2.   对一个做右旋

  这个递归与非递归的方式都是一样的。

  •   非递归:
 
  
 
  •   递归:
 
  
 

  但是有没有一次性到位的方法呢?有的

  我把非递归的两个函数展开:

  发现最后一步都是确定与父节点的关系,并不是旋转中的具体过程,于是可以简化为这样:

复制代码







复制代码

情况7-8:

  这种需要旋转的结构一般称之为RL型,需要双旋转,即两次单旋。分别为右旋和左旋。

  需要对一个进行平衡操作,方法为:

  1.   对乙进行右旋
  2.   对一个进行左旋

  同样,递归与非递归版本是一样的。

  •   非递归:
 
  
 
  •   递归:
 
  
  
 

  同样,也有一次性到位的方法:

复制代码







复制代码


下面是实现部分:

0.结构声明 [2]

复制代码


复制代码

1.类中提供的API

复制代码






    









复制代码

2.获取高度:
  因为在MAX()函数获取结束后需要1,所以这里的目的是将叶节点的高度想办法为0。

 
  
  
 

3.插入操作:

  •   递归

  通过回溯的方式找到插入的位置,先平衡后调整高度;

  哈哈,有一个很有趣的细节为什么同时判断高度差一个是

  if(getHeight(_T-> left) - getHeight(_T-> right)== 2)

  而另一个是

  if(getHeight(_T-> right) - getHeight(_T-> left)== 2)

  因为这里已经知道了插入发生在哪边了,所以肯定是插入的那边会有破坏平衡的可能,不会造成尴尬的(小 - 大)的局面。

复制代码


    

复制代码

  

  •   非递归[3]:

  可以发现,非递归的实现是先调整高度再平衡,但是要提前考虑所有情况。

  考虑左子树的情况:

复制代码

        
        

复制代码

   考虑右子树的情况:

复制代码

 
 

复制代码

 总结:

  递归真是神奇啊,对子树的处理递归的很漂亮,代码量是一方面,代码逻辑的清晰性也是非递归程序鲜有的。

  用这个来学习递归算法真是好工具,希望对于我后面复习图论有帮助。

  这篇文章中所述的非递归程序我并没有实现,肯定有疏忽的地方,欢迎大家指正。

完整示例中还有一个showThisTree(),它可以打印出漂亮的平衡二叉树。

代码相关请见我的github上

[1]    AVL树的旋转操作图解最详细

[2]左等价leftChild,同理,右也等价rightChild。

[3]    平衡二叉树(AVL)的插入和删除详解(上)

[4]参考教材  数据结构与算法分析:C语言描述(原书第2版)[美] MarkAllenWeiss着

猜你喜欢

转载自blog.csdn.net/weixin_41265887/article/details/84575516