热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

原理分析_红黑树原理分析

本文由编程笔记#小编为大家整理,主要介绍了红黑树原理分析相关的知识,希望对你有一定的参考价值。
本文由编程笔记#小编为大家整理,主要介绍了红黑树原理分析相关的知识,希望对你有一定的参考价值。




























在理解红黑树之前,先对二叉查找树进行一个简单的介绍。















1、二叉查找树























二叉查找树的特性如下:


1.左子树上所有结点的值均小于或等于它的根结点的值。


2.右子树上所有结点的值均大于或等于它的根结点的值。


3.左、右子树也分别为二叉排序树。


例如,在下图的二叉查找树中查找元素10,查找的结点依次为:9、13、11、10,利用了二分法的思想,提高了查找的效率。





红黑树原理分析



但是二叉查找树也存在缺点。例如,在下图中插入结点7、6、5、4、3,得到结果:





红黑树原理分析




红黑树原理分析



从这种情况可以看出,明显存在左子树和右子树深度相差过多,想要查找3的位置就需要每一次都遍历下一个左子树,很有可能时间复杂度变为n(与数组普通查询的时间复杂度相同)。基于上述情况,引入了平衡二叉树,红黑树即为平衡二叉树的一种。














红黑树原理分析





2、红黑树的特性























红黑树是一种自平衡二叉查找树,在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。


它的左右子树高差有可能大于1,所以红黑树不是严格意义上的平衡二叉树(AVL),但对其进行平衡的代价较低,因此性能要强于AVL。


由于每一颗红黑树都是一颗二叉排序树,因此,在对红黑树进行查找时,可以采用普通二叉排序树的查找算法,在查找过程中不需要颜色信息。红黑树有5个特性:


1.所有结点是红色或黑色。


2.根结点为黑色。


3.每个叶结点都是黑色的空结点。


4.每个红色结点的两个子结点都是黑色。


5.从任一结点到其每个叶子结点的所有路径都包含相同数目的黑结点。


下图为一个典型的红黑树。





红黑树原理分析













红黑树原理分析





3、红黑树的插入操作























1、插入元素的时候,可能会导致红黑树的结构破坏,有2种基本操作:变色和旋转。


(1)变色:将红色结点变为黑色,或将黑色结点变为红色。


(2)旋转:左旋转和右旋转。(以实例进行说明)


左旋转:以X为轴进行左旋,使X的右孩子Y旋转到X的位置,而X作为新局面中Y的左子树,且原来Y的左孩子b作为了新局面中X的右孩子。





红黑树原理分析



右旋转:以X为轴进行右旋,使X的左孩子Y旋转到X的位置,而X作为新局面中Y的右子树,且原来Y的右孩子c作为了新局面中X的左孩子。





红黑树原理分析



2、红黑树插入新结点的5种情况


注意:插入节点的时候,新插入的结点为红色。因为插入红色结点后树的性质可能不会改变,而插入黑色节点每次都会违反特性5。因此将红黑树的新插入的结点默认颜色设置为红色,是为尽可能减少插入新节点对红黑树造成的影响。




情况1:(变色)新插入的结点A刚好位于红黑树的根部。





红黑树原理分析



此时,破坏了特性2,因此直接将A变色。变色后由于A位于树的根结点上,因此每条路径上都增加了一个黑结点,因此特性5没有被破坏。





红黑树原理分析



情况2:(不变)新插入的结点B的父结点是黑色的。


此时,新结点B为红色,满足红黑树的5个特性,因此不做任何操作。





红黑树原理分析



情况3:(变色)新插入的结点D的父结点B与叔叔结点C都为红色。





红黑树原理分析



此时,B结点(红色)的孩子结点D也为红色,打破了特性4。因此需要变色:使B结点变色成黑色。





红黑树原理分析



但是,此时路径A--B--…...上多出一个黑色结点(相较于路径A--C--…...),违背了特性5。因此需要使A结点变色为红色。





红黑树原理分析



但是,此时还是存在问题。红色的A结点的孩子结点C也是红色,又违背了特性4,因此使C结点变色为黑色。





红黑树原理分析



此时的结果满足红黑树的5个特性,调整完毕。


情况4:(旋转-左旋)新插入的结点D的父结点B为红色,其叔叔结点C为黑色或无叔叔结点,且新结点D位于其父结点B的右孩子,而B结点位于其自身父结点的左孩子上。





红黑树原理分析



此时,以新结点D的父结点B为轴进行左旋,使D替代B的位置,原来的父结点B作为新的父结点D的左孩子,且原来D的左子树2作为新局面中B的右子树。





红黑树原理分析



旋转之后变为了情况5。


