版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
AVL树实际上是为了解决二分搜索树在极端情况下退化成链表的问题。AVL树通过自动调节左右子树的高度可以保证查找时间复杂度在O(logN)。
在AVL树中,新增节点的默认高度是1,新增节点的父节点默认高度是2,以此类推。左子节点的高度与右子节点的高度差成为平衡因子。在AVL树中,要求所有节点的平衡因子都小于等于1。
由于节点的平衡因子是通过左右子树的高度计算的,所以我们就需要在节点中记录当前节点的高度值。
还是直接看代码。
package loop;
import java.util.ArrayList;
import java.util.List;
//平衡树
public class AVLTree<E extends Comparable<E>> {
private Node<E> root;
private int size;
// 判断是否为二叉搜索树
public boolean isBst() {
List<E> eList = new ArrayList<>();
inOrder(eList, root);
for (int i = 1;i < eList.size();i ++) {
if (eList.get(i-1).compareTo(eList.get(i)) > 0) {
return false;
}
}
return true;
}
private void inOrder(List<E> eList, Node<E> node) {
if(node == null) {
return;
}
inOrder(eList, node.left);
eList.add(node.data);
inOrder(eList, node.right);
}
private int getHeight(Node<E> node) {
if (node == null) {
return 0;
}
return node.height;
}
private int getBalanceFactor(Node<E> node) {
if (node == null) {
return 0;
}
//左- 右
return getHeight(node.left) - getHeight(node.right);
}
private boolean isBalanced(Node<E> node) {
if (node == null) {
return true;
}
int balanceFactor = getBalanceFactor(node);
if (Math.abs(balanceFactor) > 1) {
return false;
}
return isBalanced(node.left) && isBalanced(node.right);
}
public boolean isBalanced() {
return isBalanced(root);
}
//添加节点
public void add(E e) {
root = add(root, e);
}
private Node<E> add(Node<E> node, E e) {
if (node == null) {
this.size ++;
return new Node(e);
}
Node<E> retNode ;
if (e.compareTo(node.data) > 0) {
node.right = add(node.right, e);
} else if (e.compareTo(node.data) < 0) {
node.left = add(node.left, e);
} else {
node.data = e;
}
//更新当前节点高度
node.height = 1 + Math.max(getHeight(node.left), getHeight(node.right));
int balanceFactor = getBalanceFactor(node);
//LL
if (balanceFactor > 1 && getBalanceFactor(node.left) >= 0) {
//右旋转
return rightRotate(node);
}
if (balanceFactor < -1 && getBalanceFactor(node.right) < 0) {
//左旋转
return leftRotate(node);
}
//LR
if (balanceFactor > 1 && getBalanceFactor(node.left) < 0) {
node.left = leftRotate(node.left);
return rightRotate(node);
}
//RL
if (balanceFactor < -1 && getBalanceFactor(node.right) > 0) {
node.right = rightRotate(node.right);
return leftRotate(node);
}
return node;
}
public void remove(E e) {
}
private Node<E> remove(Node<E> node, E e) {
if (node == null) {
return null;
}
Node<E> retNode ;
if (e.compareTo(node.data) > 0) {
node.right = remove(node.right, e);
retNode = node;
} else if (e.compareTo(node.data) < 0){
node.left = remove(node.left, e);
retNode = node;
} else {
//找到了待删除的节点
if (node.left == null) {
Node<E> right = node.right;
node.right = null;
this.size --;
retNode = right;
} else if (node.right == null) {
Node<E> left = node.left;
node.left = null;
this.size --;
retNode = left;
} else {
/**
即有左子树 又 有右子树
* */
Node<E> rightMinNode = minNode(node.right);
rightMinNode.right = remove(node.right, rightMinNode.data);
rightMinNode.left = node.left;
node.left = node.right = null;
this.size --;
retNode = rightMinNode;
}
}
//调整平衡性
if (retNode == null) {
return null;
}
//更新高度
retNode.height = Math.max(getHeight(retNode.right), getHeight(retNode.left)) + 1;
//获取平衡因子
int balanceFactor = getBalanceFactor(retNode);
//LL
if (balanceFactor > 1 && getBalanceFactor(retNode.left) >= 0) {
//右旋转
return rightRotate(node);
}
if (balanceFactor < -1 && getBalanceFactor(retNode.right) < 0) {
//左旋转
return leftRotate(node);
}
//LR
if (balanceFactor > 1 && getBalanceFactor(retNode.left) < 0) {
node.left = leftRotate(node.left);
return rightRotate(node);
}
//RL
if (balanceFactor < -1 && getBalanceFactor(retNode.right) > 0) {
node.right = rightRotate(node.right);
return leftRotate(node);
}
return retNode;
}
private Node<E> minNode(Node<E> node) {
if (node == null) {
return null;
}
if (node.left == null) {
return node;
}
return minNode(node.left);
}
//左旋转
public Node rightRotate(Node<E> node) {
Node<E> x = node.left;
Node<E> t1 = x.right;
x.right = node;
node.left = t1;
node.height = Math.max(getHeight(node.left), getHeight(node.right)) + 1;
x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1;
return x;
}
//右旋转
public Node leftRotate(Node<E> node) {
Node<E> x = node.right;
Node<E> t1 = x.left;
x.left = node;
node.right = t1;
node.height = Math.max(getHeight(node.left), getHeight(node.right)) + 1;
x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1;
return x;
}
//删除节点
private class Node<E> {
E data;
Node<E> left;
Node<E> right;
int height;
public Node(E data) {
this.data = data;
this.left = null;
this.right = null;
this.height = 1;
}
}
}