平衡二叉排序树AVL介绍

为甚么要诞生平衡二叉排序树?
因为一般的二叉树,面对有序数组,会变得很畸形。
在这里插入图片描述
这种就是畸形而且诡异的东西。

平衡二叉树的核心是要平衡,一个二叉排序树如果不平衡,我们需要通过旋转的方式让它变得平衡,不然肯定不行啊同志。
在这里插入图片描述
一定要清楚知道二叉树的,左右高度。
在这里插入图片描述
左右高度差,小于2就是平衡的,大于2就不平衡了。
在这里插入图片描述
先进行分类一共4个分类
找到出问题那个节点的父亲节点,你的孩子影响了高度,你就要承担责任·,需要找到父亲节点。
找到出问题节点的父亲节点。然后根据父亲节点的位置,判定是什么问题类型?是rr?rl?ll ?还是Lr
这种是左子树比右子树长
这个分类主要是看,哪个树,孩子,影响了高度问题。
出问题的节点就是那个影响了,深度的节点。
比如ll,
在这里插入图片描述
在这里插入图片描述
确定好影响二叉树高度的那个点,看看那个需要被修剪的枝叶是在根节点的左左,还是右右。上图明显是左左。

需要通过旋转来进行,让二叉树平衡起来。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
前面都是左边树太多,要通过右旋转,解决问题


这种属于右边太多,右旋解决问题。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
直接这么解决左旋不就完了???
在这里插入图片描述
两种最复杂情况
在这里插入图片描述
先右旋,再左旋,丢给别人去背锅。让部下背锅
右旋之后,实际上已经变成了rr情况,这样左旋就行了。

在这里插入图片描述
左旋转步骤
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
原来的6这个节点,没有指向,所以会被垃圾回收掉。
不过这种方法很傻逼,我觉得前文提到的那个就鸠占鹊巢,才是,最好的解决方案
这就是鸠占鹊巢,之所以要让6继承4的领地,是因为4的领地是有上面的指针直接指向的,你要直接让6继承4的一切势力范围,包括4背后的东西,你都要继承过来,最好的办法就是你自己带上9筒,装成4的样子,这样才能把4背后东西都继承过来。
直接让根节点的右指针指向右子树的左节点
然后让右子树的左指针指向自己不就完了。?
在这里插入图片描述
本质还是,4带着小弟3,去占领了,6的小弟5的位置,5只能委屈巴巴的当了4的小弟,而6伪装成了4的样子,带上9筒,装成了4。
在这里插入图片描述
在这里插入图片描述

比如上图这种直接这样解决就行。
在这里插入图片描述
调整的就是红线部分
最重要的是,还要把指在

这就是比较简单的左旋。

二叉树介绍

package org.example.sort;

public class HeroNode{
    //实现这个接口之后,可以按照你想要方式进行排序
    public  int no;

    public  HeroNode left;
    public  HeroNode right;

