数据结构和算法------AVLTree的实现

在实现AVLTree之前,首先应该明确:
1. AVLTree是一种特殊的BinarySearchTree,即带有平衡条件的二叉查找树.所以BinarySearchTree的部分操作在此处可以套用.
2. 在removeinsert操作的时候,应该及时调整(balance)新的AVLTree,让其满足其定义.
3. insert操作时候,有如下四种情况:

左左
右右
左右
右左

(几张图,画一个小时 - - !)

上代码:

public class AVLTree<AnyType extends Comparable<? super AnyType>> {

    private static final int ALLOWED_IMBALANCE = 1;
    private AVLNode<AnyType> root;

    /*
     * 判空
     */
    public boolean isEmpty() {
        return root == null;
    }

    public int getHeight(AVLNode<AnyType> t) {
        return height(t);
    }

    /**
     * 查找最小值的方法
     * 
     * @author ZFY
     * 
     * @return
     */
    public AnyType findMin() {
        if (isEmpty()) {
            throw new NullPointerException();
        }
        return findMin(root).element;
    }

    /**
     * 插入
     * 
     * @author ZFY
     * 
     * @param x
     *            待插入的元素
     */
    public void insert(AnyType x) {
        root = insert(x, root);
    }

    /**
     * 移除
     * 
     * @author ZFY
     * 
     * @param x
     *            待移除的元素
     */
    public void remove(AnyType x) {
        root = remove(x, root);
    }

    // ---------------------------------------------------------------------------------

    /**
     * 节点内部类
     * 
     * @author ZFY
     */
    private static class AVLNode<AnyType> {
        private AVLNode<AnyType> left;
        private AVLNode<AnyType> right;
        AnyType element;
        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;
        }

    }

    /**
     * Method to get the height of the Node
     * 
     * @author ZFY
     * 
     * @param t
     * @return Return the height of node,if null,return -1;
     */
    private int height(AVLNode<AnyType> t) {
        return t == null ? -1 : t.height;
    }

    /**
     * 查找以t为根的子树种的最小值
     * 
     * @author ZFY
     * 
     * @param t
     * @return
     */
    private AVLNode<AnyType> findMin(AVLNode<AnyType> t) {
        /**
         * 递归写法
         */
        if (t == null) {
            return null;
        } else if (t.left == null) {
            return t;
        } else {
            return findMin(t.left);
        }
        /**
         * 非递归写法 if(t!=null){ while(t.left!=null){ t=t.left; } } return t;
         */

    }

    /**
     * 插入一个节点的方法
     * 
     * @author ZFY
     * 
     * @param x
     * @param t
     * @return
     */
    private AVLNode<AnyType> insert(AnyType x, AVLNode<AnyType> t) {
        if (t == null) {
            return new AVLNode<AnyType>(x, null, null);
        }

        int compareResult = x.compareTo(t.element);

        if (compareResult < 0) {
            t.left = insert(x, t.left);
        } else if (compareResult > 0) {
            t.right = insert(x, t.right);
        } else {
            ;
        }
        return balance(t);
    }

    /**
     * 调整不平衡节点的方法.不平衡分为四种情况 1.对X的左儿子的左子树进行一次插入 2.对X的左儿子的右子树进行一次插入
     * 3.对X的右儿子的左子树进行一次插入 4.对X的右儿子的右子书进行一次插入
     * 
     * @author ZFY
     * 
     * @param t
     * @return
     */
    private AVLNode<AnyType> balance(AVLNode<AnyType> t) {
        if (t == null) {
            return t;
        }
        if (height(t.left) - height(t.right) > ALLOWED_IMBALANCE) {
            if (height(t.left.left) >= height(t.left.right)) {
                // 左左==>右旋
                t = rotateWithLeftChild(t);
            } else {
                // 左右==>先左旋再右旋
                t = doubleWithLeftChild(t);

            }

        } else if (height(t.right) - height(t.left) > ALLOWED_IMBALANCE) {
            if (height(t.right.right) >= height(t.right.left)) {
                // 右右==>左旋
                t = rotateWithRightChild(t);
            } else {
                // 右左==>先右旋再左旋
                t = doubleWithRightChild(t);
            }
        }

        t.height = Math.max(height(t.left), height(t.right)) + 1;
        return t;
    }

    /**
     * 左左旋转的方法(即向右旋)
     * 
     * @author ZFY
     * 
     * @param k2
     *            平衡被破坏的节点
     * @return k1 平衡之后的树的根节点
     */
    private AVLNode<AnyType> rotateWithLeftChild(AVLNode<AnyType> k2) {
        AVLNode<AnyType> k1 = k2.left;
        k2.left = k1.right;
        k1.right = k2;
        k2.height = Math.max(k2.left.height, k2.right.height) + 1;
        k1.height = Math.max(k1.left.height, k2.height) + 1;
        return k1;

    }

    /**
     * 右右旋转的方法(即向左旋)
     * 
     * @author ZFY
     * 
     * @param k1
     *            平衡被破坏的节点
     * @return k1 平衡之后的树的根节点
     */
    private AVLNode<AnyType> rotateWithRightChild(AVLNode<AnyType> k1) {
        AVLNode<AnyType> k2 = k1.right;
        k1.right = k2.left;
        k2.left = k1;
        k1.height = Math.max(k1.left.height, k1.right.height) + 1;
        k2.height = Math.max(k2.right.height, k1.height) + 1;
        return k2;

    }

    /**
     * 左右旋转的方法 即 先调用右右旋转的方法,在调用左左旋转的方法
     * 
     * @author ZFY
     * 
     * @param k3
     *            平衡被破坏的节点
     * @return 平衡之后的树的根节点
     */
    private AVLNode<AnyType> doubleWithLeftChild(AVLNode<AnyType> k3) {
        k3.left = rotateWithRightChild(k3.left);
        return rotateWithLeftChild(k3);
    }

    /**
     * 右左旋转的方法 即 先调用左左旋转的方法,在调用右右旋转的方法
     * 
     * @author ZFY
     * 
     * @param k3
     *            平衡被破坏的节点
     * @return 平衡之后的树的根节点
     */
    private AVLNode<AnyType> doubleWithRightChild(AVLNode<AnyType> k1) {
        k1.right = rotateWithLeftChild(k1.right);
        return rotateWithRightChild(k1);
    }

    private AVLNode<AnyType> remove(AnyType x, AVLNode<AnyType> t) {
        if (t == null) {
            return t;
        }

        int compareResult = x.compareTo(t.element);

        if (compareResult < 0) {
            t.left = remove(x, t.left);
        } else if (compareResult > 0) {
            t.right = remove(x, t.right);
        } else if (t.left != null && t.right != null) {
            t.element = findMin(t.right).element;
            t.right = remove(t.element, t.right);
        } else {
            t = (t.left != null) ? t.left : t.right; // 用t.left或者是t.right取代t
        }
        return balance(t);
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值