avl 平衡二叉树

package com.haojiangbo.avltree;



//AVL二叉查找树
public class AvlTree {

    public Node root;

    public void add(Node node){
        if(null == root){
            root = node;
            return;
        }
        root.add(node);
    }

    public int getHigth(){
        return root.getHigth();
    }

    public int getRigthHigth(){
        return root.rigthHigth();
    }

    public int getLeftHigth(){
        return root.left.leftHigth();
    }

    public Node  get(int v){
        if(null == root){
            return null;
        }
        return root.get(v);
    }
    //中序遍历
    public void  zhongxu(){
        if(null == root){
            return;
        }
        root.zhongxu();
    }

    public AvlTree.Node searhParent(int v){
        if(null == this.root){
            return null;
        }
        else{
            return this.root.searhParent(v);
        }
    }

    public void del(int v){
        if(root == null){
            return;
        }
        Node target =  get(v);
        //如果节点的root节点不存在 说明为根节点    处理根节点的逻辑
        if(target == root){
            if(null == target.left && null == target.rigth){
                root = null;
            }else if(null != target.left && null != target.rigth){
                Node temp = root.left;
                del(root.left.value);
                root.value = temp.value;
            }else{
                if(target.rigth != null){
                    root = target.rigth;
                }else if(target.left != null){
                    root = target.left;
                }
            }
            return;
        }

        Node parent = searhParent(v);

        //被删除节点不是根节点 3种情况的删除方法
        //1 叶子节点  左右子树都为空
        //2 单边节点 左树 或者右树为空值 父节点指向删除节点的子节点
        //3 全树节点 左右节点都不为空的情况   找到当前节点的1级左子树   然后删除  把1级左子树的值替换掉当前节点

        if(target.left == null && target.rigth == null){
            if(null != parent.left && target.value == parent.left.value){
                parent.left = null;
            }else{
                parent.rigth = null;
            }
        }else if(target.left != null && target.rigth != null){
            Node temp = target.left;
            del(target.left.value);
            target.value = temp.value;
        }else{
            if(null != target.left){
                if(null != parent.left && parent.left.value == target.value){
                    parent.left = target.left;
                }else{
                   parent.rigth = target.left;
                }
            }else{
                if(null != parent.left && parent.left.value == target.value){
                    parent.left = target.rigth;
                }else{
                    parent.rigth = target.rigth;
                }
            }
        }
    }

    /**
     * 接地啊对象
     */
    public static class  Node{
        public int value;
        //左叶子节点
        public Node left;
        //右叶子节点
        public Node rigth;
       /* //父节点
        public Node parent;*/

        @Override
        public String toString() {
            return "Node{" +
                    "value=" + value +
                    '}';
        }

        public  Node (int value){
            this.value = value;
        }

        //左子树高度
        public int leftHigth(){
            if(null == left){
                return 0;
            }
            return left.getHigth();
        }

        //右子树高度
        public int rigthHigth(){
            if(null == rigth){
                return 0;
            }
            return rigth.getHigth();
        }

        //树的高度
        public int getHigth(){
            return Math.max(left == null ? 0:left.getHigth()
            ,rigth == null? 0: rigth.getHigth())+1;
        }

        /**
         * 左旋转
         */
        public void leftRotate(){
            //创建新节点已当前根节点的值
            Node newNode = new Node(value);
            //新节点的左子树为当前节点的左子树
            newNode.left = left;
            //新节点的右子树为当前节点右子树的左子树
            newNode.rigth = rigth.left;
            //当前节点的值替换为右子节点的值
            value = rigth.value;
            //当前节点的右子树设置为  右子树的右子树
            rigth = rigth.rigth;
            //当前左子节点设置为新节点
            left = newNode;
        }


        /**
         * 右旋转
         */
        public void rigthRotate(){
            //创建1个新节点
            Node newNode = new Node(value);
            //新节点的右节点 指向当前节点的右节点
            newNode.rigth = rigth;
            //新节点的左节点指向当前节点的左节点的右节点
            newNode.left = left.rigth;
            //当前节点的值 等于左节点的值 等于把当前节点的左节点 删除了
            value = left.value;
            //当前节点的左节点指向左节点的左节点
            left = left.left;
            //当前节点的右节点指向新节点
            rigth = newNode;
        }


        public Node get(int value){
            if(value == this.value){
                return this;
            }
            if(value < this.value && null != this.left){
                return this.left.get(value);
            }else if(value >= this.value && null != this.rigth){
                return this.rigth.get(value);
            }else{
                return null;
            }
        }

        public void  zhongxu(){
            if(null != this.left){
                this.left.zhongxu();
            }
            System.out.println(this.value);
            if(null != this.rigth){
                this.rigth.zhongxu();
            }
        }


        public void  add(Node node){
            if(node.value < this.value){
                if(this.left == null){
                    this.left = node;
                }else{
                    this.left.add(node);
                }
            }else{
                if(this.rigth == null){
                    this.rigth = node;
                }else{
                    this.rigth.add(node);
                }
            }
            //如果右子树减左子树的高度 大于1
            if((rigthHigth() - leftHigth()) > 1){
                if(null != rigth && rigth.leftHigth() > rigth.rigthHigth()){
                    rigth.rigthRotate();
                }
                leftRotate();
                return;
            }
            //此处的判断条件是个非常耗费性能的递归函数 所以上面执行完之后 马上return
            if(leftHigth() - rigthHigth() > 1){
                //如果当前节点的右子树的高度大于左子树高度
                //就先进行一次左旋转
                if(null != left && left.rigthHigth() > left.leftHigth()){
                    left.leftRotate();
                }
                rigthRotate();
                return;
            }

        }

        /**
         * 查找父节点
         * @param v
         * @return
         */
        public AvlTree.Node searhParent(int v){
            if((this.left != null && this.left.value == v)
                    || (this.rigth != null && this.rigth.value == v)
            ){
                return  this;
            }
            if(null != this.left && this.value > v){
                return this.left.searhParent(v);
            }else if (null != this.rigth && this.value <= v){
                return this.rigth.searhParent(v);
            }else {
                return null;
            }
        }

    }



}
发布了11 篇原创文章 · 获赞 1 · 访问量 364

猜你喜欢

转载自blog.csdn.net/qq_37421368/article/details/97316709
今日推荐