1概念
平衡二叉树(Balanced Binary Tree或Height-Balanced Tree)又称AVL树(根据它的发明者G.M.Adelson-Velsky和E.M.Landis命名的)。它或者是一棵空树,或者是具有下列性质的二叉树:它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1.
若将二叉树上结点的平衡因子BF(Balance Factor)定义为该结点的左子树的深度减去它的右子树的深度,则平衡二叉树上所有结点的平衡因子只可能是-1,0和1.
只要二叉树上有一个结点的平衡因子的绝对值大于1,则该二叉树就是不平衡的。
2旋转
由一个正序序列{1,2,3,4,5,6,7,8}构成一个二叉搜索树时,如图2所示,它将退化为链表,使得查找时出现最坏的情况——时间复杂度为O(n)。故而希望使由无序序列构成的二叉搜索树成为平衡二叉树。因为AVL树上任何结点的左右子树的深度之差都不超过1,即它的深度和logn是同数量级的,因此它的平均查找长度也和logn同数量级。
一般来说,在AVL树中进行插入或删除结点后,可能导致AVL树失去平衡。失去平衡的AVL树可以概括为4种类型:LL型、LR型、RR型和RL型。
(1)LL型(Left-Left型),在左子树的左边结点进行插入
在左子树的左边结点插入结点1之后,使得结点3失去平衡,这种就是失衡的LL型,可通过单向右旋平衡处理:让s变成根结点,s的右子树变成p的左子树,p变成s的右子树。
/*二叉搜索树结点*/
typedef struct bst_node
{
int data;
int bf;/*结点的平衡因子*/
struct bst_node *lchild;
struct bst_node *rchild;
}bst_node_t, bst_tree_t;
/*右旋平衡处理: 对以p为根的二叉搜索树作右旋处理,处理后p指向新的树根结点*/
void r_rotate(bst_tree_t **p)
{
bst_tree_t *s;
s = (*p)->lchild; /*s为p的左子树根结点*/
(*p)->lchild = s->rchild; /*s的右子树作为p的左子树*/
s->rchild = *p; /*p作为s的右子树*/
*p = s; /*s作为根结点,p指向新的根结点*/
}
(2)RR型(Right-Right型),在右子树的右边结点插入
在右子树的右边结点插入结点5之后,使得结点3失去平衡,这种就是失衡的RR型,可通过单向左旋平衡处理:让s变成根结点,s的左子树变成p的右子树,p变成s的左子树。
/*左旋平衡处理:对以p为根结点的二叉搜索树作左旋处理,处理后,p指向新的根结点*/
void l_rotate(bst_tree_t **p)
{
bst_tree_t *s;
s = (*p)->rchild; /*s为p的右子树根结点*/
(*p)->rchild = s->lchild;/*s的左子树作为p的右子树*/
s->lchild = *p; /*p作为s的左子树*/
*p = s; /*s作为根结点,p指向新的根结点*/
}
(3)LR型(Left-Right型),在左子树的右边结点插入
在左子树的右边结点插入结点3之后,使得结点5失去平衡,这种就是失衡的LR型。对这种情况,先作左旋处理,再作右旋处理。
(4)RL型(Right-Left型),在右子树的左边结点插入