AVL Trees 学习笔记
AVL Trees 是一种特殊的二叉搜索树,它的作用是通过自我调整,让整棵树保持平衡,从而降低整棵树的高度,以提高查找效率。
本文将首先介绍AVL Trees,然后介绍它的实现方法,性能评估,最后分析题目。
Introduction
特点
通过自我调整使树趋于平衡,降低树的高度,提高搜索效率
本质
二叉搜索树
变化
相比于二叉搜索树,有两个变化,一是每个节点增加了BF属性用于存储左子树和右子树的高度差,二是每次增加或删除节点后都会进行调整,使之balance
实现
结构
增加了BF属性的二叉搜索树
typedef struct node* tree;
struct node{
element key;
tree left;
tree right;
int BF;
}
BF = height of left tree - height of right tree
通过判断每个节点的BF值判断树是否height balanced. 若失去平衡,则开始调整。
Height Balanced
An empty binary tree is height balanced. If T is a nonempty binary tree with TL and TR as its left and right subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
(2) | hL - hR | < 1 where hL and hR are the heights of TL and TR , respectively.
调整触发条件
- 更新BF值
- 从增加或删除节点的位置开始向上遍历,访问BF值
- 若有BF< -1 || BF > 1 调整该节点及其子树
若一直到根节点BF都正常则无需调整 - 调整完成,更新BF值
调整
共有 RR, LL, RL, LR 四种情况
RR
需要注意的是,矩形(如BL,BR, AL)表示的不是一个节点,而是表示一棵子树,A表示的不一定是root,而是一个Trouble Maker节点。
LL
LL情况与RR相似,它们是对称的。它们的共同点是,都是在从 Trouble Maker节点 到 其子节点 到 子节点的子树 这条路径上,旋转一次。
LR
LR和RL的情况就要稍微复杂,需要进行两次旋转。
这次旋转中事实上包括了两次旋转,首先是B, C, C的子树路径上进行一次左旋转:
然后是A, C, B路径上的第二次旋转:
RL
RL的情况与LR情况相似
性能评估
每次操作需要遍历从最底端到root的各个节点,时间复杂度为O(h),调整操作时间复杂度为O(1)。故每次操作时间复杂度为O(h)。
又 h = O(lnN)
故操作时间复杂度为O(lnN)
证明 h = O(lnN)
记一个高度为h的树,节点数为nh
一棵高度为h,节点数最少的树是这样的形式:由此我们可以得出nh = nh-1 + nh-2 + 1
令Fi = nh + 1
有Fi = Fi-1 + Fi-2
我们可以发现 Fi 符合斐波那契数列,且通过将h=1, h=2, h=3 代入,我们可以得出i = h+2
即 nh+2 - 1 符合斐波那契数列
根据斐波那契数列的理论