情况5:(旋转-右旋+变色)新插入的结点D的父结点B为红色,其叔叔结点C为黑色或无叔叔结点,且新结点D位于其父结点B的左孩子,而B结点位于其自身父结点的左孩子上。





红黑树原理分析



此时,以新结点D的祖父结点A为轴进行右旋,使父结点B替代A的位置,原来的祖父结点A作为新的祖父结点B的右孩子,且原来B的右子树3作为新局面中A的左子树。





红黑树原理分析



由于右旋之后根的右子树上多了一个黑结点,违背了特性5;且树的根结点的颜色为红色,也违背了特性2。因此需要使B结点变为黑色,A结点变色为红色。





红黑树原理分析



到底为止,调整后的树满足了红黑树的5个特性。


注意:当情况4、5中的父结点B是祖父节点A的右孩子时,情况4:新结点D是B的左孩子,此时以B为轴右旋进入情况5;情况5:新结点D是B的右孩子,此时以祖父节点A为轴左旋,再变色。




3、实例


在下图基础上插入21结点。


(1)按照二叉查找树的规则插入21结点。





红黑树原理分析



(2)调整结点21:判断插入21属于插入操作的哪种情况,并调整。


经判断,发现新插入的21结点的父结点及叔叔结点都是红色,符合情况3。因此需要进行变色操作:22变为黑色,25变为红色,27变为黑色。





红黑树原理分析



调整之后,以25为根的子树满足了红黑树的5个特性。但是25与其父结点17都为红色,不符合特性4。


(3)调整25结点:将结点25看作新结点,往上进行调整。


此时符合情况5的变形:即新结点25的父结点17为红色,叔叔结点15为黑色,且25是17的右孩子,父结点17为祖父节点13的右孩子,需要先左旋再变色。


左旋:以13为轴左旋后,17结点替代13结点的位置,变为根结点。而13变为17的左孩子,以15为根的子树变为13的右子树。





红黑树原理分析



变色:使17变色为黑色,13变色为红色。此时,这棵树的调整完毕。





红黑树原理分析













红黑树原理分析





4、红黑树的删除操作























1、二叉查找树删除操作的3种情况


(1)待删除的结点是叶子结点,则直接删除。





红黑树原理分析




红黑树原理分析



(2)待删除的结点有1个孩子:让其孩子结点直接替代它。





红黑树原理分析




红黑树原理分析



(3)待删除结点有2个孩子。





红黑树原理分析



5有两个孩子,需要在其子树中选择与5最接近的结点替代它。一般习惯选择5的后继结点(按照中序排序)替代它,此处为结点6。


将6复制到5的位置上,然后原来的6结点按照情况1或2进行删除。





红黑树原理分析




红黑树原理分析



2、红黑树删除操作的3个步骤


此处红黑树的删除操作是在二叉查找树删除操作基础上展开的。


(1)步骤1:若待删除结点有2个非空孩子,则需将其变为只有一个孩子或没有孩子。






红黑树原理分析




例如删除结点8。首先根据二叉查找树进行删除操作:结点8有两个孩子,因此使用中序排序中8的后继结点10复制到8的位置,结点颜色是待删除结点的颜色,然后删除原来位置的10。





红黑树原理分析



此时,由中序遍历的性质得知10结点没有左孩子,因此转化为了删除结点10,且10结点只有一个右孩子,进入步骤2。


(2)步骤2:根据待删除结点及其唯一的孩子结点颜色,分为以下3种情况。


A、待删除结点为红色,孩子为黑色。





红黑树原理分析



直接按照二叉查找树的方法,进行删除操作,即用结点2替代结点1。





红黑树原理分析



B、待删除结点为黑色,孩子为红色。





红黑树原理分析



首先按照二叉查找树的方法,删除结点1。





红黑树原理分析



但是2结点所在的这条路径上黑结点的数目少了一个,因此需要变色:将2变为黑色。





红黑树原理分析



C、待删除结点为黑色,孩子也为黑色或空的叶节点。





红黑树原理分析



首先按照二叉查找树的方法删除结点1。





红黑树原理分析



但此时2所在的路径上的黑结点数目减少了一个,且无法通过变色解决,因此跳转到步骤3。


(3)步骤3:主要解决双黑结点,即父结点与唯一子结点都是黑色。子结点替代父结点后,有6种情况。


A、不变:结点2为树的根。此时所有路径的黑结点都少了1个,因此满足特性5,不需调整。





红黑树原理分析



B、变色:结点2的父亲、兄弟、侄子都为黑色。





红黑树原理分析



将其兄弟B变为红色。





红黑树原理分析



