平衡二叉树的左旋和右旋

article/2025/9/29 15:28:24

文章目录

  • 复习树
    • 1. 树的概念
    • 2. 二叉树(Binary Tree)
    • 3. 满二叉树
    • 4. 完全二叉树
    • 5. 二叉堆
    • 6. 二叉搜索树
  • 左旋和右旋
    • 7. 平衡二叉树(平衡二叉搜索树)

本文章是我的库存文章,本来不发的,但还是发吧,请跳到第7节,那才是讲左旋和右旋的。至于前面的复习树要看也可以,只是一堆概念,并不复杂。

复习树

1. 树的概念

  生活中的树跟程序中的树其实大同小异,比如生活中的树是不是有树根,在树根的基础上是不是会有分叉,而在这些分叉中是不是也可能会继续分叉,而在这些分叉上是不是也可能会生出叶子。
  对比第一段的描述,程序中的树也是如此,它也有根,也会分叉,当然也有叶子。只不过它是倒着的树,如下:

图1:

术语:

  • 结点:就是图1的每一个元素。
  • 前件/后件:以图1为例,元素2的前件就是元素5,后件就是元素1和元素3。
  • 根结点:在树结构中,只有一个结点没有前件,该结点就为根结点。比如图1的数字5,可以把它想象成一个倒着的树,既然是倒着的,那么树根是不是就在上面。
  • 父结点:在树结构中,每个结点只有一个前件,这个前件就是该结点的父结点。
  • 子结点:在树结构中,每个结点可以有多个后件,这些后件就是该结点的子结点。
  • 叶子结点(终端结点):在树结构中,没有后件的结点称为叶子结点(生活中的叶子不能分叉)。
  • 分支结点(非终端结点):除了叶子结点以外的结点。
  • :树中一个结点的子结点个数称为该结点的度,树中结点的最大度数称为树的度。
  • 树的深度:在树结构中,根结点所在的层次为1,其他结点所在的层次为其父结点所在的层次加1,最大的层次称为树的深度。
  • 子树:以图1为例,整个就是一颗树,那么在这颗树中又可拆分为一个子树,就好像在生活中你拔了一根树枝回家当玩具,插在泥土上,然后指着它对你的朋友说:“你看,它是一颗树”。所以,在图1中,我们能不能把它中的元素为2,1,3的结点拆分出来成为它的一颗子树?那么相应的,结点为8和7的也可以拆分出来成为一颗子树。

注意:
  一个结点也可以是一个树,也就是该树的度为0。

2. 二叉树(Binary Tree)

  二叉,二叉,顾名思义就是一个结点分了两个叉,叫二叉,但是注意,不是一定就要分两个叉,你分一个叉,甚至不分叉都可以,就是不能分两个叉以上的叉,比如三叉肯定不行,也就是说,要满足二叉树的话,你的度就只能是0,或者1,或者2
  二叉树是在树的概念上延伸出来的,它规定了你这个结点最多只能有两个子结点,通常一个在左,一个在右,那么我们就把在左边的那个结点称为左子树,右边的那个结点就是右子树,注意,这种左右子树只存在二叉树中,比如你来个四叉树我怎么给它分左右子树。还有最后注意次序不能颠倒,也就是说它是严格分左右的,左就是左,右就是右,即使你这个结点只有一个子树,也要分左右。

存储结构:
  二叉树的存储结构分为顺序存储和链式存储:

  • 顺序存储:二叉树的顺序存储就是用一组连续的存储单元存放二叉树中的结点元素,一般按照自上而下,自左向右的顺序存储。以图1为例,就是528137。但是注意,如果有空元素,要为空元素留出空间。
  • 链式存储(*):二叉树的链式存储结构是用一个链表来存储一颗二叉树,二叉树中每一个结点用链表的一个链结点来存储。在二叉树中,结点结构通常包括若干数据域及若干个指针域,在二叉链表中至少包括三个域:

