【转】平衡二叉树(AVL)

平衡二叉树的定义 (AVL—— 发明者为Adel'son-Vel'skii 和 Landis)

平衡二叉查找树(AVL树),具备二叉查找树的特点外,还具有一个重要特点: 它的左子树和右子树都是平衡二叉树,并且左子树和右子树的平衡因子不超过1 (也就是每个节点的平衡因子只能是1,0,-1)

什么是平衡因子?

节点的左子树和右子树高度(深度)的差值

平衡二叉树是如何在插入数据的时候保持平衡的

当插入一个结点的时候,先检查是否因为插入结点而破坏了平衡,若破坏,找出其中的最小不平衡二叉树,调整最小不平衡二叉树,达到平衡。 最小不平衡二叉树指的是离插入结点最近并且平衡因子的绝对值大于1的结点为根的子树。

平衡二叉树的操作

查找操作

       平衡二叉树的查找基本与二叉查找树相同。

插入操作

       在平衡二叉树中插入结点与二叉查找树最大的不同在于要随时保证插入后整棵二叉树是平衡的。那么调整不平衡树的基本方法就是: 旋转 。 下面我们归纳一下平衡旋转的4中情况

1> 绕某元素左旋

         

从图上看,以结点80和结点90为杠杆,左旋

插入结点100后,结点80的平衡因子改变为-2,也就是当结点的平衡因子变为-2,需要按照结点左旋

当树中节点X的右孩子的右孩子上插入新元素,且平衡因子从-1变成-2后,就需要绕节点X进行左旋

2> 绕某元素右旋

从图上看,是结点100和结点85为杠杆,右旋

插入结点80后,结点100的平衡因子改变为2,当结点的平衡因子改变为2时候,进行右旋操作

当树中节点X的左孩子的左孩子上插入新元素,且平衡因子从1变成2后,就需要绕节点X进行右旋

3> 按照某元素的左子结点左旋转,在按照元素自己右旋转

当结点X的左孩子Y的右孩子插入新元素,平衡因子由1变为2,需按照Y左旋转,在按照X结点右旋转

4> 按照某元素的右子结点旋转,在按照元素自身左旋转

当结点X的右孩子Y的左孩子插入结点,X的平衡因子由-1变为-2,需要按照Y结点右旋转,再按照X结点自身左旋

平衡二叉树性能分析

平衡二叉树的性能优势:

      很显然,平衡二叉树的优势在于不会出现普通二叉查找树的最差情况。其查找的时间复杂度为O(logN)。

平衡二叉树的缺陷:

      (1) 很遗憾的是,为了保证高度平衡,动态插入和删除的代价也随之增加。因此,我们在下一专题中讲讲《红黑树》 这种更加高效的查找结构。

      (2) 所有二叉查找树结构的查找代价都与树高是紧密相关的,能否通过减少树高来进一步降低查找代价呢。我们可以通过多路查找树的结构来做到这一点,在后面专题中我们将通过《多路查找树/B-树/B+树 》来介绍。

      (3) 在大数据量查找环境下(比如说系统磁盘里的文件目录,数据库中的记录查询 等),所有的二叉查找树结构(BST、AVL、RBT)都不合适。如此大规模的数据量(几G数据),全部组织成平衡二叉树放在内存中是不可能做到的。那么把这棵树放在磁盘中吧。问题就来了:假如构造的平衡二叉树深度有1W层。那么从根节点出发到叶子节点很可能就需要1W次的硬盘IO读写。大家都知道,硬盘的机械部件读写数据的速度远远赶不上纯电子媒体的内存。 查找效率在IO读写过程中将会付出巨大的代价。在大规模数据查询这样一个实际应用背景下,平衡二叉树的效率就很成问题了。对这一问题的解决:我们也会在《多路查找树/B-树/B+树 》 将详细分析。

      上面提到的红黑树和多路查找树都是属于深度有界查找树(depth-bounded tree —DBT)

转载:http://hxraid.iteye.com/blog/609949

猜你喜欢

转载自blog.csdn.net/Ditto_zhou/article/details/83309910