我们有了二叉排序树为什么我们还需要平衡二叉排序树?
大家都知道树的结构其实也算是链表的一种变形,所以在最坏情况下树有可能变成线性的链表,那么此时遍历的效率(平均查找长度)很比较差(长),也失去了树的结构定义的初衷。
所以平衡二叉排序树就是为了维护“树”的基本形态。
1.平衡二叉排序树
平衡因子存储在节点当中,其含义就是当前节点的左子树深度与右子树深度之差。
如果一棵树所有节点的平很因子都是(0,1,-1),那么此树就为平衡二叉排序树。
一棵空树是平衡二叉树;若 T 是一棵非空二叉树,其左、右子树为 TL 和 TR ,令 hl 和 hr 分别为左、右子树的深度。当且仅当:
①TL 、 TR 都是平衡二叉树;
② | hl - hr |≤ 1;
时,则 T 是平衡二叉树。
2. 失衡及调整
失去平衡的4种姿态:LL(左左),LR(左右),RR(右右)和RL(右左).
2.1 LL的旋转
以K2为轴心点做右旋
2.2 RR的旋转
以K1为轴心点做左旋
2.3 LR的旋转
先以K1做轴心点做左旋(LL情况),现以K3做右旋
2.4 RL的旋转
先以K3做轴心点做右旋(RR情况),现以K1做左旋
3 JAVA代码
public class AvlTree<AnyType extends Comparable<? super AnyType>> {
public void insert(AnyType value) {
root = insert(value, root);
}
public void remove(AnyType value) {
AvlNode<AnyType> z;
if ((z = search(root, value)) != null)
root = remove(z, root);
}
public AvlNode<AnyType> search(AnyType key) {
return search(root, key);
}
private AvlNode<AnyType> search(AvlNode<AnyType> x, AnyType key) {
if (x == null)
return x;
int cmp = key.compareTo(x.element);
if (cmp < 0)
return search(x.left, key);
else if (cmp > 0)
return search(x.right, key);
else
return x;
}
private AvlNode<AnyType> remove(AvlNode<AnyType> z, AvlNode<AnyType> node) {
if (node == null || z == null)
return null;
int cmp = z.element.compareTo(node.element);
if (cmp < 0) { // 待删除的节点在"tree的右子树"中
node.left = remove(z, node.left);
if (height(node.right) - height(node.left) == 2) {
AvlNode<AnyType> r = node.right;
if (height(r.left) > height(r.right)) {
node = rightLeftRotate(node);
} else {
node = rightRightRotate(node);
}
}
node.height = Math.max(height(node.left), height(node.right)) + 1;
return node;
}
if (cmp > 0) { // 待删除的节点在"tree的左子树"中
node.right = remove(z, node.right);
if (height(node.left) - height(node.right) == 2) {
AvlNode<AnyType> l = node.left;
if (height(l.right) > height(l.left)) {
node = leftRightRotate(node);
} else {
node = leftLeftRotation(node);
}
}
node.height = Math.max(height(node.left), height(node.right)) + 1;
return node;
}
// cmp = 0
// 删除叶子节点直接删除
if (node.left == null && node.right == null) {
node = null;
return node;
}
// 删除只有右子树节点,直接将其右子树补上来
if (node.left == null && node.right != null) {
node = node.right;
node.height = Math.max(height(node.left), height(node.right)) + 1;
return node;
}
// 删除只有左子树节点,直接将其左子树补上来
if (node.left != null && node.right == null) {
node = node.left;
node.height = Math.max(height(node.left), height(node.right)) + 1;
return node;
}
// 删除2子树节点,且左高大于右高,找其前趋(左子树最大值)
if (height(node.left) > height(node.right)) {
AvlNode<AnyType> max = maximum(node.left);
node.element = max.element;
node.left = remove(max, node.left);
node.height = Math.max(height(node.left), height(node.right)) + 1;
return node;
}
// 删除2子树节点,且右高大于左高,找其后继(右子树最小值)
AvlNode<AnyType> min = minimum(node.right);
node.element = min.element;
node.right = remove(min, node.right);
node.height = Math.max(height(node.left), height(node.right)) + 1;
return node;
}
private AvlNode<AnyType> insert(AnyType x, AvlNode<AnyType> node) {
if (node == null)
return new AvlNode<AnyType>(x);
if (x.compareTo(node.element) == 0)
return node;
if (x.compareTo(node.element) > 0) {
node.right = insert(x, node.right);
if (height(node.right) - height(node.left) == 2) {
if (x.compareTo(node.right.element) > 0) {
node = rightRightRotate(node);
} else {
node = rightLeftRotate(node);
}
}
} else {
node.left = insert(x, node.left);
if (height(node.left) - height(node.right) == 2) {
if (x.compareTo(node.left.element) < 0) {
node = leftLeftRotation(node);
} else {
node = leftRightRotate(node);
}
}
}
node.height = Math.max(height(node.left), height(node.right)) + 1;
return node;
}
private AvlNode<AnyType> rightLeftRotate(AvlNode<AnyType> k2) {
k2.right = rightRotate(k2.right);
return leftRotate(k2);
}
private AvlNode<AnyType> leftRightRotate(AvlNode<AnyType> k2) {
k2.left = leftRotate(k2.left);
return rightRotate(k2);
}
// 插入节点是在节点的左边,直接当前结点右旋转
private AvlNode<AnyType> leftLeftRotation(AvlNode<AnyType> k2) {
return rightRotate(k2);
}
// 插入节点是在节点的右边,直接当前结点左旋转
private AvlNode<AnyType> rightRightRotate(AvlNode<AnyType> k2) {
return leftRotate(k2);
}
// 以K2结点右旋
private AvlNode<AnyType> rightRotate(AvlNode<AnyType> k2) {
AvlNode<AnyType> k1 = k2.left;
k2.left = k1.right;
k1.right = k2;
k2.height = Math.max(height(k2.left), height(k2.right)) + 1;
k1.height = Math.max(height(k1.left), k2.height) + 1;
return k1;
}
// 以K2结点左旋
private AvlNode<AnyType> leftRotate(AvlNode<AnyType> k2) {
AvlNode<AnyType> k1 = k2.right;
k2.right = k1.left;
k1.left = k2;
k2.height = Math.max(height(k2.right), height(k2.left)) + 1;
k1.height = Math.max(height(k1.right), k2.height) + 1;
return k1;
}
/*
* 查找最大结点:返回tree为根结点的AVL树的最大结点。
*/
private AvlNode<AnyType> maximum(AvlNode<AnyType> tree) {
if (tree == null)
return null;
while (tree.right != null)
tree = tree.right;
return tree;
}
/*
* 查找最小结点:返回tree为根结点的AVL树的最小结点。
*/
private AvlNode<AnyType> minimum(AvlNode<AnyType> tree) {
if (tree == null)
return null;
while (tree.left != null)
tree = tree.left;
return tree;
}
private int height(AvlNode<AnyType> node) {
return node == null ? -1 : node.height;
}
private AvlNode<AnyType> root;
private static class AvlNode<AnyType> {
AnyType element;
AvlNode<AnyType> left;
AvlNode<AnyType> right;
int height;
AvlNode(AnyType theElement) {
this(theElement, null, null);
}
AvlNode(AnyType theElement, AvlNode<AnyType> lt, AvlNode<AnyType> rt) {
element = theElement;
left = lt;
right = rt;
height = 0;
}
}
}