【AVL树】AVL树的插入操作以及旋转

AVL树是二叉搜索树的一种,确保左右子树高度差不超过1以保持平衡。插入新节点后,可能需要通过四种旋转方式(左旋、右旋、左右旋、右左旋)来调整树的平衡。插入操作包括查找插入位置、插入节点、更新平衡因子和进行必要的旋转调整。左右旋和右左旋分别适用于特定的平衡因子组合。
摘要由CSDN通过智能技术生成

在讲解AVL树之前必须了解二叉搜索树,
可以看我之前的博客:二叉搜索树

AVL树是在二叉搜索树的基础上,在向二叉树排序树中插入新的结点,如果保证每个结点的左右子树的高度差的绝对值不超过1,即需要在插入的时候判断是否满足条件,然后对树进行旋转,从而可减低树的高度,减少平均搜索长度。

AVL树:(1)它的左右子树都是AVL树
(2)右子树和左子树的高度差(平衡因子)的绝对值不能超过1 (1 0 -1)。

给出实现AVL树的节点

template<class T>
struct BlancedBianryTreeNode
{
    BlancedBianryTreeNode(T data)
    : _data(data)
    , _bf(0)
    , _pLeft(NULL)
    , _pRight(NULL)
    , _pParent(NULL)
    {}
    T _data;
    int _bf; //平衡因子:右子树的高度-左子树的高度
    BlancedBianryTreeNode<T>* _pLeft;
    BlancedBianryTreeNode<T>* _pRight;
    BlancedBianryTreeNode<T>* _pParent;
};

下面讲解如何向平衡二叉树中插入一个元素, 大神勿喷。
步骤1:如果是空树,插入后即为根节点,插入后直接返回
步骤2:如果树不空,寻找插入位置,若在寻找的过程中找到key,则插入失败直接返回(注:与二叉搜索树的插入操作一样)
步骤3:插入结点,链接到树上,
步骤4:更新平衡因子
步骤5:对树进行调整:旋转

步骤2详解:在找的过程中,需要标记其找入插入位置的父节点pParent,因为在插入新节点pCur的时候,需要判断插入的位置(插入到父节点的左边还是右边)。直接看下面的代码

步骤4详解:插入新元素后该元素的平衡因子为0,但是其父节点的平衡因子可能改变,所以需要更新其平衡因子bf。
如果pCur为父节点pParent的左孩子,则pParent->_bf–;
如果pCur为父节点pParent的右孩子,则pParent->_bf++;
一直向上更新,直到更新到根节点或者父节点的bf为0。
如果父节点的bf为2或者-2的话,就不保持平衡,需要进行旋转。

步骤5详解 旋转有四种旋转方式:左旋,右旋,左右旋,右左旋
(1)左旋分为三种情况:
这里写图片描述


步骤一:先把SubRL链接到pParent上,更新SubRL的父节点,注意SubRL可能为空
步骤二:修改subR,挂到原子树上,注意先得保存pParent的父节点,注意pParent可能为根节点,其父节点为NULL
步骤三:修改pParent,挂接到subR上
步骤四:更新pParent和SubR的平衡因子
从图中可以看出:三种方式的左旋后pParent和SubR的平衡因子都为0。所以旋转后,再更新pParent和SubR的平衡因子。
什么时候左旋:pParent->bf 为2 ,SubR->bf 为1。

代码

    void _RotateL(Node* pParent) //左旋
    {
        Node* SubR = pParent->_pRight; //当前节点pParent的左孩子
        Node* SubRL = SubR->_pLeft; //可能为空
        //先将 SubRL 链接到
        pParent->_pRight = SubRL;
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值