在实现AVLTree之前,首先应该明确:
1. AVLTree
是一种特殊的BinarySearchTree
,即带有平衡条件的二叉查找树.所以BinarySearchTree
的部分操作在此处可以套用.
2. 在remove
和insert
操作的时候,应该及时调整(balance
)新的AVLTree
,让其满足其定义.
3. insert
操作时候,有如下四种情况:
(几张图,画一个小时 - - !)
上代码:
public class AVLTree<AnyType extends Comparable<? super AnyType>> {
private static final int ALLOWED_IMBALANCE = 1;
private AVLNode<AnyType> root;
/*
* 判空
*/
public boolean isEmpty() {
return root == null;
}
public int getHeight(AVLNode<AnyType> t) {
return height(t);
}
/**
* 查找最小值的方法
*
* @author ZFY
*
* @return
*/
public AnyType findMin() {
if (isEmpty()) {
throw new NullPointerException();
}
return findMin(root).element;
}
/**
* 插入
*
* @author ZFY
*
* @param x
* 待插入的元素
*/
public void insert(AnyType x) {
root = insert(x, root);
}
/**
* 移除
*
* @author ZFY
*
* @param x
* 待移除的元素
*/
public void remove(AnyType x) {
root = remove(x, root);
}
// ---------------------------------------------------------------------------------
/**
* 节点内部类
*
* @author ZFY
*/
private static class AVLNode<AnyType> {
private AVLNode<AnyType> left;
private AVLNode<AnyType> right;
AnyType element;
int height;
// 构造方法
AVLNode(AnyType theElement) {
this(theElement, null, null);
}
AVLNode(AnyType theElement, AVLNode<AnyType> lt, AVLNode<AnyType> rt) {
element = theElement;
left = lt;
right = rt;
height = 0;
}
}
/**
* Method to get the height of the Node
*
* @author ZFY
*
* @param t
* @return Return the height of node,if null,return -1;
*/
private int height(AVLNode<AnyType> t) {
return t == null ? -1 : t.height;
}
/**
* 查找以t为根的子树种的最小值
*
* @author ZFY
*
* @param t
* @return
*/
private AVLNode<AnyType> findMin(AVLNode<AnyType> t) {
/**
* 递归写法
*/
if (t == null) {
return null;
} else if (t.left == null) {
return t;
} else {
return findMin(t.left);
}
/**
* 非递归写法 if(t!=null){ while(t.left!=null){ t=t.left; } } return t;
*/
}
/**
* 插入一个节点的方法
*
* @author ZFY
*
* @param x
* @param t
* @return
*/
private AVLNode<AnyType> insert(AnyType x, AVLNode<AnyType> t) {
if (t == null) {
return new AVLNode<AnyType>(x, null, null);
}
int compareResult = x.compareTo(t.element);
if (compareResult < 0) {
t.left = insert(x, t.left);
} else if (compareResult > 0) {
t.right = insert(x, t.right);
} else {
;
}
return balance(t);
}
/**
* 调整不平衡节点的方法.不平衡分为四种情况 1.对X的左儿子的左子树进行一次插入 2.对X的左儿子的右子树进行一次插入
* 3.对X的右儿子的左子树进行一次插入 4.对X的右儿子的右子书进行一次插入
*
* @author ZFY
*
* @param t
* @return
*/
private AVLNode<AnyType> balance(AVLNode<AnyType> t) {
if (t == null) {
return t;
}
if (height(t.left) - height(t.right) > ALLOWED_IMBALANCE) {
if (height(t.left.left) >= height(t.left.right)) {
// 左左==>右旋
t = rotateWithLeftChild(t);
} else {
// 左右==>先左旋再右旋
t = doubleWithLeftChild(t);
}
} else if (height(t.right) - height(t.left) > ALLOWED_IMBALANCE) {
if (height(t.right.right) >= height(t.right.left)) {
// 右右==>左旋
t = rotateWithRightChild(t);
} else {
// 右左==>先右旋再左旋
t = doubleWithRightChild(t);
}
}
t.height = Math.max(height(t.left), height(t.right)) + 1;
return t;
}
/**
* 左左旋转的方法(即向右旋)
*
* @author ZFY
*
* @param k2
* 平衡被破坏的节点
* @return k1 平衡之后的树的根节点
*/
private AVLNode<AnyType> rotateWithLeftChild(AVLNode<AnyType> k2) {
AVLNode<AnyType> k1 = k2.left;
k2.left = k1.right;
k1.right = k2;
k2.height = Math.max(k2.left.height, k2.right.height) + 1;
k1.height = Math.max(k1.left.height, k2.height) + 1;
return k1;
}
/**
* 右右旋转的方法(即向左旋)
*
* @author ZFY
*
* @param k1
* 平衡被破坏的节点
* @return k1 平衡之后的树的根节点
*/
private AVLNode<AnyType> rotateWithRightChild(AVLNode<AnyType> k1) {
AVLNode<AnyType> k2 = k1.right;
k1.right = k2.left;
k2.left = k1;
k1.height = Math.max(k1.left.height, k1.right.height) + 1;
k2.height = Math.max(k2.right.height, k1.height) + 1;
return k2;
}
/**
* 左右旋转的方法 即 先调用右右旋转的方法,在调用左左旋转的方法
*
* @author ZFY
*
* @param k3
* 平衡被破坏的节点
* @return 平衡之后的树的根节点
*/
private AVLNode<AnyType> doubleWithLeftChild(AVLNode<AnyType> k3) {
k3.left = rotateWithRightChild(k3.left);
return rotateWithLeftChild(k3);
}
/**
* 右左旋转的方法 即 先调用左左旋转的方法,在调用右右旋转的方法
*
* @author ZFY
*
* @param k3
* 平衡被破坏的节点
* @return 平衡之后的树的根节点
*/
private AVLNode<AnyType> doubleWithRightChild(AVLNode<AnyType> k1) {
k1.right = rotateWithLeftChild(k1.right);
return rotateWithRightChild(k1);
}
private AVLNode<AnyType> remove(AnyType x, AVLNode<AnyType> t) {
if (t == null) {
return t;
}
int compareResult = x.compareTo(t.element);
if (compareResult < 0) {
t.left = remove(x, t.left);
} else if (compareResult > 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; // 用t.left或者是t.right取代t
}
return balance(t);
}
}