AVL是最先发明的自平衡二叉查找树算法。在AVL中任何节点的两个儿子子树的高度最大差别为一,所以它也被称为高度平衡树,n个结点的AVL树最大深度约1.44log2n。查找、插入和删除在平均和最坏情况下都是O(log n)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。
package com.gloomy.Tree;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.Stack;
/**
* 平衡二叉树
*
* @author 过路的守望
*
*/
public class AVLTree {
/*
* 平衡二叉树的更
*/
private Node root;
public AVLTree(Node root) {
this.root = root;
}
public static void main(String[] args) {
Node A = new Node(1);
Node B = new Node(2);
Node C = new Node(3);
Node D = new Node(4);
Node E = new Node(5);
Node F = new Node(6);
Node G = new Node(7);
Node H = new Node(8);
Node I = new Node(9);
Node J = new Node(10);
Node K = new Node(11);
Node L = new Node(12);
Node M = new Node(13);
Node N = new Node(14);
AVLTree avlTree = new AVLTree(C);
avlTree.insert(D);
avlTree.insert(E);
avlTree.insert(A);
avlTree.insert(B);
avlTree.insert(F);
avlTree.insert(G);
avlTree.insert(M);
avlTree.insert(N);
avlTree.insert(J);
avlTree.insert(H);
avlTree.insert(I);
avlTree.insert(K);
avlTree.insert(L);
avlTree.remove(G);
avlTree.remove(M);
avlTree.remove(E);
avlTree.remove(F);
avlTree.remove(D);
avlTree.remove(I);
avlTree.remove(J);
System.out.println(avlTree.findMax().val);
System.out.println(avlTree.findMin().val);
avlTree.levelOrder(avlTree.root);
avlTree.preOrder(avlTree.root);
avlTree.inOrder(avlTree.root);
avlTree.postOrder(avlTree.root);
}
/**
* 平衡二叉树中是否包含节点node
*
* @param node
* @return
*/
public boolean contains(Node node) {
/*
* 平衡二叉树为空,自然不包含
*/
if (root == null) {
return false;
}
Node currentNode = root;
/*
* 标记node是否大于当前节点
*/
int flag = node.compareTo(currentNode);
/*
* 检查平衡二叉树中是否包含节点node
*/
while (flag != 0) {
if (flag > 0) {
currentNode = currentNode.right;
} else {
currentNode = currentNode.left;
}
/*
* 平衡二叉树树中为找到节点node,放回false。
*/
if (currentNode == null) {
return false;
}
flag = node.compareTo(currentNode);
}
return true;
}
/**
* 递归检查平衡二叉树中root是否包含node节点
*
* @param node
* @param root
*/
public boolean contains(Node node, Node root) {
/*
* root为空显然不包含节点node
*/
if (root == null) {
return false;
}
int flag = node.compareTo(root);
/*
* 在root的右子树中检查是否含有node节点
*/
if (flag > 0) {
return contains(node, root.right);
}
/*
* 在root的左子树中检查是否含有node节点
*/
if (flag < 0) {
return contains(node, root.left);
}
/*
* root中含有此节点,返回true
*/
return true;
}
/**
* 返回平衡二叉树中的最大节点
*
* @return
*/
public Node findMax() {
return findMax(root);
}
/**
* 返回平衡二叉树中的最小节点
*
* @return
*/
public Node findMin() {
return findMin(root);
}
/**
* 找到平衡二叉树root中的最大节点
*
* @param root
* @return
*/
private Node findMax(Node root) {
/**
* root节点为空
*/
if (root == null) {
return null;
}
/*
* 找到右子树中的最大元素节点
*/
Node currentNode = root;
while (currentNode.right != null) {
currentNode = currentNode.right;
}
return currentNode;
}
/**
* 递归查找平衡二叉树中的最大节点
*
* @param root
* @return
*/
private Node findMaxRec(Node root) {
if (root == null) {
return null;
}
if (root.right != null) {
return findMaxRec(root.right);
}
return root;
}
/**
* 查找平衡二叉树root中的最小节点
*
* @param node
* @param root
* @return
*/
private Node findMin(Node root) {
/*
* root为空
*/
if (root == null) {
}
/*
* 在左子树中寻找最小节点元素
*/
Node currentNode = root;
while (currentNode.left != null) {
currentNode = currentNode.left;
}
return currentNode;
}
/**
* 递归查找平衡二叉树中的最小元素
*
* @param root
* @return
*/
private Node findMinRec(Node root) {
/*
* root 为空
*/
if (root == null) {
return root;
}
if (root.left != null) {
return findMinRec(root.left);
}
return root;
}
/**
* 返回节点node的高度,node如果为null,则高度为-1
*
* @param node
* @return
*/
private int getHeight(Node node) {
return node == null ? -1 : node.hight;
}
/**
* 单旋转-右旋
*
* @param node
* @return
*/
private Node rolateWithLeftChild(Node node) {
Node leftChild = node.left;
node.left = leftChild.right;
leftChild.right = node;
/*
* 更新节点高度
*/
node.hight = 1 + Math.max(getHeight(node.left), getHeight(node.right));
leftChild.hight = 1 + Math.max(getHeight(leftChild.left),
getHeight(leftChild.right));
return leftChild;
}
/**
* 单旋转-左旋
*
* @param node
* @return
*/
private Node rolateWithRightChild(Node node) {
Node rightChild = node.right;
node.right = rightChild.left;
rightChild.left = node;
/*
* 更新节点高度
*/
node.hight = 1 + Math.max(getHeight(node.left), getHeight(node.right));
rightChild.hight = 1 + Math.max(getHeight(rightChild.left),
getHeight(rightChild.right));
return rightChild;
}
/**
* 双旋转-RL
*
* @param node
* @return
*/
private Node doubleWithLeftChild(Node node) {
node.left = rolateWithRightChild(node.left);
return rolateWithLeftChild(node);
}
/**
* 双旋转-LR
*
* @param node
* @return
*/
private Node doubleWithRightChild(Node node) {
node.right = rolateWithLeftChild(node.right);
return rolateWithRightChild(node);
}
/**
* 向平衡二叉树中插入节点node
*
* @param node
*/
public void insert(Node node) {
/*
* 更新引用(传值)
*/
root = insert(node, root);
}
/**
* 删除平衡二叉树中的节点node
*
* @param node
*/
public void remove(Node node) {
root = remove(node, root);
}
/**
* 递归实现向root平衡二叉树中插入元素node
*
* @param node
* @param root
* @return
*/
private Node insert(Node node, Node root) {
if (root == null) {
root = new Node(node.val);
}
int flag = node.compareTo(root);
if (flag > 0) {
root.right = insert(node, root.right);
/*
* 左右子树高度差
*/
flag = Math.abs(getHeight(root.left) - getHeight(root.right));
if (flag == 2) {
/*
* RR型
*/
if (getHeight(root.right.right) > getHeight(root.right.left)) {
root = rolateWithRightChild(root);
}
/*
* RL型
*/
else {
root = doubleWithRightChild(root);
}
}
} else if (flag < 0) {
root.left = insert(node, root.left);
/*
* 左右子树高度差
*/
flag = Math.abs(getHeight(root.left) - getHeight(root.right));
if (flag == 2) {
/*
* LL型
*/
if (getHeight(root.left.left) > getHeight(root.left.right)) {
root = rolateWithLeftChild(root);
}
/*
* LR型
*/
else {
root = doubleWithLeftChild(root);
}
}
}
/*
* 更新root的高度 上层的高度由子树的高度决定
*/
root.hight = 1 + Math.max(getHeight(root.left), getHeight(root.right));
return root;
}
/**
* 递归删除二叉平衡树root中的节点node
*
* @param node
* @param root
* @return
*/
private Node remove(Node node, Node root) {
/*
* root为空
*/
if (root == null) {
return null;
}
int flag = node.compareTo(root);
/*
* 待删除节点在右子树上
*/
if (flag > 0) {
root.right = remove(node, root.right);
}
/*
* 待删除节点在左子树上
*/
if (flag < 0) {
root.left = remove(node, root.left);
}
/*
* 找到待删除节点
*/
if (flag == 0) {
if (root.left != null && root.right != null) {
/*
* 用待删除节点右子树上的最小节点的与待删除节点交换,然后问题变为删除节点replaceNode
*/
Node replaceNode = findMin(root.right);
root.val = replaceNode.val;
root.right = remove(replaceNode, root.right);
} else {
root = root.right == null ? root.left : root.right;
}
}
if (root != null) {
flag = Math.abs(getHeight(root.left) - getHeight(root.right));
} else {
flag = 0;
}
if (flag == 2) {
if (getHeight(root.left) > getHeight(root.right)) {
/*
* LL型旋转
*/
if (getHeight(root.left.left) > getHeight(root.left.right)) {
root = rolateWithLeftChild(root);
}
/*
* LR型旋转
*/
else {
root = doubleWithLeftChild(root);
}
} else {
/*
* RR型旋转
*/
if (getHeight(root.right.right) > getHeight(root.right.left)) {
root = rolateWithRightChild(root);
}
/*
* RL型旋转
*/
else {
root = doubleWithRightChild(root);
}
}
}
/*
* 更新root的高度
*/
if (root != null) {
root.hight = 1 + Math.max(getHeight(root.left),
getHeight(root.right));
}
return root;
}
/**
* 非递归先序遍历
*
* @param node
*/
public void preOrder(Node node) {
if (node == null) {
return;
}
System.out.println("先序遍历:");
Stack stack = new Stack();
stack.push(node);
while (!stack.isEmpty()) {
node = stack.pop();
System.out.print(node.val + " ");
/*
* 先加入右儿子
*/
if (node.right != null) {
stack.push(node.right);
}
if (node.left != null) {
stack.push(node.left);
}
}
System.out.println();
}
/**
* 非递归中序遍历
*
* @param node
*/
public void inOrder(Node node) {
if (node == null) {
return;
}
System.out.println("中序遍历:");
Stack stack = new Stack();
while (node != null || !stack.isEmpty()) {
while (node != null) {
stack.push(node);
node = node.left;
}
/*
* 处理完左子树,根节点,处理右子树。
*/
node = stack.pop();
System.out.print(node.val + " ");
node = node.right;
}
System.out.println();
}
/**
* 非递归后序遍历
*
* @param node
*/
public void postOrder(Node node) {
if (node == null) {
return;
}
System.out.println("后序遍历:");
Stack stack = new Stack();
/*
* preNode记录前一个出栈的节点
*/
Node preNode = null;
while (node != null || !stack.isEmpty()) {
while (node != null) {
stack.push(node);
node = node.left;
}
node = stack.peek();
/*
* 处理完左子树,在处理右子树,最后处理根节点。
*/
while (node.right == null || node.right == preNode) {
System.out.print(node.val + " ");
stack.pop();
preNode = node;
if (stack.isEmpty()) {
System.out.println();
return;
}
node = stack.peek();
}
node = node.right;
}
}
public void levelOrder(Node node) {
if (node == null) {
return;
}
System.out.println("层序遍历:");
Queue queue = new ArrayDeque();
queue.offer(node);
/*
* 处理完上一层厚再处理下一层
*/
while (!queue.isEmpty()) {
node = queue.poll();
System.out.print(node.val + " ");
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
System.out.println();
}
}
/**
* 平衡二叉树节点类
*
* @author 过路的守望
*/
class Node implements Comparable {
/*
* val 节点值 height 节点高度
*/
int val;
Node left;
Node right;
int hight;
public Node(int val) {
this.val = val;
}
@Override
public int compareTo(Node o) {
return this.val - o.val;
}
}