BST(二叉搜索树)转AVL(平衡二叉树)

本文介绍了如何将二叉搜索树(BST)转换为平衡二叉树(AVL树)。通过增加节点高度属性,使用辅助栈进行自底向上检查,并实现左旋、右旋、RL旋和LR旋操作,以及插入和删除后的恢复函数,确保平衡因子的绝对值不超过1,从而保持树的平衡状态。
摘要由CSDN通过智能技术生成

有了之前的BST,我们再其基础上,进行小小的改动即可形成平衡二叉树。
先看二叉平衡树的定义:
具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
要实现它,
首先我们需要为节点,entry新增加一个属性,表示节点的高度,int high。
之后,由于要对树进行自底向上的回溯,检查平衡因子是否符合标准。且我们不存在父节点,故需要一个辅助栈记录我们插入的节点,以便回溯时检查平衡因子。且这个辅助栈是再tree本类中的。
那么,我们新增以下功能:
左旋,右旋,先左后右旋,先右后左旋。
获取高度:
检查平衡因子
插入后恢复函数
删除后回复函数

获取节点的高度 getHight:参数:节点,返回值,高度
因为节点自带高度,故直接返回此节点的高度即可,
检查平衡因子:入参:节点,返回值:平衡因子,
Return Math.abs( getHight(p.left)-getHight(p.right) ).

左旋:

如图,
在这里插入图片描述
插入红色节点之后,顶级节点(笑脸节点)的平衡因子大于等于二,且右子树的深度过大,故需要左旋(笑脸节点的视角):
先获得笑脸节点的右侧节点–>绿色的花草节点,再将花草节点的左侧节点–>彩色(三色节点)赋值给笑脸节点的右侧节点,再将花草节点的左侧节点赋值给笑脸节点
在这里插入图片描述
在这里插入图片描述
如此一来,左旋完成。
右旋(同左旋一致):
在这里插入图片描述
第一步:
在这里插入图片描述
第二步:
在这里插入图片描述
完成。

RL操作:
进行一次右节点的右旋,在对本节点进行一次左旋即可完成。
在这里插入图片描述
LR同RL同理:
进行一次左节点的左旋,再对本节点进行一次右旋操作即可:
在这里插入图片描述
最后是检查平衡因子的函数:
FixAfterInsertion()
;入参为插入节点的key,因为要知道插入左子树还是右子树。
当回溯的辅助栈不为空时:弹栈,令节点的高度变成(左右子树高度的最大者+1),同时,计算平衡因子,左右子树高度的差,若是(假设为节点p)平衡因子的绝对值大于等于2,则进行旋转调平。
分为以下几种情况:
当 左子树高度-右子树高度的差 时:
平衡因子为-2则说明插入的是p节点的右子树,
继续判断插入key值与p节点右子树的key值的权重大小
若大于:表示应该为:左旋操作,执行左旋,并令p的右子树等于左旋的返回值。
在这里插入图片描述
若小于,则表示应该先右旋再左旋,执行RL操作,并令p的右子树等于RL的返回值。
平衡因子为2则说明插入的是p节点的左子树
继续判断插入key值与p节点左子树的key值的权重大小
若小于:表示应该为:右旋操作,执行右旋,并令p的左子树等于右旋的返回值。

若大于,则表示应该为:执行LR操作,并令p的左子树等于LR的返回值。

以上,我们就完成了平衡树的增加操作了,同时在增加时记录增加的路径,再增加节点后调用本方法即可。
接下来是删除操作后的回复方法。

写一个fixAfterDeletetion方法,入参为节点实例,
自顶向下检查,若发现平衡因子大于二(此处我的计算方式为右子树高度减左子树高度…)
当因子为2时,表明删除的是左子树,
当右子树的平衡因子大于等于0时,需要左旋
当右子树的平衡因子小于0时,需要进行RL旋转。
当因子为-2时,表明删除的是右子树,
当左子树的平衡因子小于0时,需要右旋
当左子树的平衡因子大于等于0时,需要进行LR旋转。
再删除节点后调用本方法即可。
总体的代码如下:

AVLTREE:

public class AVLTree<K,V> implements Iterable<Entry<K,V>>{
    private static final int MAX = 16;
    private Entry<K,V> root;
    private Comparator<K> comparator;
    private int size;
    private LinkedList<Entry<K,V>> stack;

//    TreeMap
    public AVLTree() {
        size = 0;
        stack = new LinkedList<>();
    }
    public AVLTree(Comparator<K> comparator) {
        this.comparator = comparator;
        size = 0;
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值