package tree;
/**
* 平衡二叉树(AVL树)
* 这里只模拟int类型实现,如果需要其他类型,请将int类型修改为泛型,并实现extends Comparable<T>接口,方便比较
* 动态模拟实现:https://www.cs.usfca.edu/~galles/visualization/AVLtree.html
* GitHub地址:https://github.com/hack-feng/algorithm
*/
public class AVLTree{
private Node root;
static class Node{
int data;
Node left;
Node right;
int height;
Node(Node left, Node right, int data) {
this.left = left;
this.right = right;
this.data = data;
this.height = 0;
}
}
// 插入节点
private void insert(int data){
root = insert(data, root);
}
private Node insert(int data, Node node){
if(node == null){
Node returnNode = new Node(null, null, data);
// 新创建的树,高度默认为1
returnNode.height = 1;
return returnNode;
}else{
// 如果root.data的值大于data, 则在左子树上插入,否则在右子树上插入
if(node.data > data){
node.left = insert(data, node.left);
// 判断树是否失衡,失衡需要旋转
if(getHeight(node.left) > getHeight(node.right) + 1){
// 判断进行两次旋转还是一次旋转
if(node.left.data > data){
//(LL)一次旋转, 右旋
node = LL(node);
}else{
//(LR)两次旋转, 先左旋,再右旋
node = LR(node);
}
}
}else{
node.right = insert(data, node.right);
// 判断树是否失衡,失衡需要旋转
if(getHeight(node.right) > getHeight(node.left) + 1){
// 判断进行两次旋转还是一次旋转
if(node.right.data > data){
//(RL)两次旋转,先右旋,再左旋
node = RL(node);
}else{
//(RR)一次旋转,左旋
node = RR(node);
}
}
}
// 重新计算树的高度
node.height = setHeight(node);
return node;
}
}
// 左左情况, 进行一次右旋
private Node LL(Node node){
Node leftNode = node.left;
node.left = leftNode.right;
leftNode.right = node;
//重新计算高度
node.height = setHeight(node);
leftNode.height = setHeight(leftNode);
return leftNode;
}
// 左右情况, 先进行左旋,再进行一次右旋
private Node LR(Node node){
node.left = RR(node.left);
node = LL(node);
return node;
}
// 右右情况, 进行一次左旋
private Node RR(Node node){
Node rightNode = node.right;
node.right = rightNode.left;
rightNode.left = node;
//重新计算高度
node.height = setHeight(node);
rightNode.height = setHeight(rightNode);
return rightNode;
}
// 右左情况,先进行右旋,再进行一次左旋
private Node RL(Node node){
node.right = LL(node.right);
node = RR(node);
return node;
}
// 获取树的高度
private int getHeight(Node node){
return node == null ? 0 : node.height;
}
// 重新计算树的高度
private int setHeight(Node node){
return Math.max(getHeight(node.left), getHeight(node.right)) + 1;
}
// 打印节点
private void printNode(Node root){
if(root != null){
printNode(root.left);
System.out.println(root.data);
printNode(root.right);
}
}
public static void main(String [] args){
// int[] dataArray = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
int[] dataArray = new int[]{2, 8, 5, 6, 7, 4, 3, 1, 9};
AVLTree tree = new AVLTree();
for (int i : dataArray) {
tree.insert(i);
}
tree.printNode(tree.root);
}
}
一天一个算法——>平衡二叉树的插入
最新推荐文章于 2022-10-31 08:22:52 发布
