平衡二叉树AVL

我们有了二叉排序树为什么我们还需要平衡二叉排序树?

大家都知道树的结构其实也算是链表的一种变形,所以在最坏情况下树有可能变成线性的链表,那么此时遍历的效率(平均查找长度)很比较差(长),也失去了树的结构定义的初衷。 
所以平衡二叉排序树就是为了维护“树”的基本形态。

 

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;
        }

    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值