1. AVL树介绍
AVL树(Adelson-Velsky and Landis Tree)是一种自平衡的二叉搜索树,其特点主要包括平衡性和高效的查找、插入和删除操作。
平衡性
AVL树通过维护每个节点的平衡因子(左子树高度与右子树高度之差)来保持树的平衡。平衡因子的值只能是-1、0或1。如果某个节点的平衡因子绝对值大于1,那么该树就失去了平衡,需要通过旋转操作来重新平衡。
高效的查找、插入和删除操作
由于AVL树保持了平衡,其查找、插入和删除操作的时间复杂度都能保持在O(log n)的范围内,其中n是树中节点的数量。这使得AVL树在处理大量数据时能够保持高效的性能。
旋转操作
当AVL树失去平衡时,会触发旋转操作来恢复平衡。旋转操作主要有四种:右旋(单旋)、左旋(单旋)、右-左双旋和左-右双旋。这些旋转操作通过改变树中节点的链接关系来降低树的高度,从而保持树的平衡。
应用场景
AVL树广泛应用于需要频繁插入、删除和查找操作的场景,如数据库索引、文件系统的目录结构、实时数据更新等。在这些场景中,AVL树能够保持高效的性能,确保数据处理的快速响应。
2. 源码
public class AvlTree {
private AVLNode root = null;
public void put(int key, Object value) {
this.root = this.doPut(root, key, value);
}
public void delete(int key) {
this.root = doDelete(root, key);
}
private AVLNode doDelete(AVLNode node, int key) {
if (node == null) {
return null;
}
if (key < node.key) {
node.left = doDelete(node.left, key);
} else if (key > node.key) {
node.right = doDelete(node.right, key);
} else {
// 找到了
// 只有一个孩子
if (node.left == null) {
node = node.right;
} else if (node.right == null) {
node = node.left;
} else {
// 有两个孩子
// 找到后继节点
AVLNode s = node.right;
while (s.left != null) {
s = s.left;
}
// 删除后继节点, 因为会失衡, 返回删除后的根节点
s.right = this.doDelete(node.right, s.key);
s.left = node.left;
node = s;
}
}
if (node == null) {
return null;
}
updateHeight(node);
return balance(node);
}
private AVLNode doPut(AVLNode node, int key, Object value) {
if (node == null) {
return new AVLNode(key, value);
}
if (key == node.key) {
node.value = value;
return node;
}
if (key < node.key) {
node.left = doPut(node.left, key, value);
} else {
node.right = doPut(node.right, key, value);
}
// 更新高度
updateHeight(node);
// 平衡二叉树
return balance(node);
}
private AVLNode balance(AVLNode node) {
if (node == null) {
return null;
}
if (bf(node) > 1 && bf(node.left) >= 0) {
//LL -> 右旋
return rightRotation(node);
} else if (bf(node) > 1 && bf(node.left) < 0) {
// LR -> 左右旋
node.left = leftRotation(node.left);
return rightRotation(node);
} else if (bf(node) < -1 && bf(node.right) < 0) {
// RR -> 左旋
return leftRotation(node);
} else if (bf(node) < -1 && bf(node.right) >= 0) {
// RL -> 右左旋
node.right = rightRotation(node.right);
return leftRotation(node);
}
return node;
}
private AVLNode rightRotation(AVLNode p) {
AVLNode l = p.left;
AVLNode lr = l.right;
l.right = p;
p.left = lr;
updateHeight(p);
updateHeight(l);
return l;
}
private AVLNode leftRotation(AVLNode p) {
AVLNode r = p.right;
AVLNode rl = r.left;
r.left = p;
p.right = rl;
updateHeight(p);
updateHeight(r);
return r;
}
private void updateHeight(AVLNode node) {
node.height = Integer.max(height(node.left), height(node.right));
}
private int bf(AVLNode node) {
return height(node.left) - height(node.right);
}
private int height(AVLNode node) {
if (node == null) {
return 0;
}
return node.height;
}
/**
* 节点信息
*/
static class AVLNode {
int key;
Object value;
AVLNode left;
AVLNode right;
int height = 1;
public AVLNode(int key, Object value) {
this.key = key;
this.value = value;
}
}
}