在向大家介绍AVL树之前,我们先来看一下二叉搜索树的缺点。
BST的高度受输入顺序影响会有比较大的波动。
最好的高度为O(log n):
最坏的高度为O(n):
这样不稳定的结构不是我们想要的数据结构,我们应当追求一种比较稳定比较平衡的结构。
从上图的分析可以看出,并不是这种结构本身存在问题,
而是我们在构造这棵二叉搜索树的时候如果稍加控制即可把高度控制在O(log n)。
怎样使得BST始终保持O(log n)级的平衡状态?
Adelson-Velskii和Landis发明了AVL树。
○AVL树是一种平衡的二叉搜索树。
○任何结点的左子树和右子树高度最多相差1。
先来简单介绍一下AVL树的性质与结构特点:
1.AVL树可以为空。
2.具有n个结点的AVL树,高度为O(log n)
3.如果T是一棵AVL树,那么它的左右子树TL、TR也是AVL树,并且| hL-hR|≤1(hL、hR 是它的左右子树的高度)
为了便于了解当前二叉搜索树的平衡情况,我们引入了平衡因子的概念:
平衡因子,用bf(x)来表示结点x的平衡因子。
它被定义为:bf(x)= x的右子树的高度 – x的左子树的高度
对于一个AVL树中的结点平衡因子之可能取值为0,1和-1,这样才满足AVL树的结构特性。
下面来介绍一下AVL树的基本操作。
首先是AVL树结点的插入:
插入与BST一样,新结点作叶结点。但是需要一定的调整才行。
相应子树的根结点变化大致有三类
○结点原来是平衡的,现在成为左重或右重的:修改相应前驱结点的平衡因子。
○结点原来是某一边重的,而现在成为平衡的了:树的高度未变,不修改。
○结点原来就是左重或右重的,而新结点又加到重的一边:不平衡,属于“危急结点”,需要调整。
下面来举个栗子解释如何使二叉搜索树恢复平衡。
接下来介绍一下AVL树结构调整,具体分为以下四类:
○左单旋转
○右单旋转
○先左后右旋转
○先右后左旋转
下面来总结一下AVL树的插入:
向一棵高度平衡的AVL树中插入一个新结点时,
如果树中某个结点的平衡因子的绝对值|balance|>1,则出现了不平衡,
需要做平衡化处理。
下面继续介绍一下AVL搜索树的删除操作。
为了恢复删除后的A节点平衡,我们需要确定其不平衡类型。
如果删除发生在左子树,那么不平衡就是L型。
如果删除发生在右子树,那么不平衡就是R型。
对于R型不平衡,我们具体可以将删除操作归纳为以下三种:
○R0类型的旋转
○R1类型的旋转
○R-1类型的旋转