AVL树是最早发明的自平衡二叉搜索树之一。
平衡因子(Balance Factor):某结点的左右子树的高度差
AVL树的特点
- 每个结点的平衡因子只可能是1,0,-1(绝对值<=1,如果超过,称之为“失衡”)
- 每个结点的左右子树高度差不超过1
- 搜索,添加,删除的时间复杂度是O(logn)
添加导致的失衡
最坏情况:可能会导致所有祖先结点都失衡,父节点,非祖先结点,都不可能失衡。
如何解决添加导致的失衡?
旋转有LL-右旋转(单旋) RR-左旋转(单旋) LR-RR左旋转,LL右旋转(双旋) RL-LL右旋转,RR左旋转(双旋),可以通过旋转解决具体的添加失衡
LL-右旋转(单旋)
如图n为某个结点,p为n的父节点,g为n的祖父结点,T0,T1是n的子树且高度相等,T2是p的右子树,与左子树n的高度相等,T3是g的右子树,比左子树p的高度少1。(图画的不太好,莫笑!!!)
现在在T0子树下添加一个结点如下图,发现g结点失去平衡,n和p结点没有失去平衡。g结点的平衡因子变成2。
可以通过右旋转恢复平衡,右旋转后仍是一颗二叉搜索树:T0<n<T1<p<T2<g<T3,且树的高度没有改变,整棵树达到平衡。
g.left=p.right
p.right=g//让p成为这颗子树的根结点
注意:还需要维护T2,p,g的parent属性,先后更新g,p的高度。
RR-左旋转(单旋)
如下图,T2子树和T3子树高度相等,T1子树和n子树高度相等,T0子树比p子树高度大1。
现在往T3子树下添加一结点,如下图(图画的确实不好看),g的平衡因子变成-2。
可以通过左旋转来恢复平衡,左旋转后仍然是一颗二叉搜索树:T0<n<T1<p<T2<g<T3,且树的高度没有改变,整棵树达到平衡。
g.right=p.left
p.left=g//让p成为这颗子树的根结点
这里需要注意维护T1,p,g的parent属性,先后更新g,p的高度。
画图太累了,我就不画了,LR(双旋)和RL双旋也是依赖前面两个单旋的基础上的,比较简单,这里不在叙述。