遍历:

  • 先序遍历:先访问根结点,其次遍历左子树,最后遍历右子树。以图1为例,结果为:521387。
  • 中序遍历:先遍历左子树,其次访问根结点,最后遍历右子树。以图1为例,结果为:123578。注意结果为有序的,但只满足二叉搜索树,后面会介绍。
  • 后序遍历:先遍历左子树,其次遍历右子树,最后访问根结点。以图1为例,结果为:132785。

 注意,对于中序遍历,有如下术语:

  • 前驱结点:对二叉树的中序遍历,遍历后的顺序,当前结点的前一个结点为该结点的前驱结点。
  • 后继结点:对二叉树的中序遍历,遍历后的顺序,当前结点的后一个结点为该结点的后继结点。

3. 满二叉树

  如下图:
在这里插入图片描述

图2:
  图2就是一个满二叉树,对比普通的二叉树,它有什么特点?

  不用说,二叉树的特点它都有,那么至于它为什么叫满二叉树,就是因为它的每一个结点,除了叶子结点都有两个子结点,并且每一层都满足最多的子结点数(每一层都填满)。像这种树就叫满二叉树。同时因为每一层都要填满,所以所有的叶子结点都在最下一层。最后注意满二叉树的每个结点的度要么是0,要么是2,不能为1。

4. 完全二叉树

  如下图:
在这里插入图片描述

图3:
特点:
  • 完全二叉树就是指除了最后一层之外,其它每一层的结点数都是满的。
  • 对任意一结点,如果其右子树的最大层次为L,则其左子树的最大层次为L或L+1(子树必须向左对齐,右子树不能单独存在,也就是说,必须先左子树,再右子树。或者说,最后一层的结点是自左向右依次排序的)。
    在这里插入图片描述
图4:

  以上就不属于完全二叉树。因为元素0027是元素0026的右子树,而右子树是不能独立存在的,如果把元素0027换成左子树就可以。

  • 度为1的结点只有0或1个。

5. 二叉堆

  二叉堆在完全二叉树的基础之上,增加了节点取值的限制条件,分为两种堆,最大堆和最小堆。

  • 最大堆:各个父结点的值总是大于或等于任何一个子结点的值。
  • 最小堆:各个父结点的值总是小于或等于任何一个子结点的值。

如下就是最小堆:

图5:

  看根结点0,它有两个子结点分别是1和3,根据最小堆的概念,0是不是小于1和3?是不是满足条件,然后再继续看元素为1的结点,它也一样有两个子结点为4和2,根据概念,1是不是小于4和2?依次类推,只要全部满足那么这颗树就是二叉堆。

6. 二叉搜索树

  二叉搜索树又叫二叉查找树或二叉排序树,是一颗特殊的二叉树,那么要成为一颗二叉树要满足哪些条件?如下:

  • 左子树不空,则左子树所有结点值均小于或等于该结点的值。
  • 右子树不空,则左子树所有结点值均大于或等于该结点的值。
  • 左右子树也是二叉搜索树。

  说白了就是一个结点它的左子树是小于或等于它的,而它的右子树是大于或等于它的。
  还记得中序遍历吧,只有二叉搜索树进行中序遍历的结果才是有序的,也就是说,图1就是一个二叉搜索树。
  比如有这么一行数,为256174,那么我们怎么用二叉搜索树来存储呢?如下:

图6:

  你还可以对上图进行中序排序,看看是不是124567。结果就是有序的。
  所以假如有这么一行数据,1234567,缺点是不是暴露出来了呀,是不是二叉树就被退化成一个链表呀!那怎么办呀,这就要引入一个平衡二叉树了。

左旋和右旋

7. 平衡二叉树(平衡二叉搜索树)

  平衡二叉树又称为AVL树,于1962年首次提出。有如下特点:

  • 左右子树深度之差的绝对值不超过1。最高层-最底层<=1,所以平衡二叉树只是相对平衡。
  • 左右子树仍然为平衡二叉树。

  衡量是否为平衡二叉树,引入一个概念,平衡因子:定义结点左子树与右子树的高度差为该结点的平衡因子,平衡因子的值只可能是-1(右子树比左子树高1),0(一样高),1(左子树比右子树高1)。如果不是这3个数,比如2,那就说明你这颗树不平衡了。如下图:

