二叉平衡树

平衡二叉树

平衡二叉树又称为AVL树
平衡二叉树定义(AVL):它或者是一颗空树,或者具有以下性质的二叉排序树:它的左子树和右子树的深度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。

一棵AVL树有如下必要条件:

条件一:它必须是二叉查找树。
条件二:每个节点的左子树和右子树的高度差至多为1。

不是二叉排序树
左右子树高度差超过1

构建平衡二叉树 单旋转与双旋转

当插入节点是左左(LL)型时

在这里插入图片描述
右右型
在这里插入图片描述左右型
在这里插入图片描述
右左型
在这里插入图片描述

代码实现:
节点类:

public class TreeNode {
    int value;
    TreeNode leftNode;
    TreeNode rightNode;

    public void setLeftNode(TreeNode leftNode) {
        this.leftNode = leftNode;
    }

    public void setRightNode(TreeNode rightNode) {
        this.rightNode = rightNode;
    }

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

    /*
    * 查看高度
    * */
    public int height(){
        return Math.max( leftNode == null ? 0 : leftNode.height(),rightNode == null ? 0 : rightNode.height()) +1;
    }

    /*获取左子树的高度*/
    public int leftHeight(){
        if(leftNode == null){
            return 0;
        }
        return leftNode.height();
    }
    public int rightHeight(){
        if(rightNode == null){
            return 0;
        }
        return rightNode.height();
    }

    /*
    * 向子树中添加节点
    * */
    public void add(TreeNode node) {
        if(node == null){
            return;
        }
        //判断当前节点与该节点的值大小
        if(node.value < this.value){   //如果要小
            //如果当前节点的左子节点为空,就直接添加为左子节点
            if(this.leftNode == null){
                this.leftNode = node;
            }else{  //否则继续递归
                this.leftNode.add(node);
            }
        }
        if( node.value > this.value){    //如果要大
            if(this.rightNode == null){  //如果当前当前节点的右子节点为空,就直接添加为右子节点
                this.rightNode = node;
            }else{  //否则继续递归
                this.rightNode.add(node);
            }
        }
        //判断是否平衡
        //左左不平衡  左边的高度要大于右边的高度
        if((leftHeight() - rightHeight())>= 2){

            //进行双旋转
            if( leftNode.leftHeight() < leftNode.rightHeight()){
                leftNode.leftRotate();//先左旋转,再右旋转
                rightRotate();
            }else{  //单旋转
                rightRotate();
            }

        }
        if((leftHeight() - rightHeight()) <= -2){
            //双旋转
            if(rightNode.leftHeight() > rightNode.rightHeight()){
                rightNode.rightRotate();  //先右旋转再左旋转
                leftRotate();
            }
            //左旋转
            leftRotate();
        }
    }

    private void leftRotate() {
        //创建一个新节点
        TreeNode newNode = new TreeNode(value);
        //将当前节点的值赋给新节点
        newNode.value = value;
        //将当前节点的左子树设为新节点的左子树
        newNode.leftNode = leftNode;
        //将当前节点的右子树的左子树设为新节点的右子树
        newNode.rightNode = rightNode.leftNode;
        //将当前节点的右子节点的值赋给当前节点
        value = rightNode.value;
        //将当前节点的右子节点的右子树赋给新当前节点的右子树
        rightNode = rightNode.rightNode;
        //左子树为新节点
        leftNode = newNode;
    }

    /*
    * 右旋转*/
    private void rightRotate() {
        //创建一个新节点,来存放当前节点的值
        TreeNode newNode = new TreeNode(value);
        //将当前节点的右子树设为新节点的右子树
        newNode.rightNode = rightNode;
        //把当前节点的左子树的右子树设为新节点的右子树
        newNode.leftNode = leftNode.rightNode;
        //将当前节点的值设为左子节点的值
        value = leftNode.value;
        //将当前节点 的左子树设为左子树的左子树
        leftNode = leftNode.leftNode;
        //再把当前节点的右子树设为新节点的树
        rightNode = newNode;
    }


    /*
    * 中序遍历二叉树 顺序从小到大
    * */
    public void InOrder(TreeNode node) {
        if(node == null){
            return;
        }
        InOrder(node.leftNode);
        System.out.print(node.value + " ");
        InOrder(node.rightNode);
    }
}

树:


public class BinarySortTree {
    TreeNode root;

 	/*
    * 查看树的高度
    * */
    public int Height(TreeNode node){
        if(node == null){
            return 0;
        }else{
            return node.height();
        }
    }

    /*
    * 向二叉排序树中插入节点
    * */
    public void add(TreeNode node){
        if(root == null){
            root = node;
        }else{
            root.add(node);
        }
    }

    /*
    *遍历方法
    *  中序遍历
    * */

    public void Inorder(){
       if(root != null){
           root.InOrder(root);
       }
    }
}

测试类:

public class Test {
    public static void main(String[] args) {
        int[] arr = new int[]{1,2,3,4,5,6,7,8};
        int[] arr2 = new int[]{8,9,6,7,5,4};
        int[] arr3 = new int[]{2,1,4,3,5,6};
        int[] arr4 = new int[]{8,9,5,4,6,7};

        BinarySortTree bst = new BinarySortTree();
        for(int i : arr4){
            bst.add(new TreeNode(i));
        }
        System.out.println(bst.root.height());
        System.out.println(bst.root.value);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

且-听风吟.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值