概念: 二叉树存在值顺序插入导致树高度过大的问题、平衡二叉树通过旋转的方式、使二叉树处于平衡状态、子树高度差不能大于1
旋转规则:
左子树高右旋、右子树高左旋
右旋时插入节点在最右、则子树先左旋
左旋时插入节点在最左、则子树先右旋
代码实现:
package com.info.dataStructure.avl;
/**
* @author haizhuangbu
* @date 2024/3/22 10:47
* @mark AvlNode 节点
*/
public class AvlNode<T extends Comparable<T>> {
AvlNode<T> left;
AvlNode<T> right;
T key;
// 高度
int height;
public AvlNode(T key) {
this.key = key;
this.height = 0;
}
}
package com.info.dataStructure.avl;
/**
* @author haizhuangbu
* @date 2024/3/22 10:45
* @mark AvlTree
*/
public class AvlTree<T extends Comparable<T>> {
// 根节点
private AvlNode<T> root;
public AvlTree() {
this.root = null;
}
/**
* @param node 节点
* @return 节点高度(树的高度)
*/
private int height(AvlNode<T> node) {
if (node == null) return -1;
return node.height;
}
private void updateHeight(AvlNode<T> node) {
// 当前树的高度为 最大的子树高度 + 1
node.height = Math.max(height(node.left), height(node.right)) + 1;
}
/**
* @param avlNode 节点
* @return 右旋
*/
private AvlNode<T> rotateLeft(AvlNode<T> avlNode) {
AvlNode<T> right = avlNode.right;
avlNode.right = right.left;
right.left = avlNode;
updateHeight(avlNode);
updateHeight(right);
return right;
}
/**
* @param node 节点
* @return 右旋
*/
private AvlNode<T> rotateRight(AvlNode<T> node) {
AvlNode<T> left = node.left;
node.left = left.right;
left.right = node;
updateHeight(node);
updateHeight(left);
return left;
}
private AvlNode<T> insert(AvlNode<T> node, T key) {
if (node == null) return new AvlNode<>(key);
// 将节点插入 平衡二叉树中
if (key.compareTo(node.key) < 0) {
node.left = insert(node.left, key);
} else if (key.compareTo(node.key) > 0) {
node.right = insert(node.right, key);
} else {
// 键值存在不需要插入
return node;
}
// 不满足 子节点高度差不能大于1
if (height(node.left) - height(node.right) == 2) {
if (key.compareTo(node.left.key) < 0) {
return rotateRight(node);
} else {
node.left = rotateLeft(node.left);
return rotateRight(node);
}
} else if (height(node.right) - height(node.left) == 2) {
if (key.compareTo(node.right.key) > 0) {
return rotateLeft(node);
} else {
node.right = rotateRight(node.right);
return rotateLeft(node);
}
}
updateHeight(node);
return node;
}
public void insert(T key) {
root = insert(root, key);
}
}