代码如下
public class AVLTree<T extends Comparable<? super T>> {
private AVLNode<T> root;
/**
* 插入
* @param t 待插入的元素 不可为空
*/
public void insert(T t) {
root = insert_0(root,t);
}
private AVLNode<T> insert_0(AVLNode<T> currRoot , T value){
if(currRoot==null)return new AVLNode<>(value,null,null);
if(value.compareTo(currRoot.value)<0){
currRoot.left = insert_0(currRoot.left,value);
}else if(value.compareTo(currRoot.value)>0){
currRoot.right = insert_0(currRoot.right,value);
}
//更新高度
currRoot.height = Math.max(height(currRoot.left),height(currRoot.right)) + 1;
//平衡本节点子树
currRoot = balance(currRoot);
return currRoot;
}
/**
* 平衡一个节点子树
* @param currRoot
* @return
*/
private AVLNode<T> balance(AVLNode<T> currRoot ){
if(isUnbalance(currRoot))return currRoot;
else {
if(height(currRoot.left)>height(currRoot.right)){
if(height(currRoot.left.left)>=height(currRoot.left.right)){//左左,这里用大于等于,是为了在删除后的平衡操作中,兼容 两个一样高的子树,插入不会导致两个一样超高的子树,但删除却会
currRoot = rotateLeftLeft(currRoot);
}
if(height(currRoot.left.right)>height(currRoot.left.left)) {//左右
currRoot = rotateLeftRight(currRoot);
}
}else{
if(height(currRoot.right.right)>=height(currRoot.right.left)){//右右
currRoot = rotateRightRight(currRoot);
}
if(height(currRoot.right.left)>height(currRoot.right.right)) {//右左
currRoot = rotateRightLeft(currRoot);
}
}
}
//发生平衡后,更新高度
refreshHeight(currRoot);
return currRoot;
}
/**
* 左左单选转
* @param currRoot
* @return
*/
private AVLNode<T> rotateLeftLeft(AVLNode<T> currRoot){
AVLNode<T> left = currRoot.left;
AVLNode<T> leftRight = left.right;
left.right = currRoot;
currRoot.left=leftRight;
return left;
}
/**
* 左右双旋转(可通过先对左节点进行右旋转,再对本节点进行左旋转完成。但本处没有这么做)
* @param currRoot
* @return
*/
private AVLNode<T> rotateLeftRight(AVLNode<T> currRoot){
AVLNode<T> left = currRoot.left;
AVLNode<T> leftLeft = left.left;
AVLNode<T> leftRight = left.right;
AVLNode<T> leftRightLeft = leftRight.left;
AVLNode<T> leftRightRight = leftRight.right;
left.right = leftRightLeft;
currRoot.left = leftRightRight;
leftRight.left = left;
leftRight.right = currRoot;
return leftRight;
}
/**
* 右右单旋转
* @param currRoot
* @return
*/
private AVLNode<T> rotateRightRight(AVLNode<T> currRoot){
AVLNode<T> right = currRoot.right;
AVLNode<T> rightLeft = right.left;
right.left = currRoot;
currRoot.right=rightLeft;
return right;
}
/**
* 右左双旋转
* @param currRoot
* @return
*/
private AVLNode<T> rotateRightLeft(AVLNode<T> currRoot){
AVLNode<T> right = currRoot.right;
AVLNode<T> rightRight = right.right;
AVLNode<T> rightLeft = right.left;
AVLNode<T> rightLeftRight = rightLeft.right;
AVLNode<T> rightLeftLeft = rightLeft.left;
right.left = rightLeftRight;
currRoot.right = rightLeftLeft;
rightLeft.right = right;
rightLeft.left = currRoot;
return rightLeft;
}
/**
* 节点是否不平衡
* @param currRoot
* @return
*/
private boolean isUnbalance(AVLNode<T> currRoot) {
return Math.abs(height(currRoot.left) - height(currRoot.right))<=1;
}
/**
* 计算高度
* @param node
* @return
*/
private int height(AVLNode<?> node){
return AVLNode.height(node);
}
/**
* 更新高度
* @param node
* @return
*/
private int refreshHeight(AVLNode<?> node){
if(node==null)return -1;
int leftH = refreshHeight(node.left);
int rightH = refreshHeight(node.right);
node.height = Math.max(leftH,rightH)+1;
return node.height;
}
private static class AVLNode<E extends Comparable<? super E>>{
E value;
AVLNode<E> left;
AVLNode<E> right;
int height;
AVLNode(E value , AVLNode<E> left , AVLNode<E> right){
this.value = value;
this.left = left;
this.right = right;
height = 0;
}
static int height(AVLNode<?> node){
return node==null?-1:node.height;
}
}
}