AVL树-平衡树

我们先来分析AVL的高度
在这里插入图片描述

node.heigh= Math.max(getHeigh(node.left),getHeigh(node.right))+1;`

首先,我们向二叉树插入数据18和45,插入18的时候,根据上述代码,我们从20的左右子节点找到一个高度最高的,也就是30
所在的位置高度1,然后再+1得到20节点所在的高度。我们再插入45的时候,取30左右子节点的最大高度,30的左子节点为null,所以右子节点高度为1,也就是30的高度为2.此时回溯到20节点,20节点的左右子节点最大节点为30高度为2,再加1就是3了。再回溯到根节点15.。。
其实从上面不难看出,我们只要求左右节点的最大高度,然后再加上本身节点的具有的高度1,就的得到了节点的高度,然后依次回溯

我们再来分析平衡因子

在这里插入图片描述
首先,这是一棵平衡二叉树,平衡因子就是在二叉树中,左子树的高度和右子树的高度差不可能超过1.

在这里插入图片描述

如果我们任由平衡因子增大,也就是左右子树的增大,那么就会出现链表化的情况,导致查找成本增加,O(logN)的时间复杂度会退化成O(n)时间复杂度如下图所示:
在这里插入图片描述

           int balance = Math.abs(getBalance(node));
            if (balance!=1){
                System.out.println("不平衡");
            }
            return node;
        
        public int getBalance(Node node){
              if(null=node)
              return 0;
             return  getHeigh(node.left)-getHeigh(node.right);
        }

在这里插入图片描述
旋转后就变成这样
在这里插入图片描述
右旋转代码

     public Node rightRoate(Node node){
            Node x=node.left;
            Node T=x.right;

            x.right=node;
            node.left=T;
            //这里的+1 只是重新计算,并不是意味着直接+1
            node.heigh=Math.max(getHeigh(node.left),getHeigh(node.right))+1;
            x.heigh=Math.max(getHeigh(x.left),getHeigh(x.right))+1;
            //这里很巧妙的用到了 return node 作为上个栈帧对象引用赋值
             return x;
        }

左旋转
在这里插入图片描述

  public Node leftRoate(Node node){
             Node x= node.right;
             Node T=x.left;

             x.left=node;
             node.right=T;
           node.heigh=Math.max(getHeigh(node.left),getHeigh(node.right))+1;
           x.heigh=Math.max(getHeigh(x.left),getHeigh(x.right))+1;
           return x;
       }

返回值很有意义,直接更新在树形结构上的结点。
AVL树代码

static class BST{
        Node root;

        //root结点
        public BST(Node root){
                this.root=root;
        }
        //插入操作
        private Node insert(Node node,int data){
             if (null==node){
                 return new Node(data);
             }

             if (node.data>data){
               node.left=insert(node.left,data);
             }else if (node.data<data){
                 node.right=insert(node.right,data);
             }
            node.heigh= Math.max(getHeigh(node.left),getHeigh(node.right))+1;

            int balance = getBalance(node);
            //LL
            if (balance<-1&&getBalance(node.right)<=0){
               return   leftRoate(node);
            }
            //RR
            if (balance>1&&getBalance(node.left)>=0){
               return rightRoate(node);
            }
            //LR
            if (balance>1&&getBalance(node.left)<0){
                node.left=leftRoate(node.left);
                return rightRoate(node);
            }
            //RL
            if (balance<-1&&getBalance(node.right)>0){
                node.right=rightRoate(node.right);
                return leftRoate(node);
            }
            return node;
        }
        public int getBalance(Node node){
            if(node == null)
                return 0;
             return  getHeigh(node.left)-getHeigh(node.right);
        }
        public Node rightRoate(Node node){
            Node x=node.left;
            Node T=x.right;

            x.right=node;
            node.left=T;
            //这里的+1 只是重新计算,并不是意味着直接+1
            node.heigh=Math.max(getHeigh(node.left),getHeigh(node.right))+1;
            x.heigh=Math.max(getHeigh(x.left),getHeigh(x.right))+1;
            //这里很巧妙的用到了 return node 作为上个栈帧对象引用赋值
             return x;
        }

       public Node leftRoate(Node node){
             Node x= node.right;
             Node T=x.left;

             x.left=node;
             node.right=T;
           node.heigh=Math.max(getHeigh(node.left),getHeigh(node.right))+1;
           x.heigh=Math.max(getHeigh(x.left),getHeigh(x.right))+1;
           return x;
       }
       public int getHeigh(Node node){
            if (node==null){
                return 0;
            }
            return node.heigh;
       }
       //插入操作
       public void insert(int data){
            insert(root,data);
       }
    }

RR、LL、RL和LR

RR 不平衡节点 后连续两个都是右子节点 只要左旋转
LL 不平衡节点 后连续两个都是左子节点 只要右旋转
RL 不平衡节点 先右后左 节点 先右旋转再左旋转
LR 不平衡节点 先左后右 节点 先左旋转再右旋转

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值