• D&F学数据结构系列——AVL树(平衡二叉树)


    AVL树(带有平衡条件的二叉查找树)

    定义:一棵AVL树是其每个节点的左子树和右子树的高度最多差1的二叉查找树。

    为什么要使用AVL树(即为什么要给二叉查找树增加平衡条件),已经在我之前的博文中说到过http://www.cnblogs.com/sage-blog/p/3864640.html

    AVL树的高度:最大为 1.44log(N+2)-1.328,实际上的高度只比 logN 稍微多一点。

          当进行插入操作时,我们需要更新通向根节点的路径上那些节点的所有平衡信息,而插入操作隐含的困难是插入一个节点可能破坏AVL树的特性,这必须通过对树的修正来做到,我们称其为旋转(rotation)

          在插入以后,只有那些从插入节点到根节点的路径上的节点的平衡可能被改变,因为只有这些节点的子树可能发生变化。当我们沿着这条路径上行到根并更新平衡信息时,我们可以找到一个节点,它更新后的平衡信息破坏了AVL条件。如何在第一个这样的节点重新平衡这棵树?

          设必须重新平衡的节点为X,这种不平衡可能出现在下面四种情况中:

              (1)对X的左儿子的左子树进行一次插入

              (2)对X的左儿子的右子树进行一次插入

              (3)对X的右儿子的左子树进行一次插入

              (4)对X的右儿子的右子树进行一次插入

           情形(1)和(4)关于X点对称,(2)和(3)关于X点对称。可以看做只有两种情况

           第一种情况发生在“外面”(左左,右右):对树进行单旋转(single rotation)

           第二种情况发生在“里面”(左右,右左):对树进行双旋转(double rotation)

    单旋转:

             上图中我们对X结点进行插入新结点操作之前,k2是满足AVL平衡特性的。在X上插入新结点后,k2的左子树比右子树深2层,k2的AVL平衡特性被破坏。为了使树恢复平衡,我们把X上移一层,并把Z下移一层。我们重新安排结点以形成一棵等价的树。抽象的形容就是:把树的形象地看成是柔软灵活的,抓住结点K1,使劲摇两下这棵树,在重力作用下,k1变成了新的根。最后将K1的右儿子Y放到k2左儿子的位置上是满足二叉查找树的性质的。

    ***

    双旋转:

         在图4-34中的子树Y已经有一项插入其中,这个事实保证它是非空的。我们可以假设它有一个根和两棵子树。于是,我们可以把整棵树看成是四棵子树和由三个节点连接。恰好树B或树C中有一棵比D深两层(除非它们都是空的),但是我们不能肯定是哪一棵,但这并不重要,能保证有一棵就行。

           为了让树重新平衡,我们不能再让k3作为根了,而图4-34所示的在k3和k1之间的旋转又解决不了问题,唯一的选择就是把k2用作新的根。这迫使k1是k2的左儿子,k3是k2的右儿子,B是k1的右子树,C是k2的左子树,从而完全确定了这四棵树的最终位置。

    ***

  • 相关阅读:
    iOS开发——高级篇——iOS抽屉效果实现原理
    iOS开发——高级篇——FMDB 数据库简单使用
    iOS开发——高级篇——多线程dispatch_apply
    iOS开发——基础篇——get和post请求的区别
    iOS开发——高级篇——线程同步、线程依赖、线程组
    谈谈程序员最讨厌做的事
    iOS开发——高级篇——iOS 项目的目录结构
    iOS开发——高级篇——Runtime实际应用
    程序猿如何“智斗”产品经理
    iOS开发——基础篇——iOS开发 Xcode8中遇到的问题及改动
  • 原文地址:https://www.cnblogs.com/sage-blog/p/3866008.html
Copyright © 2020-2023  润新知