AVL树之java实现

来源:互联网 发布:qq飞车大黄蜂数据被改 编辑:程序博客网 时间:2024/05/21 10:22

AVL树是自平衡二叉查找树,其实现自平衡原理为旋转。
代码中对应情形如下:
这里写图片描述

java实现代码如下:

/** * Created by Administrator on 2017/4/11. *///AVL树的节点类class AVLNode<T> {    T element;    AVLNode<T> left;    AVLNode<T> right;    int height;//记录高度    //构造器    public AVLNode(T theElement) {        this(theElement, null, null);        element = theElement;    }    public AVLNode(T theElement, AVLNode<T> left, AVLNode<T> right) {        this.element = theElement;        this.left = left;        this.right = right;        this.height = 0;    }}//AVL树public class AVLTree<T extends Comparable> {    //私有属性    private AVLNode<T> root;//根节点    private int height(AVLNode<T> t) {        return t == null ? -1 : t.height;    }    //构造方法    AVLTree() {        this.root = null;    }    //插入操作    public void insert(T x) {        this.root = insert(x, root);    }    //删除操作    public void remove(T x) {        this.root = remove(x, root);    }    //中序打印操作    public void infPrintTree() {        infPrintTree(root);        System.out.println();    }    //判断是否是AVL树    public boolean isAVL() {        return Math.abs(maxDeep(root.right) - maxDeep(root.left)) < 2;    }    public AVLNode<T> findMax(AVLNode<T> t) {        if (t == null)            throw new RuntimeException("this AVLNode is Empty");        if (t.right == null)            return t;        return findMax(t.right);    }    public AVLNode<T> insert(T x, AVLNode<T> t) {        if (t == null)//传入节点为空,则将该节点作为根节点返回            return new AVLNode<>(x, null, null);        int compareResult = x.compareTo(t.element);        if (compareResult < 0)//传入元素x小于t            t.left = insert(x, t.left);        else if (compareResult > 0)//传入元素x大于t            t.right = insert(x, t.right);        return balance(t);    }    //重新进行平衡    public AVLNode<T> balance(AVLNode<T> t) {        if (t == null)            return t;        if (height(t.left) - height(t.right) > 1) {//左插入            if (height(t.left.left) >= height(t.left.right)) //左左插入  情形1                t = singleRightRotate(t);//右旋             else //左右插入           情形2                t = doubleLeftRightRotate(t);//左右双旋        }        if (height(t.right) - height(t.left) > 1) {//右插入            if (height(t.right.right) >= height(t.right.left)) //右右插入    情形3                t = singleLeftRotate(t);//左旋            else //右左插入       情形4                t = doubleRightLeftRotate(t);//右左双旋        }        t.height = height(t.right) > height(t.left) ? height(t.right) + 1 : height(t.left) + 1;        return t;    }    //右单旋    private AVLNode<T> singleRightRotate(AVLNode<T> t) {        System.out.println("进行右旋转==============>>>");        AVLNode<T> r = t.left;        t.left = r.right;        r.right = t;        t.height = height(t.left) > height(t.right) ? height(t.left) + 1 : height(t.right) + 1;        r.height = height(t.right) > height(r) ? height(t.right) + 1 : height(r) + 1;        return r;    }    //左单旋    private AVLNode<T> singleLeftRotate(AVLNode<T> t) {        System.out.println("进行左旋转==============>>>");        AVLNode<T> r = t.right;        t.right = r.left;        r.left = t;        t.height = height(t.left) > height(t.right) ? height(t.left) + 1 : height(t.right) + 1;        r.height = height(t.left) > height(r) ? height(t.left) + 1 : height(r) + 1;        return r;    }    //右左双旋    private AVLNode<T> doubleRightLeftRotate(AVLNode<T> t) {        System.out.println("进行右左双旋==============>>>");        t.right = singleRightRotate(t.right);        return singleLeftRotate(t);    }    //左右双旋    private AVLNode<T> doubleLeftRightRotate(AVLNode<T> t) {        System.out.println("进行左右双旋==============>>>");        t.left = singleLeftRotate(t.left);        return singleRightRotate(t);    }    public AVLNode<T> remove(T x, AVLNode<T> 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 = findMax(t.left).element;            remove(t.element, t.left);        } else //单儿子情形            t = t.left == null ? t.right : t.left;        if (t != null)            t.height = height(t.right) > height(t.left) ? height(t.right) + 1 : height(t.left) + 1;        return balance(t);    }    public int maxDeep(AVLNode<T> t) {        int dl, dr;//记录左右树的深度        if (t == null)            return 0;        else {            dl = maxDeep(t.left);            dr = maxDeep(t.right);        }        return dl > dr ? dl + 1 : dr + 1;    }    public void infPrintTree(AVLNode<T> t) {        if (t == null)            return;        infPrintTree(t.left);        System.out.print(t.element + " ");        infPrintTree(t.right);    }    public static void main(String[] args) {        AVLTree avlT = createAVLTree();        System.out.println("是否是AVL树:" + avlT.isAVL());        System.out.println("中序打印出该树===>>>");        avlT.infPrintTree();        avlT.remove(60);        avlT.insert(35);    }    /**     *              50     *            /    \     *          30      60     *        /   \     *      20     40     *     * @return     */    private static AVLTree createAVLTree() {        AVLTree<Integer> avlT = new AVLTree();        avlT.insert(50);        avlT.insert(60);        avlT.insert(30);        avlT.insert(40);        avlT.insert(20);        return avlT;    }}

下图更详细解释左旋和右旋,本图片为转载:
http://blog.csdn.net/collonn/article/details/20128205

原创博文,转载请注明出处。

0 0
原创粉丝点击