约束
- 节点高度:节点到叶子节点的最大高度,叶子节点高度为0,null节点高度为-1。
- 每个节点的左子树和右子树高度差的绝对值小于等于1。
- 当出现高度差绝对值为2时,需要通过旋转来达到自平衡。
节点类、高度计算
private class AVLNode<E> {
private E e;
private AVLNode<E> left, right, parent;
private Integer height;
private AVLNode(E e) {
this.e = e;
}
}
private int size;
private AVLNode<E> root;
private int height(AVLNode<E> node) {
return null == node ? -1 : node.height;
}
private int recalculateHeight(AVLNode<E> node) {
return Math.max(height(node.left), height(node.right)) + 1;
}
旋转图示

图片来源:
Mhss at zh.wikipedia,CC BY-SA 3.0
旋转代码
LL -- 左左单旋转 -- 右旋
private AVLNode<E> LLRotate(AVLNode<E> node) {
AVLNode<E> result = node.left;
node.left = result.right;
result.right = node;
node.height = recalculateHeight(node);
result.height = recalculateHeight(result);
return result;
}
RR -- 右右单旋转 -- 左旋
private AVLNode<E> RRRotate(AVLNode<E> node) {
AVLNode<E> result = node.right;
node.right = result.left;
result.left = node;
node.height = recalculateHeight(node);
result.height = recalculateHeight(result);
return result;
}
LR -- 左右双旋转 -- 先左旋后右旋
private AVLNode<E> LRRotate(AVLNode<E> node) {
node.left = this.RRRotate(node.left);
return this.LLRotate(node);
}
RL -- 右左双旋转 -- 先右旋后左旋
private AVLNode<E> RLRotate(AVLNode<E> node) {
node.right = this.LLRotate(node.right);
return this.RRRotate(node);
}
添加
public void add(E e) {
root = this.add(e, root);
}
private AVLNode<E> add(E e, AVLNode<E> node) {
if (node == null) {
this.size++;
return new AVLNode<>(e);
}
if (e.compareTo(node.e) < 0) {
node.left = add(e, node.left);
if (height(node.left) - height(node.right) == 2) {
if (e.compareTo(node.left.e) < 0) {
node = LLRotate(node);
}
else {
node = LRRotate(node);
}
}
}
else if (e.compareTo(node.e) > 0) {
node.right = add(e, node.right);
if (height(node.right) - height(node.left) == 2) {
if (e.compareTo(node.right.e) > 0) {
node = RRRotate(node);
}
else {
node = RLRotate(node);
}
}
}
node.height = recalculateHeight(node);
return node;
}
测试
public void levelOrder() {
this.levelOrder(root);
}
private void levelOrder(AVLNode<E> node) {
Queue<AVLNode<E>> queue = new LinkedList<>();
queue.add(node);
Integer height = node.height;
while (!queue.isEmpty()) {
AVLNode<E> temp = queue.poll();
if (!height.equals(temp.height)){
height = temp.height;
System.out.println();
}
System.out.print(temp.e + " ");
if (temp.left != null) {
queue.add(temp.left);
}
if (temp.right != null) {
queue.add(temp.right);
}
}
}
public static void main(String[] args) {
Integer[] array = {4, 2, 7, 6, 8, 5};
AVL avl = new AVL();
avl.addArray(array);
avl.levelOrder();
}
结果
6
4 7
2 5 8