    public HeroNode(int no) {
        this.no = no;

    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public HeroNode getLeft() {
        return left;
    }

    public void setLeft(HeroNode left) {
        this.left = left;
    }

    public HeroNode getRight() {
        return right;
    }

    public void setRight(HeroNode right) {
        this.right = right;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", left=" + left +
                ", right=" + right +
                '}';
    }

    public HeroNode() {
    }

    public void infoxOrder(){
        if(this == null){
            return;
        }
        //中序遍历
        //左根右
        if(this.left != null){
            this.left.infoxOrder();
        }

        System.out.print(this.no + "   ");

        if(this.right != null){
            this.right.infoxOrder();
        }
    }

    //根节点交给树里面那个方法去进行判断,我不管了
    //默认进来就是好的
    public HeroNode delNode(HeroNode parent,int typeflag,int value){//带着父节点进来
        //typeflag确保我们知道父亲是往哪里递归的
        //typeflag = 1往左递归,0往右递归

        if(this == null){
            return new HeroNode(-1);
        }

        else if(this.no == value){
            if(typeflag == 1){//父类向左递归过来
                parent.left = this.left == null ? this.getRight() : this.getLeft();
                //如果子节点左边为空,那就等于右节点
            }
            else {
                //父类向右递归过来的
                parent.right = this.left == null ? this.getRight() : this.getLeft();

            }
            return this;
        }

        else if(this.no >= value){
            //往左递归
            parent = this;//递归前保留当前节点作为父亲节点
            typeflag = 1;
            if(this.left == null){
                return new HeroNode(-1);
            }
            return this.left.delNode(parent,typeflag,value);
        }

        else if(this.no < value){
            parent = this;
            typeflag = 0;
            if(this.right == null){
                return new HeroNode(-1);
            }
            return  this.right.delNode(parent,typeflag,value);
        }

        return new HeroNode(-1);


    }




//    //树的高度就是递归看
//    //每一棵树的高度都是,向左递归看到左子树,向右递归看看右子树,
//    public int height(){
//        //树的高度题目
//        //输的高度本质就是看看左子树,和右子树深度,返回最大那个值
//        return Math.max(this.left == null ? 0 : this.left.height(),this.right == null ? 0 : this.right.height()) + 1;//
//

    //查一下左子树的高度



    //前面二叉树哪里,会处理一下High初始值得问题的
    public int height(int high){//代表高度
        int resultHigh;//作为返回结果的高度
        int leftHight = 0;//代表左子树高度
        int rightHight = 0;//右子树高度

        if(this.left == null && this.right == null){
            //循环终止条件
            resultHigh = high;//左右子树都为null那么就返回当前深度
        }

        else{
            if(this.left != null){
                //递归得到左子树高度
                leftHight = this.left.height(high + 1);//每次递归深度加1

            }

            if(this.right != null){
                //递归得到右子树高度
                rightHight = this.right.height(high + 1);
            }
            resultHigh = Math.max(leftHight,rightHight);//每个节点都是一颗二叉树,比较一下,左右子树高度然后返回高度
        }
        return resultHigh;
        //向左向右递归,得到左右子树高度
        //然后进行比较
    }

    //对头节点左旋转,麻烦的在于还要估计,被旋转的根节点上面还有人,所以我们只能给他带上9筒。让他继承实力范围。
    public void leftRotate(){
        //左旋转
        HeroNode newNode = new HeroNode(this.no);//创建新节点,将原来根节点值放进去
        newNode.left = this.left;
        newNode.right = this.right.left;

        this.no = this.right.no;//带上9筒,开始伪装
        this.right.left = newNode;
        this.right = this.right.right;



    }

    //添加进去一个节点
    public void add(HeroNode node){
        if(this == null){
            return;//递归终止条件
        }
        //传递进来这个Node要自己找位置
        //添加一个节点
        //先判断一下和根节点的关系
        if(this.no <= node.no){
            if(this.right == null){
                this.right = node;//大于根节点,并且根节点右边空着,直接挂上去
            }
            else
                this.right.add(node);//否则当前节点带着Node向右递归
        }

        else{
            if(this.left == null){
                this.left = node;
            }
            else
                this.left.add(node);
        }

        //添加完一个节点之后,如果右子树比左子树高,那么直接左旋


    }
}

红黑树本质就是自平衡二叉树,就是每次加入一个节点之后,树都会自我遍历深度,倘若不平衡,会通过自我旋转来让树变成平衡二叉树。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
平衡二叉排序树转换为平衡二叉排序树的常用方法是通过旋转操作来调整树的结构。以下是一种常见的方法,称为AVL树的自平衡操作: 1. 确定不平衡节点:首先,需要确定平衡二叉排序树中的不平衡节点。可以通过计算节点的平衡因子来判断是否平衡平衡因子是指节点的左子树高度减去右子树高度的值。 2. 执行旋转操作:根据不平衡节点的情况,执行相应的旋转操作来调整树的结构。有四种基本的旋转操作: - 左旋(LL旋转):当不平衡节点的左子树高度大于右子树高度,并且左子树的左子树高度大于等于左子树的右子树高度时,执行左旋操作。 - 右旋(RR旋转):当不平衡节点的右子树高度大于左子树高度,并且右子树的右子树高度大于等于右子树的左子树高度时,执行右旋操作。 - 左右旋(LR旋转):当不平衡节点的左子树高度大于右子树高度,并且左子树的右子树高度大于左子树的左子树高度时,执行左右旋操作。 - 右左旋(RL旋转):当不平衡节点的右子树高度大于左子树高度,并且右子树的左子树高度大于右子树的右子树高度时,执行右左旋操作。 3. 递归调整:对于执行了旋转操作的节点,需要递归地向上调整,直到根节点,以确保整棵树的平衡性。 需要注意的是,转换平衡二叉排序树平衡二叉排序树可能会导致树的结构发生变化,因此在进行转换之前,需要考虑是否有必要进行转换以及转换后对应用程序的影响。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值