AVL树:是带有平衡条件的二叉查找树,且左右子节点的树深度相差不超过1;在插入元素的时候可能会破坏原来AVL树的平衡,此时就需要通过旋转来解决平衡问题.在插入以后,只有那些从插入点到根节点的路径上的节点的平衡可能被破坏,因为只有这些节点的子树可能发生变化.所以当我们沿着这条路径上行并更新平衡信息时,可以发现一个节点,它的平衡破坏了AVL条件.此时将第一个这样的节点称为α,插入情况如下:
①.对α的左儿子的左子树进行一次插入(单旋转)
②.对α的左儿子的右子树进行一次插入(双旋转)
③.对α的右儿子的左子树进行一次插入(双旋转)
④.对α的右儿子的右字数进行一次插入(单旋转)
单旋转:
k2为从插入的节点往上寻找,满足第一个左右子树不平衡的节点,k1,为其对应的子节点(左节点或者右节点);旋转过程可以认为拎着k1抖,然后左右的重量就相仿了,达到了平衡的条件.
/**
*
* 2016-3-13
* @author sima
* @param <T>
*/
public class AVLTree<T extends Comparable<T>> {
private static class AVLNode<T>{
@SuppressWarnings("unused")
public AVLNode(T element) {
this(element, null, null);
}
public AVLNode(T ele,AVLNode<T> left,AVLNode<T> right) {
this.element = ele;
this.left = left;
this.right = right;
this.length = 0 ;
}
T element;
AVLNode<T> left;
AVLNode<T> right;
int length;
}
private int length(AVLNode<T> node){
return node == null ? -1 : node.length;
}
private AVLNode<T> insert(T ele,AVLNode<T> tree){
if(tree == null)
return new AVLNode<T>(ele, null, null);
int compareResult = ele.compareTo(tree.element);
if(compareResult < 0){
tree.left = insert(ele, tree.left);
if(length(tree.left) - length(tree.right) == 2)
if( ele.compareTo(tree.element) < 0)
tree = rotateWithLeftChild(tree);// 该节点是插入到左节点的左子树上,所以单旋转即可完成调整,
else
tree = doubleWithLeftChild(tree);
}else if(compareResult > 0){
tree.right = insert(ele, tree.right);
if(length(tree.right) - length(tree.left) == 2)
if(ele.compareTo(tree.element) > 0)
tree = rotateWithRightChild(tree);
else
tree = doubleWithRightChild(tree);
}else
;
tree.length = Math.max(tree.right.length, tree.left.length) + 1;
return tree;
}
private AVLNode<T> doubleWithRightChild(AVLNode<T> k3) {
// TODO Auto-generated method stub
return null;
}
/**
* 在右子树插入右节点的时候单旋转...
* rotateWithRightChild
* @param tree
*/
private AVLNode<T> rotateWithRightChild(AVLNode<T> k2) {
AVLNode<T> k1 = k2.right;
k2.right = k1.left;
k1.left = k2;
k2.length = Math.max(k2.left.length, k2.right.length) + 1;
k1.length = Math.max(k2.length, k1.left.length) + 1;
return k1;
}
/**
* 双旋转...
* doubleWithLeftChild
* @param tree
* @throws ClassNotFoundException
* @throws SQLException
*/
private AVLNode<T> doubleWithLeftChild(AVLNode<T> k3) {
k3.left = rotateWithLeftChild(k3.left);
return rotateWithLeftChild(k3);
}
/**
* 左子树插入左节点的时候单旋转...
* rotateWithLeftChild
* @param tree
*/
private AVLNode<T> rotateWithLeftChild(AVLNode<T> k2) {
AVLNode<T> k1 = k2.left;
k2.left = k1.right; // k1 变为原来k2这棵树的根节点.
// 因为k1.right > k1 < k2,所以把k2.left = k1.right
k1.right = k2; //k2 设置为新树的右节点.
//重新设置k1,k2 的深度.
k2.length = Math.max(k2.left.length, k2.right.length) + 1;
k1.length = Math.max(k2.length, k1.left.length) + 1;
return k1;
}
}