1,介绍—->来自百度
2,AVL的旋转
AVL树的基本操作一般涉及运做同在不平衡的二叉查找树所运做的同样的算法。但是要进行预先或随后做一次或多次所谓的”AVL旋转”。
假设由于在二叉排序树上插入结点而失去平衡的最小子树根结点的指针为a(即a是离插入点最近,且平衡因子绝对值超过1的祖先结点),则失去平衡后进行进行的规律可归纳为下列四种情况:
AVL在插入和删除节点造成不平衡的时候需要对发生不平衡的节点及时调整,调整方法为旋转操作。根据造成不平衡的节点出构型可分为:LL 、RR 、LR 、RL型,对应的操作则为单旋和双旋,
下图所示为LL构型,在B节点的左子树上插入节点导致A节点失衡,调整过程为:以B节点为轴心,A节点顺时针旋转至B的右子树,A的右子树又B的右子树代替。通过右旋操作,返回以B为Root的平衡子树。 RR够型和LL够型成对称关系,操作方向相反,此处就省略了。
2.1 LL型
2.2 RR型
下图所示为LR构型,在B节点的右子树上插入新节点导致A节点失衡,调整过程分两个步骤:首先以C为轴心,B绕C逆时针旋转,生成的子树作为A的左子树;这样就变化成了LL型,然后用上图所示的方法调整即可。通过先左旋后右旋,返回以C为Root的平衡子树。RL型和LR型呈对称状,此处也省略。
2.3 LR型
2.4 RL型
RL型和上面的LR刚好相反
源码片段:
节点定如下:这是内部类
static class Entry<E>
{
E element;
Entry<E> parent;
Entry<E> left;
Entry<E> right;
int balance = EH; //平衡因子,只能为1或0或-1
public Entry(E element,Entry<E> parent)
{
this.element = element;
this.parent = parent;
}
private Entry(){}
@Override
public String toString() {
return element+" BF="+balance;
}
}
基本定义
private static final int LH = 1; //左高
private static final int EH = 0; //等高
private static final int RH = -1; //右高
左旋
private void rotateLeft(Entry<E> p)
{
System.out.println("绕"+p.element+"左旋");
if(p!=null){
Entry<E> r = p.right;
p.right = r.left; //把p右子树的左节点嫁接到p的右节点,如上图,把BL作为A的右子节点
if (r.left != null)
{//如果B的左节点BL不为空,把BL的父节点设为A
r.left.parent = p;
}
r.parent = p.parent; //A的父节点设为B的父节点
if (p.parent == null) //如果p是根节点
{
root = r; //r变为父节点,即B为父节点
}
else if (p.parent.left == p) //如果p是左子节点
{
p.parent.left = r; //p的父节点的左子树为r
}
else
{ //如果p是右子节点
p.parent.right = r; //p的父节点的右子树为r
}
r.left = p; //p变为r的左子树,即A为B的左子树
p.parent = r; //同时更改p的父节点为r,即A的父节点为B
}
}
右旋
private void rotateRight(Entry<E> p)
{
System.out.println("绕"+p.element+"右旋");
if(p!=null){
Entry<E> l = p.left;
p.left = l.right; //把B的右节点BR作为A的左节点
if (l.right != null) //如果BR不为null,设置BR的父节点为A
{
l.right.parent = p;
}
l.parent = p.parent; //A的父节点赋给B的父节点
if (p.parent == null) //如果p是根节点
{
root = l; //B为根节点
}
else if (p.parent.right == p) //如果A是其父节点的左子节点
{
p.parent.right = l; //B为A的父节点的左子树
}
else //如果A是其父节点的右子节点
{ p.parent.left = l; //B为A的父节点的右子树
}
l.right = p; //A为B的右子树
p.parent = l; //设置A的父节点为B
}
}