图7:
  图7每个结点要么是0,要么是-1或1,并不存在大于1的或小于-1的情况,所以图7这颗树就是平衡二叉搜索树。那么非平衡的例子就是图6了,为什么图6非平衡呢?如下:   那问题来了,如何解决这个问题呢?要解决这个问题就要涉及到旋转的知识了,这个知识点我也是花了两个小时才琢磨出来它是怎么转的,其实很简单。首先要知道有如下四种情况,如下:

  也就是说,遇到问题,首先要分析它是上图中的哪一种情况,因为到时候调整会有左旋右旋之分,包括调整次数,我说明一下,上图LL和RR只需要调整一次,而LR和RL要调整两次才平衡。那么好,我们就对图6进行调整,首先,看到图6这张图,根据平衡因子计算,它不平衡,要调整,ok,没问题,那怎么调,看,它是上图4种的哪一种?怎么看?比如图6,是怎么导致不平衡的,你是不是要找出来,谁?是不是元素7的加入导致树的不平衡?你可以把元素7干掉,是不是就是平衡树,那么我们是不是找到罪魁祸首了呀,那么好,根据我上图说的4种情况的概念出发,它是不是属于RR情况,你读呗,括号里我是不是写了当根节点右子树的右子树有节点插入,导致二叉树不平衡。所以明白了吧,而且我也说了,RR只需要调整一次即可平衡,所谓的调整就是你要么左旋要么右旋,那么到底是左旋还是右旋呢?你可以想一下天平秤,如下:
  你就把中间的那个分度盘看作是根结点,横梁的两边就分别是左子树和右子树,你看上图。右边的那个横梁是不是往下跑了呀,是不是就说明了右边的东西重一点,那么为了保持平衡,你是不是下意识的会用你的手去拖你右边的那个托盘往上托,让它跟左边的横梁保持在一条直线上,是不是?那就没问题了,我们现在要解的这道题,就跟图上那个天平秤一样,往上托,也就是逆时针,准确讲就是左旋,是不是so easy。所以如下:
  图画的有点丑啊,没关系,将就的看吧。好,回到正题,也就是说以根节点(分度盘)为圆形,右子树往上托,那么就会造成右子树的根结点成为整个树的根结点,原来的根结点就会沦为小弟成为右子树的根结点的左子树,既然原来的根结点都沦为给别人当小弟了,那么大哥是不是要表示表示,那么大哥就会把它原来的左子树也就是上图中的元素4给元素2,成为它的右子树,所以上图我们是不是要改造一下呀,不然就不叫二叉,直接叫三叉吧,如下:
  这样不就平衡了吗?是不是简单易懂,那么相应的,LL调整就是反过来的,什么旋,右旋,这我就不说了,看第二种情况,如下:
  别冲动,别一看到右边的多,就着急往上托,要先分析,它属于上述4种情况的哪一种情况?我们先看上图,为了保持平衡我们是不是得把元素8的结点给坎了呀,所以,再结合4种情况的每一个概念分析,比如先从根结点出发,然后走子树,再走右子树的子树,那么你明白了吗,是不是就是RL调整呀,而且我还说了,只要是RL或LR就要经历两次调整,也就是两次旋转,你能像第一种情况那样直接就左旋吗,肯定不行,不信你试试,在草稿纸上画一画,我就懒得在电脑上画一遍了。那怎么搞?首先,问题是不是出在右子树上?那么我们就只针对右子树,也就是如下:
  那么我们就要对它采用右旋,如下:
  这是不是做了一次调整呀,然后再结合剩下的两个元素,如下:
  不过这样还没有平衡哦,还是一样分析是哪一种情况,再做最后一次调整就行了,经过分析,它属于RR调整这个情况,所以右子树整体往上移,怎么移,说过了,要是不会移就说明我的第一种情况你没看懂。
  最后注意,以上几种情况是边添加数据边调整的。

