AVL树是一种自平衡二叉查找树。它是由Seymour Lipschutz和Yaakov Avlson于1962年提出的。AVL树的特点是每个节点的左右两个子树的高度差(平衡因子)最多为1,从而保证了其时间复杂度为O(log n)。
在插入节点时,首先进行普通二叉查找树的操作,然后根据树的不平衡情况调整树形。AVL树的插入操作可以分为以下几步:
在删除节点时,首先进行普通二叉查找树的操作,然后根据树的变化情况调整树形。AVL树的删除操作可以分为以下几步:
AVL树使用旋转操作来调整其不平衡状态。主要有以下三种旋转方式:
每个节点包含一个平衡因子来记录其子树的高度差。平衡因子的可能值为-1、0或1,分别表示左重子树、左右子树相同高度和右重子树。
下面是一个简单的Java实现示例:
class AVLNode {
int key;
int height;
AVLNode left, right;
public AVLNode(int item) {
key = item;
height = 1; // 新插入节点的高度为1
}
}
public class AVLTree {
AVLNode root;
// 计算节点高度
private int height(AVLNode N) {
if (N == null)
return 0;
return N.height;
}
// 获取平衡因子
private int getBalance(AVLNode N) {
if (N == null)
return 0;
return height(N.left) - height(N.right);
}
// 右旋操作
AVLNode rightRotate(AVLNode y) {
AVLNode x = y.left;
AVLNode 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;
}
// 左旋操作
AVLNode leftRotate(AVLNode x) {
AVLNode y = x.right;
AVLNode 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;
}
AVLNode insert(AVLNode node, int key) {
if (node == null)
return new AVLNode(key);
if (key < node.key)
node.left = insert(node.left, key);
else if (key > node.key)
node.right = insert(node.right, key);
else // Equal keys not allowed
return node;
// 更新高度
node.height = 1 + Math.max(height(node.left), height(node.right));
// 获取平衡因子
int balance = getBalance(node);
// 平衡检查
if (balance > 1 && key < node.left.key) {
return rightRotate(node);
}
if (balance < -1 && key > node.right.key) {
return leftRotate(node);
}
if (balance > 1 && key > node.left.key) {
node.left = leftRotate(node.left);
return rightRotate(node);
}
if (balance < -1 && key < node.right.key) {
node.right = rightRotate(node.right);
return leftRotate(node);
}
// 如果未达到不平衡状态,则不需要调整
return node;
}
}
以上代码展示了AVL树的基本操作和Java实现。实际应用中,可以根据需要进一步完善和优化。