1. 设某个节点的左子树的叶子节点到根的最远路径为left_height
设某个节点的右子树的叶子节点到根的最远路径为right_height
2. 设平衡的度量为平衡因子-K,那么公式:K = left_height - right_height,平衡状态为 -1 <=k<=1
右图特征: 平衡因子k = 3 -1 = 2 ,大于1,并且新添加的节点的值小于根节点的左子树的值。
我们可以将不平衡的左子树进行左旋转,将不平衡的情况转到最外边。再向右旋转整个树。
什么时候左旋转、什么时候右旋转?
其实单凭感觉就可以知道,哪里比较冗余,就向反方向旋转。
注意:如果比较冗余的是最外边,单次旋转即可。
如果冗余的是里面,就需要左右旋转,或者右左旋转。
左旋转和右旋转的原理是相同的。
package demo;
/**
* @version 1.0
* @description:
* @author: 宇文智
* @date 2024/6/13 9:19
*/
public class AVLTree {
// 内部类表示树的节点
class TreeNode {
int value, height;
TreeNode left, right;
TreeNode(int value) {
this.value = value;
height = 1;
}
}
TreeNode root;
// 获取节点的高度
int height(TreeNode N) {
if (N == null)
return 0;
return N.height;
}
// 获取节点的平衡因子
int getBalance(TreeNode N) {
if (N == null)
return 0;
return height(N.left) - height(N.right);
}
// 右旋操作
TreeNode rightRotate(TreeNode y) {
TreeNode x = y.left;
TreeNode T2 = x.right;
x.right = y;
y.left = T2;
y.height = Math.max(height(y.left), height(y.right)) + 1;
x.height = Math.max(height(x.left), height(x.right)) + 1;
return x;
}
// 左旋操作
TreeNode leftRotate(TreeNode x) {
TreeNode y = x.right;
TreeNode T2 = y.left;
y.left = x;
x.right = T2;
x.height = Math.max(height(x.left), height(x.right)) + 1;
y.height = Math.max(height(y.left), height(y.right)) + 1;
return y;
}
// 插入节点
TreeNode insert(TreeNode node, int value) {
if (node == null)
return new TreeNode(value);
if (value < node.value)
node.left = insert(node.left, value);
else if (value > node.value)
node.right = insert(node.right, value);
else
return node;
node.height = 1 + Math.max(height(node.left), height(node.right)); //插入一个节点+1
int balance = getBalance(node);
if (balance > 1 && value < node.left.value) //左边树高,并且新插入的节点落到了左子树的左边,所以正常一次右旋转即可。
return rightRotate(node);
if (balance < -1 && value > node.right.value)
return leftRotate(node);
if (balance > 1 && value > node.left.value) {
node.left = leftRotate(node.left);
return rightRotate(node);
}
if (balance < -1 && value < node.right.value) {
node.right = rightRotate(node.right);
return leftRotate(node);
}
return node;
}
// 插入接口
void insert(int value) {
root = insert(root, value);
}
// 查找节点
boolean search(TreeNode root, int value) {
if (root == null)
return false;
if (value == root.value)
return true;
else if (value < root.value)
return search(root.left, value);
else
return search(root.right, value);
}
// 查找接口
boolean search(int value) {
return search(root, value);
}
// 中序遍历
void inorder(TreeNode root) {
if (root != null) {
inorder(root.left);
System.out.print(root.value + " ");
inorder(root.right);
}
}
// 中序遍历接口
void inorder() {
inorder(root);
}
public static void main(String[] args) {
AVLTree tree = new AVLTree();
// 插入节点
int[] values = {10, 20, 30, 40, 50, 25};
for (int value : values) {
tree.insert(value);
}
// 中序遍历
System.out.println("Inorder traversal of the given tree:");
tree.inorder(); // 应输出:10 20 25 30 40 50
// 查找节点
System.out.println("\n\nSearch results:");
System.out.println("Search 25: " + tree.search(25)); // 应输出:true
System.out.println("Search 15: " + tree.search(15)); // 应输出:false
}
}