AVL树:为了解决二叉查找树的高度过高问题。比如1,2,3,4,5,6找起来还没有数组快,就体现不出它的优势,AVL树实际是对他的一个优化。
特点:高度相差不超过1.
判断高度?
//高度
public int height(){
return Math.max(left==null?0:left.height(),right==null?0:right.height())+1;
}
如何进行左旋?
- 创建一个新节点,值等于当前根节点的值; Node newNode=new Node(value);
- 把新节点的左子树设置成当前节点的左子树; newNode.left=this.left;
- 把新节点的右子树设置成当前节点右子树的左子树; newNode.right=this.right.left
- 把当前节点的值换为右子结点的值;this.value=this.right.value;
- 把当前节点的右子树设置为右子树的右子树; this.right=this.right.right;
- 把当前节点的左子树设置为新节点; this.left=newLeft;
如何进行右旋?
- 创建一个新节点,值等于当前根节点的值;
- 新节点的右子树设置为当前节点的右子树;
- 新节点的左子树设置为当前节点的左子树的右子树;
- 把当前节点的值换为左子树节点的值。
- 把当前节点的左子树设置为当前节点左子树的左子树;
- 把当前节点的右子树设置为新的结点;
//右旋
public void rightRotate(){
Node newNode=new Node(value);
newNode.right=this.right;
newNode.left=this.left.right;
this.value=this.left.value;
this.left=this.left.left;
this.right=newNode;
}
双旋树:
比如这个,左子树的右子树高度大于左子树高度,就需要先对当前节点的左子树进行左旋,调整后再对当前右旋(不这样的话,直接左旋,右旋就会陷入循环,却永远达不到平衡)
//右边高于左边,左旋
if(rightHeight()-leftHeight()>1)
{
if(this.right!=null&&this.right.leftHeight()>this.right.rightHeight()){
this.right.rightRotate();
leftRotate();
}else{
leftRotate();
}
}
if(leftHeight()-rightHeight()>1)
{
//如果左子树的右子树高度大于左子树
if(this.left!=null&&this.left.rightHeight()>this.left.leftHeight())
{
this.left.leftRotate();
rightRotate();
}else{
rightRotate();
}
}
}