AVL树是带有平衡条件的二叉查找树。一颗AVL树是其每个结点的左子树和右子树的高度最多相差1。
进行插入操作时,怎么样把插入后的树调整成AVL树。.
将影响平衡因子的结点为a
四种情况
1.对a的左儿子的左子树插入
2.对a的右儿子的右子树插入
3.对a的左儿子的右子树插入
4.对a的右儿子的左子树插入
1和2两种情况都是单选择,将a结点向下移,它的儿子向上移
3和4是双旋转, 左右旋转的话,就是,左子树进行youyou旋转,然后总体在zuozuo旋转。
private int height(AvlNode t){
return t==null ? 0 : t.height;
}
//avl树的高度
//插入
private AvlNode insert(int x, AvlNode t){
if(t==null)
rerurn new AvlNode(x,null,null);
int a=x.compareTo(t.element);
//比较元素大小
if(a>0)
t.right=insert(x,t.right);
else if(a<0)
t.left=insert(x,t.left);
esle
;//啥也不用做
return balance(t);
}
private static final int A = 1;//当做一个常量 拿来比较高度
private AvlNode balance(AvlNode t){
if(t==null)
return t;
if(height(t.left)-height(t.right)>A){ //插入元素到左孩子还是右孩子
if( height(t.left.left)>=height(t.left.right) )
//单选择,左左
t=zuozuo(t);
else
t=zuoyou(t);
}else{
if( height(t.right.right)>=height(t.right.left) )
t=youyou(t);
else
t=youzuo(t);
}
t.height=Math.max( height(t.left) , height(t.right) ) +1;
return t;
}
private AvlNode zuozuo( AvlNode t)
{
AvlNode t1=t.left;
t.left=t1.right;
t1.right=t;
t.height=Math.max( height(t.left) , height(t.right)) + 1;
t1.height=Math.max( height(t1.left), t.height ) + 1;
return t1;
}
//youyou和这个差不多
private AvlNode youyou(AvlNode t){
AvlNode t1 = t.right;
t.right = t1.left;
t1.left = t;
t.height=Math.max( height(t.left) , height(t.right)) + 1;
t1.height=Math.max( height(t1.left), t.height ) + 1;
return t1;
}
private AvlNode zuoyou(AvlNode t)
{
t.left=youyou(t.left);
t=zuozuo(t);
return t;
}
AVL树的删除
private AvlNode remove(int x, AvlNode t)
{
if(t==null)
return t;
int a=x.compareTo(t.element);
if(a<0)
t.left=remove(x, t.left);
else if(a>0)
t.right=remove(x, t.right);
else{
if(t.left!=null && t.right!=null)
t.element=findMin(t.right).element;
t.right=remove(t.element, t.right);
else
t=(t.left!=null) ? t.left : t.right;
// 它return到了新的t了,因为递归实现,之前原来的父亲指到了这个t.
return balance(t);
}