当前位置: 首页 > news >正文

平衡搜索树的左单旋、右单旋、左右双旋、右左双旋

在平衡搜索树中进行插入结点时,有可能会破坏整棵树的平衡。为了保证平衡不被破坏,就要对一些节点进行旋转,从而来降低树的高度,这样也能保证树的平衡。

一、左单旋:

(上图中的▲结点有可能是NULL,也有可能不为空。。。下同)

从图中可以看出,进行左单旋时,只是改变了parent的右指针以及subR的左指针指向。将subR的左子树(subRL)作为parent的右子树,并让parent作为subR的左子树。很明显,这样做就降低了这棵树的高度。

进行旋转时需要注意的两点:

1.改变subRL->_parent指向时,需要判断subRL是否为NULL,如果为空,就不能对其解引用。

2.parent是否为根节点?如果parent为根节点,那么旋转完成后只需将subR赋给根节点即可;但如果parent不为根节点,即parent是某一节点ppNode的子树,就要判断parent在ppNode的左还是右,这样才能确定subR的位置。


void RotateLeft(Node* parent)    //左单旋
    {        
        Node* subR = parent->_right;
        Node* subRL = subR->_left;
 
        parent->_right = subRL;    //先改变parent的右指针
        if (subRL)    //subRL可能为NULL
        {
            subRL->_parent = parent;
        }
 
        Node* ppNode = parent->_parent;
        subR->_left = parent;
        parent->_parent = subR;
 
        if (ppNode == NULL)
        {
            _root = subR;
            subR->_parent = NULL;
        }
        else
        {
            //判断subR应链接在ppNode的左子树还是右子树
            if (ppNode->_left == parent)
                ppNode->_left = subR;
            else
                ppNode->_right = subR;
 
            subR->_parent = ppNode;
        }
    }
二、右单旋:

同左单旋一样,右单旋转是将subL的右子树结点赋给parent的左指针,并让parent自己作为subL的右子树。


    void RotateRight(Node* parent)    //右单旋
    {
        Node* subL = parent->_left;
        Node* subLR = subL->_right;
 
        parent->_left = subLR;
        if (subLR)
        {
            subLR->_parent = parent;
        }
 
        Node* ppNode = parent->_parent;
        subL->_right = parent;
        parent->_parent = subL;
 
        if (ppNode == NULL)    //说明parent结点为根节点
        {
            _root = subL;
            subL->_parent = NULL;
        }
        else
        {
            //如果parent不为根节点,判断其在上一个结点的右还是左
            if (ppNode->_left == parent)
                ppNode->_left = subL;
            else
                ppNode->_right = subL;
 
            subL->_parent = ppNode;
        }
    }
三、左右双旋:

了解了单旋之后,双旋就比较简单,只是进行了两步单旋而已


void RotateLR(Node* parent)        //左右双旋
    {
        RotateLeft(parent->_left);
        RotateRight(parent);
 
    }
四、右左双旋:

    void RotateRL(Node* parent)        //右左双旋
    {
        
        RotateRight(parent->_right);
        RotateLeft(parent);
 
    }


 

相关文章:

  • 二叉查找树(BST)、平衡二叉树(AVL树) 右单旋: 左单旋: 左右双旋: 右左双旋: AVL树查找成功失败计算
  • 树的定义和树的三种存储结构
  • 转置矩阵: 正交矩阵: 阶梯形矩阵 行简化阶梯形矩阵 行最简形矩阵 伴随矩阵的列排问题: 求二阶伴随矩阵简单例子
  • 理解逆矩阵 理解单位矩阵
  • 余子式和余子式 伴随矩阵定义 性质 二阶矩阵求伴随矩阵 伴随矩阵理解(列排)
  • 正交矩阵; 实对称矩阵; 为什么实对称矩阵一定可以对角化; AB=0 r(A)+r(B)<=n 证明; 初等矩阵; 初等矩阵的逆矩阵; 矩阵的左除右除;
  • 矩阵与行列式的区别 行列式简单理解(二三阶)
  • C++ 数学运算, cmath
  • C++中,float double区别
  • setw()函数使用,#include iomanip ——using std::setw;
  • 简单理解数组指针和指针数组
  • 有关指针的基础知识(指针定义和使用) 详解二维数组与指针、指针数组、数组指针
  • 结果真的不是最重要的,过程,体验这个过程,并且持续下去
  • Android Studio Gradle文件解释其作用
  • gradle目录以及sdk目录, ndroid:attr/colorError not found., mupdf使用,api com.artifex.mupdf:fit
  • canvas 五子棋游戏
  • Django 博客开发教程 8 - 博客文章详情页
  • docker python 配置
  • echarts花样作死的坑
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • interface和setter,getter
  • LeetCode算法系列_0891_子序列宽度之和
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • oldjun 检测网站的经验
  • spring boot下thymeleaf全局静态变量配置
  • spring-boot List转Page
  • 产品三维模型在线预览
  • 给第三方使用接口的 URL 签名实现
  • 实现简单的正则表达式引擎
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 我的面试准备过程--容器(更新中)
  • 小程序01:wepy框架整合iview webapp UI
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • 智能合约Solidity教程-事件和日志(一)
  • const的用法,特别是用在函数前面与后面的区别
  • Java数据解析之JSON
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • 从如何停掉 Promise 链说起
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (2022 CVPR) Unbiased Teacher v2
  • (4)(4.6) Triducer
  • (6)设计一个TimeMap
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (机器学习-深度学习快速入门)第三章机器学习-第二节:机器学习模型之线性回归
  • (三)c52学习之旅-点亮LED灯
  • (一)RocketMQ初步认识
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • (转)平衡树
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .NET 应用启用与禁用自动生成绑定重定向 (bindingRedirect),解决不同版本 dll 的依赖问题