数据结构与算法-平衡二叉树(AVL树)-思想篇

基本概念

  平衡二叉树(Self-Balancing Binary Search Tree 或 Height-Balanced Binary Search Tree),是一种二叉排序树,其中每一个结点的左子树和右子树的高度差至多等于1。
  我们将二叉树上结点的左子树深度减去右子树深度的值称为平衡因子BF(Balance Factor),那么平衡二叉树上所有结点的平衡因子只可能是-1、0和1。只要二叉树上有一个结点的平衡因子的绝对值大于1,那么该二叉树就是不平衡的。
  距离插入结点最近的,且以平衡因子绝对值大于1的结点为根结点的子树,我们称为最小不平衡树。

实现原理

  平衡二叉树构建的基本思想就是在构建二叉排序树的过程中,每当插入一个结点时,先检查是否因插入而破坏了树的平衡性,若是,则找出最小不平衡子树。在保持二叉排序树特性的前提下,调整最小不平衡子树中个结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。
  关于二叉排序树的创建、插入和删除过程,可参考

图示平衡二叉树构建过程

  • 假设我们现在有一个数组[3,2,1,4,5,6,7,10,9,8]需要构建二叉排序树。在没有学习平衡二叉树之前,根据二叉树的特性,我们会将其构建成图1所示的样子。虽然它完全符合二叉排序树的定义,但是对这样高度达到8的二叉树来说,查找是非常不利的。而图2的平衡二叉树,高度为4,提供了更高效的查找效率。

  • 对于数组的前两位3和2,我们很正常地构建,到了第3个数“1”时,发现此时根结点“3”的平衡因子变成了2,此时整棵树都成了最小不平衡子树,因此需要调整,如图1(结点右上角数字为平衡因子BF值)。因为BF值为正,因此我们将整个树右旋(顺时针旋转),此时结点2成了根结点,3成了2的右孩子,这样三个结点的BF值均为0,非常的平衡,如图2。

  • 然后我们再增加结点4,平衡因子没发生改变,如图3。增加结点5时,结点3的BF值为-2,说明要旋转了。由于BF值是负值,所以我们对这棵最小不平衡子树进行左旋(逆时针旋转),如图4,此时我们整个树又达到了平衡,如图5。

  • 继续增加结点,当增加结点9时,此时结点7的BF变成了-2,理论上我们只需要旋转最小不平衡子树7、9、10即可,但是如果左旋转后,结点9变成了10的右孩子,这是不符合二叉排序树的特性的,此时不能简单地左转,如图11。

  • 仔细观察图11,发现根本原因在于结点7的BF是-2,而结点10的BF是1,两者一正一负,符号不统一,而前面的几次旋转,无论左旋还是右旋,最小不平衡子树的根结点与它的子结点符号都是相同。所以我们先对结点9和结点10进行右旋,使得结点10成了9的右子树,结点9的BF为-1,此时就与结点7的BF值符号统一了,如图12。然后我们再以结点7为最小不平衡子树进行左旋,如图13。


  • 以此类推,最终得到最后的平衡二叉树。

思想总结

  如果我们需要查找的集合本身没有顺序,在频繁查找的同时也需要经常的插入和删除操作,显然我们需要构建一棵二叉排序树,但是不平衡的二叉排序树,查找效率是非常低的,因此我们需要在构建时,就让这棵二叉排序树是平衡二叉树,此时我们的查找时间复杂度就为0(logn),而插入和删除也为O(logn)。这显然是比较理想的一种动态查找表算法。

猜你喜欢

转载自blog.csdn.net/FTD_SL/article/details/86291906