平衡二叉树 (Balanced Binary Tree) (AVL树) :
空树,或者任一结点左、右子树高度差的绝对值不超过1
typedef struct avl_tree* tree;
struct avl_tree{
tree left; //指向左子树
tree right; //指向右子树
elementtype data; //结点数据
int height; //树高
};
int max(int a, int b)
{
return a > b ? a : b;
}
tree left_rotation(tree a){ //左单旋
/* 注意:a必须有一个左子结点b */
/* 将a与b做左单旋,更新a与b的高度,返回新的根结点b */
tree b=a->left;
a->left=b->right;
b->right=a;
a->height=max(a->left->height,a->right->height)+1;
b->height=max(b->left->height,b->right->height)+1;
return b;
}
tree right_rotation(tree a){ //右单旋
/* 把left,right对换即可 */
tree b=a->right;
a->right=b->left;
b->left=a;
a->height=max(a->left->height,a->right->height)+1;
b->height=max(b->left->height,b->right->height)+1;
return b;
}
tree left_right_rotation(tree a){ //左-右双旋
/* 注意:a必须有一个左子结点b,且b必须有一个右子结点c */
/* 将a、b与c做两次单旋,返回新的根结点c */
a->left=right_rotation(a->left); //将B与C做右单旋,C被返回
return left_rotation(a); //将A与C做左单旋,C被返回
}
tree right_left_rotation(tree a){ //右-左双旋
/* 同理,把left,right对换即可 */
a->right=left_rotation(a->right);
return right_rotation(a);
}
/* 如果不使用递归,将会使程序变得非常复杂,比如:
插入时需要判断在left还是right,插入后还需要判断是否仍是平衡二叉树,
而判断又需求树高,除此之外,还需要记录“麻烦节点”和“发现者”,因此下面采用递归实现:*/
tree insert(elementtype x,tree bt){
if (!bt){ //若插入空树,则新建包含一个结点的树
bt=(tree)malloc(sizeof(struct avl_tree));
bt->height=0;
bt->left=bt->right=NULL;
bt->data=x;
return bt; //插入空树结束
}
else if (x < bt->data){
bt->left=insert(x,bt->left); //插入bt的左子树
if (bt->left->height - bt->right->height == 2){ //如果需要左旋
if (x < bt->left->data) bt=left_rotation(bt); //左单旋
else bt=bt->left_right_rotation(bt); //左-右双旋
}
}
else if (x > bt->data){ //插入bt的右子树
bt->right=insert(bt->right);
if (bt->right->height - bt->left->height == 2){ //如果需要右旋
if (x > bt->right->data) bt=right_rotation(bt); //右单旋
else bt=right_left_rotation(T); //右-左双旋
}
}
//else x==bt->data,无须操作
bt->height=max(bt->left,bt->right)+1; //更新树高
return bt;
}
}