C++实现AVL树(四种旋转详解)

本文详细介绍了AVL树的概念、性质以及插入操作,包括左单旋、右单旋、左右双旋和右左双旋四种旋转情况,以保持树的平衡。同时,提到了删除操作可能引发的平衡调整,但未给出具体实现代码。
摘要由CSDN通过智能技术生成

一、概念

AVL树又称为高度平衡的二叉搜索树,它能保持二叉树的高度平衡,尽量降低二叉树的高度,减少树的平均搜索长度。

二、性质

  • 树中每个左子树和右子树都是AVL树
  • 左子树和右子树高度之差的绝对值(简称平衡因子)不超过1(0,1,-1)
    平衡因子就是用右子树的高度减去左子树的高度
    这里写图片描述
    红色的就是每个节点的平衡因子

三、AVL树的插入

如果在一棵原本是平衡的二叉搜索树中插入一个新节点,可能造成不平衡,此时必须调整树 的结构,使之平衡化。

插入算法:

  • 如果是空树,插入后即为根节点,插入后直接返回true
  • 如果树不空,寻找插入位置,若在寻找的过程中找到key,则插入失败直接返回false
  • 插入结点
  • 更新平衡因子,对树进行调整
新节点pcur平衡因子为0,但其双亲结点parent的平衡因子有三种情况:
  • 如果parent的平衡因子为0
    即在parent较矮的子树上插入新节点,parent平衡,其高度没有增加,此时从parent到 根路径 上各结点为根的子树的高度不变,即各结点的平衡因子不变,结束平衡化处理。

  • 如果parent的平衡因子的绝对值为1
    插入前parent的平衡因子为0,插入后以parent为根的子树没有失去平衡,但该子树 的高度增 加,需从parent向根节点方向回溯,继续查看parent的双亲的平衡性。

  • 在上述更新后,如果parent平衡因子的绝对值为2,新节点在较高的子树插入,需要做平衡化处理:
    若parent->_bf == 2,说明右子树高,设parent的右子subR
    当subR的平衡因子为1,执行左单旋转
    当subR的平衡因子为-1,执行先右后左双旋转
    若parent->_bf == -2,说明左子树高,设parent的左子树subL
    当subL的平衡因子为-1,执行右单旋转
    当subL的平衡因子为1,执行先左后右双旋转
    旋转后parent为根的子树高度降低,无需继续向上层回溯

1.左单旋

插入节点位于较高右子树的右侧
如下图所示:
这里写图片描述

    //左单旋
    void RotateL(pNode parent)
    {
        pNode subR = parent->_pRightChild;
        pNode subRL = subR->_pLeftChild;

        parent->_pRightChild = subRL;
        if (subRL)
            subRL->_pParent = parent;

        subR->_pLeftChild = parent;
        pNode pparent = parent->_pParent;
        subR->_pParent = pparent;
        parent->_pParent = subR;

        if (parent == _pRoot)
        {
            _pRoot = subR;
        }
        else//更新祖父节点的左右孩子
        {
            if (pparent->_pLeftChild == parent)
                pparent->_pLeftChild = subR;
            else
                pparent->_pRightChild = subR;
        }
        //更新平衡因子
        parent->_bf = subR->_bf = 0;
    }

2.右单旋

插入节点位于较高左子树的左侧
如下图所示:
这里写图片描述

void RotateR(pNode parent)
    {
        pNode subL = parent->_pLeftChild;
        pNode subLR = subL->_pRightChild;

        parent->_pLeftChild = subLR;
        if (subLR)
            subLR->_pParent = parent;

        subL->_pRightChild = parent;
        pNode pparent = parent->_pParent;
        parent->_pParent = subL;
        subL->_pParent = pparent;

        if (parent == _pRoot)
        {
            _pRoot = subL;
        }
        else
        {
            if (pparent->_pLeftChild == 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值