注意(后期整理):
  在后面重新查看的时候,发现少说了一点,就是最小平衡因子,所以这里补上,有如下图:
  如上图,罪魁祸首就是元素5的加入导致的不平衡,没问题,但还有一个问题,图上有两个结点也就是元素2和3它们的平衡因子都是-2,也就是出现了两个不平衡的因子,那听谁的?结果应该是听元素3的,因为所谓的最小平衡因子就是找离罪魁祸首(元素5)最近的不平衡元素,是不是元素3呀,元素3是不是离元素5近,所以,我们在调整的时候就应该调整以元素3为根节点的子树,也就是如下:
  再结合剩下的两个元素1和2,最终结果如下:


http://chatgpt.dhexx.cn/article/rkirWsjH.shtml

相关文章

HashMap-红黑树插入平衡、左旋、右旋源码解析

目录 一、树的演变 二、红黑树 1.红黑树的特点 2.树左旋右旋的过程 3.红黑树插入节点情景分析&#xff1a; 三、HashMap插入平衡、左旋、右旋源码解析 1.添加值 2.插入平衡 3.左旋、右旋 一、树的演变 为什么会有树&#xff0c;因为链表的查询效率是logOn,树的查询效率…

HashMap底层实现原理:红黑树左旋右旋

HashMap中的红黑树左旋、右旋&#xff1a; 一、什么是左旋、右旋&#xff1a; 红黑树的性质&#xff1a; 每个节点要么是黑色&#xff0c;要么是红色根节点是黑色每个叶子节点&#xff08;NIL&#xff09;是黑色每个红色结点的两个子结点一定都是黑色任意一结点到每个叶子结点…

平衡二叉查找树(AVL)的构建——左旋右旋

原文链接&#xff1a;https://www.cnblogs.com/ZhaoxiCheung/p/6012783.html 平衡二叉树&#xff0c;又称AVL&#xff08;Adelson-Velskii和Landis&#xff09;树&#xff0c;是带有平衡条件的二叉查找树。这个平衡条件必须要容易保持&#xff0c;而且它必须保证树的深度是 O&…

详解红黑树之左旋右旋

为什么要左旋右旋&#xff1f; 为了使得左右子树的高度差在一定范围内&#xff0c;需要通过旋转调整&#xff0c;这样就可以保持平稳的搜索效率 左旋&#xff1a; 步骤 1.设原来E的父节点是father&#xff0c;那么左旋之后需要改变的是&#xff1a; 2.S和father的关系&#…

avl树左旋右旋的理解

一直没搞懂非平衡二叉树变平衡二叉树时左旋右旋&#xff0c;今天下定决心搞懂&#xff0c;然后在众多博客中终于找到了这样一篇&#xff0c;非常形象&#xff0c;记录如下&#xff1a; AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为一&…

搞懂平衡二叉树的左旋右旋双旋(Java实现)

刚看到韩顺平老师的数据结构与算法对于平衡二叉树的讲解&#xff08;最后会附上地址&#xff09;&#xff0c;有如下理解&#xff0c;希望能帮助大家&#xff01;哪里需要改正的欢迎指正&#xff01; 平衡二叉树&#xff1a;一种二叉排序树&#xff08;BST Binary Sort Tree&a…

图示讲解AVL平衡二叉树的左旋和右旋

AVLTree 高度平衡的搜索二叉树 一棵平衡树&#xff0c;或是空树&#xff0c;或是具有以下性质的二叉搜索树&#xff1a;左子树和右子树都是AVL树&#xff0c;且左右子树的高度之差的绝对值不超过1。 该二叉树&#xff0c;根结点的右子树高度为3&#xff0c;左子树高度为2。…

左右旋对比

目录 前言 一&#xff0c;逆置法 1.1逆置思路 1.2逆置实现 二&#xff0c;左旋和右旋对比 右旋代码分析 特点对比 前言 之前在up主的博客里面已经有过了对于左旋的三种实现方法。当然&#xff0c;如果我们考虑到时间复杂度的问题&#xff0c;那么我们只要一种方法&#xf…