此时,A的两棵子树的路径上都少了一个黑结点,因此满足了特性5。但可能又会使A以外的路径不满足特性5,因此将A看作此处的2结点,进行递归调整。


C、左旋 + 变色:结点2的兄弟为红色,父亲、侄子为黑色。





红黑树原理分析



左旋:以2的父结点A为轴左旋。





红黑树原理分析



变色:使A变为红色,B变为黑色。这样操作之后会变为情况D或情况E或情况F。





红黑树原理分析



D、变色:结点2的父亲为红色,兄弟、侄子为黑色。





红黑树原理分析



变色:将结点2的父亲A变成黑色,兄弟B变成红色。这样的结果会增加2所在路径的黑结点,同时也不会缩减B所在路径的黑结点,满足了特性5。





红黑树原理分析



E、右旋 + 变色:结点2的父结点无限制,兄弟B为黑色右孩子,右侄子为黑色,左侄子为红色。





红黑树原理分析



右旋:此时,以结点2的兄弟B为轴右旋,使B的左孩子C旋转到B的位置上。





红黑树原理分析



变色:使B变成红色,C变成黑色,然后跳转到情况F。





红黑树原理分析



F、左旋+变色:结点2的父亲颜色无限制,兄弟B为黑色右孩子,右侄子为红色。





红黑树原理分析



左旋:以2结点的父亲A为轴左旋,使A的右孩子B旋转到A的位置上。





红黑树原理分析



变色:将A与B的颜色交换,D的颜色置为黑色。





红黑树原理分析



这时,2所在路径由原来的“任意-黑”转化为了“任意-黑-黑”,而在步骤2中2替代了其父结点,因此2所在路径缺少1个黑结点,本次调整完后刚好补上了之前缺的黑结点,满足了特性5;D所在路径由原来的“任意-黑-红”转化为了“任意-黑”,黑结点数目始终不变。


3、实例


在下面红黑树的基础上删除结点17。





红黑树原理分析



步骤1:分析得17有两个孩子,因此使用中序遍历中17的后继结点25复制到17的位置上,颜色为黑色。





红黑树原理分析



步骤2:此时转变为了删除原来的结点25,符合删除操作步骤2的情况C。





红黑树原理分析



删除原来的结点25





红黑树原理分析



步骤3:此时对应于删除操作步骤3的情况5的镜像。





红黑树原理分析




红黑树原理分析



这时进行左旋、变色:以结点null的兄弟15为轴进行左旋,使16旋转至15的位置;再将16变为黑,15变为红,进入情况6的镜像。





红黑树原理分析



再进行右旋和变色:以结点null的父亲25为轴进行右旋,使25的左孩子16旋转至25的位置;再将16与25颜色互换,15结点的颜色置为黑色。至此,这颗红黑树删除结点17的操作完成。





红黑树原理分析




红黑树原理分析













红黑树原理分析





5、总结























本文主要介绍了红黑树的相关原理。首先通过二叉查找树的不足引出红黑树,然后针对红黑树的5大特性,红黑树的插入操作,删除操作,都使用了大量的图形来加以说明。红黑树的应用也非常广泛,如JAVA中的TreeMap和TreeSet都是基于红黑树实现的,且JDK8中HashMap当链表长度大于8时也会转化为红黑树。






















区块链and语义研究实验室


与你分享学术科研。














推荐阅读
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了Java的集合及其实现类,包括数据结构、抽象类和具体实现类的关系,详细介绍了List接口及其实现类ArrayList的基本操作和特点。文章通过提供相关参考文档和链接,帮助读者更好地理解和使用Java的集合类。 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Learning to Paint with Model-based Deep Reinforcement Learning
    本文介绍了一种基于模型的深度强化学习方法,通过结合神经渲染器,教机器像人类画家一样进行绘画。该方法能够生成笔画的坐标点、半径、透明度、颜色值等,以生成类似于给定目标图像的绘画。文章还讨论了该方法面临的挑战,包括绘制纹理丰富的图像等。通过对比实验的结果,作者证明了基于模型的深度强化学习方法相对于基于模型的DDPG和模型无关的DDPG方法的优势。该研究对于深度强化学习在绘画领域的应用具有重要意义。 ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • macOS Big Sur全新设计大版本更新,10+个值得关注的新功能
    本文介绍了Apple发布的新一代操作系统macOS Big Sur,该系统采用全新的界面设计,包括图标、应用界面、程序坞和菜单栏等方面的变化。新系统还增加了通知中心、桌面小组件、强化的Safari浏览器以及隐私保护等多项功能。文章指出,macOS Big Sur的设计与iPadOS越来越接近,结合了去年iPadOS对鼠标的完善等功能。 ... [详细]
author-avatar
铜钱
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有