Balanced Binary Tree, 简称 AVL 树
- AVL树:每个结点的左、右子树高度之差的绝对值不超过1.
向AVL树中,插入1个新结点,会破坏平衡吗?
- 若新结点不改变“以其父亲为根”的子树的高度
不破坏 - 若新结点增加了“以其父亲为根”的子树的高度
- 若在其某个祖先处,不再向上改变”子树”的高度
不破坏 - 若向上一直改变子树的高度,
且其祖先中有平衡因子>0,
破坏平衡
- 若在其某个祖先处,不再向上改变”子树”的高度
平衡二叉树的调整
定义 被破坏结点:插入新结点后,|BF|>1的结点
RR旋转 (右单旋)
插入的结点在被破坏结点右子树的右子树上
调整方法:令被破坏结点的右子树成为根结点旋转
LL旋转 (左单旋)
插入的结点在被破坏结点的左子树的左子树上
调整方法:令被破坏结点的左子树成为根结点旋转
LR旋转 (左-右双旋)
插入的结点在被破坏结点的左子树的右子树上
调整方法:
如上图,从 ABC 调整为 CBA
RL旋转 (右-左双旋)
插入的结点在被破坏结点的右子树的左子树上
调整方法:
如上图,从 ABC 调整为 CAB
代码
因为没有模版题,所以没有验证代码正确性,仅供参考
struct AVLNode {
int key;
AVLNode *l,*r;
int height;
};
int getHeight(AVLNode *u) {
if (u==NULL) return -1;
else return u->height;
}
//左单旋
AVLNode *LL(AVLNode *A) {
AVLNode *B;
B=A->l;
A->l=B->r;
B->r=A;
A->height=max(getHeight(A->l),getHeight(A->r))+1;
B->height=max(getHeight(B->l),A->height)+1;
return B;
}
//右单旋
AVLNode *RR(AVLNode *A) {
AVLNode *B;
B=A->r;
A->r=B->l;
B->l=A;
A->height=max(getHeight(A->l),getHeight(A->r))+1;
B->height=max(getHeight(B->r),A->height)+1;
return B;
}
//左-右双旋
AVLNode *LR(AVLNode *A) {
A->l=RR(A->l);
return LL(A);
}
//右-左双旋
AVLNode *RL(AVLNode *A) {
A->r=LL(A->r);
return RR(A);
}
AVLNode *Insert(AVLNode *T, int x){
// 若插入空树,则新建包含一个结点的树
if (!T){
T=(AVLNode *)malloc(sizeof(AVLNode));
T->key=x;
T->height=0;
T->l=T->r=NULL;
}
else if (x<T->key){
T->l=Insert(T->l,x);
//如果需要左旋
if (getHeight(T->l)-getHeight(T->r)==2){
if (x<T->l->key) T=LL(T); //左单旋
else T=LR(T); //左-右双旋
}
}
else if (x>T->key){
T->r=Insert(T->r,x);
//如果需要右旋
if (getHeight(T->l)-getHeight(T->r)==-2){
if (x>T->r->key) T=RR(T); //右单旋
else T=RL(T); //右-左双旋
}
}
//更新树高
T->height=max(getHeight(T->l),getHeight(T->r))+1;
return T;
}