平衡二叉树的左旋右旋详解 看不懂你打我

平衡二叉树的左旋右旋 看不懂你打我 左旋右旋的操作为什么要左旋右旋左旋右旋能保持排序二叉排序树的性质吗下次写平衡二叉树的LL、RR、LR、RL。 左旋右旋的操作 1.左旋&#xff1a;对X节点左旋&#xff0c;即以X的右孩子Y为轴&#xff0c;将X节点转下来&#xff0c;变为Y的左…

二叉树的旋转,左旋和右旋

在AVLTree中经常会有以某个节点为点对子树进行旋转的操作&#xff0c;今天就和大家分享一下什么是二叉树的旋转。 这是一棵二叉树&#xff0c;上图称为图一。 将图一中的树以1为旋转点进行左旋后得到图二&#xff1a; 将图一中的树以1为旋转点进行右旋旋后得到图三&#xff1…

day062:平衡二叉树——左旋、右旋

二叉树、平衡二叉树的介绍&#xff1a;day061&#xff1a;二叉树、二叉查找树、平衡二叉树_ZQyyds&#xff1a;&#xff09;的博客-CSDN博客 目录 一、平衡二叉树的左旋 1.为什么要左旋、右旋&#xff1f; 2.什么是左旋&#xff1f; 3.图解 二、平衡二叉树的右旋 1.什么是…

大型json文件格式化【超简单】

问题 遇到了一个很大的JSON文件&#xff08;约4M&#xff09;&#xff0c;想格式化查看&#xff0c;在线json工具会直接崩溃&#xff0c;网上其他同学说的python方法之类的我也都实验失败&#xff0c;但是发现了vs code中一个超强的代码格式化 解决1&#xff08;2019.2.10更…

Unity存档系统——Json格式的文件

实例场景 点击Save按钮后&#xff0c;查看保存的文件 点击Load按钮后加载文档数据 Json介绍https://www.json.org/json-zh.htmlUnity中自带的JsonUtility可以将可序列化对象与Json格式相互转换。 将对象转为可序列化对象需要添加[SerializeField]&#xff0c;且为public&#…

将json文件格式转化成Excel表格形式

在程序员的工作中&#xff0c;经常有产品或者运营部门的小姐姐需要数据&#xff0c;由于不懂技术&#xff0c;就需要我们将Json格式的数据转换成Excel文档提供给她们进行数据分析。 本文就介绍一个非常简单方便的方法 1.运用的是Excel表格自带的功能 首先打开Excel文件 点击插…

js导出JSON格式文件

在src目录下新建tools文件价&#xff0c;在tools文件中新建index.js(文件内名字随意) 在index.js文件中 const Tools {// 导出文件exportJson(name, data) {let blob new Blob([data]); // 创建 blob 对象let link document.createElement("a");link.href URL.…

json文件

认识一下 json文件 直接使用记事本打开&#xff1a;例如猫狗二分类 一般都使用类似字典的方式存储&#xff0c;但和字典不同&#xff0c;无论是键还是值&#xff0c;都要加上双引号。 json文件的读取与写入 import jsondata {"a":"1","b":&q…

JSON格式校验工具

经常用ApiPost 和 Postman 测试自己写的接口的话&#xff0c;有时会不小心写错传进去的json对象&#xff0c;我们可以用json格式检验工具去检查一下自己json格式。 在线工具&#xff1a;在线 JSON 工具&#xff0c;JSON 校验/格式化/压缩/工具 - 在线工具-wetools.com微工具

python文件处理——JSON格式文件

python文件处理——JSON格式文件 hello&#xff01;我是wakeyo_J&#xff0c;每天一个konwledge point&#xff0c;一起学python&#xff0c;让技术无限发散。 JSON格式文件 python文件处理——JSON格式文件1. JSON格式1.1 JSON常用的两种结构数据类型1.2 JSON数据与python数据…

json文件格式详解

json文件格式详解 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式&a…