教你透彻了解红黑树概论
红黑树详解

红黑树详解在本文,我将比较透彻地讲解红黑树。
本文适合那些有对二叉树有一定的基础,并且熟悉C语言的读者。
本文最主要的参考资料是《Introduction to Algorithms 3rd Edition》。
1.1 二叉查找树1.1.1 基本概念二叉查找树是在数据结构中比较重要的数据结构之一,从外部看它满足集合性质,具有查找,插入和删除的基本功能,同时还可以求最大值和最小值。
由于二叉查找树独特的性质,它特别适合用来存储动态集合。
定义:对于二叉树上的所有结点x,如果y是x的左子树,那么y.key ≤ x.key。
如果y 是x的右子树,那么y.key ≥ x.key,这样的二叉树就称为二叉查找树(Binary Search Tree)。
我们关心的二叉查找树的逻辑结构,下面的两棵二叉树:图1 二叉查找树。
(a)这一棵高度为3的二叉树,因为10比15小,所以10在15的左子树上;同理在以10为根的左子树里,7比10小所以7在左子树上,12在10为根的子树的右子树上;20在以15为根的右子树上。
(b)这是一棵高度是4的二叉查找树,它的所有key与图(a)是一样的。
在图(a)中,查找最坏的情况是7和12,它们需要经过3次比较才能找到,而图(b)最坏情况是20,需要经过4次比较才能找到。
要想二叉树的查找的花费时间小,我们尽可能让二叉树不出现类以于单链形态的二叉树,让树的高度尽量的低。
对于高度为h的二叉查找树,从树根对叶子最坏的情况是比较h 次。
也就是说,对于高度为h的二叉查找树的最坏查找情况的运行时间是O(h)。
二叉树的查找效率取决于树的高度。
1.1.2 操作二叉树做为动态集,它有查找、插入、删除、最大值、最小值、前驱和后继这些基本操作。
为了后序的方便,我们定义了结点和树,另外我们还用0表示空子树。
查找在二叉查找树中根据给定的key找到该结点。
由于二叉树的性质,我们就知道,如果目标key比当前结点的key要小,那么目标结点必定在当前结点的左子树上。
红黑树-RBT(一、红黑树定义以及简介)

红⿊树-RBT(⼀、红⿊树定义以及简介)
⼀、红⿊树
1、介绍:红⿊树是⼀种⼆叉查找树,但在每个节点上增加⼀个存储位表⽰节点的颜⾊,可以是red或black。
通过对任何⼀条从根到叶⼦的路径上的各个节点着⾊⽅式的限制,红⿊树确保没有⼀条路径会⽐其他路径长出两倍,因⽽是接近平衡的。
2、定义:它或者是⼀颗空树,或者是具有⼀下性质的⼆叉查找树
1):每个节点或是红的,或是⿊的。
2):根节点是⿊的。
3):每个叶节点(NIL)是⿊的。
(所有NULL结点称为叶⼦节点,且认为颜⾊为⿊)
4):如果⼀个节点是红的,则他的两个⼦节点是⿊的。
5):对每个节点,从该节点到其⼦孙节点的所有路径上包含相同数⽬的⿊节点。
3、结构:树中的每个节点上包含五个域:color、key、left、right、p。
如果其节点没有⼀个⼦节点或者⽗节点,则该节点相应的指针(p)域包含值NIL。
我们把这些NIL视为指向⼆叉查找树的外节点,⽽把带关键字的节点是为树的内节点。
4、⾼度:⼀颗有n个内节点的红⿊树的⾼⾄多为2lg(n+1)。
5、应⽤:Java集合中的和,C++ STL中的set、map,以及Linux虚拟内存的管理,都是通过红⿊树去实现的。
。
【算法】红黑树原理和算法介绍

【算法】红⿊树原理和算法介绍红⿊树介绍⼆叉查找树 学红⿊树,⾸先理解⼆叉查找树 ⼆叉查找树(BST)具备特性1. 左⼦树上所有结点的值均⼩于或等于它的根结点的值。
2. 右⼦树上所有结点的值均⼤于或等于它的根结点的值。
3. 左、右⼦树也分别为⼆叉排序树。
⼆叉查找树是⼆分查找的思想,查找所需的最⼤次数等同于⼆叉树的⾼度。
在插⼊节点的时候也是利⽤类似的⽅法,⼀层⼀层⽐较⼤⼩,找到合适的插⼊位置。
如下图,这样虽然满⾜了⼆叉查找树的条件,但是这个是瘸腿的⼆叉查找树,就和链表没有区别了。
这是⼆叉查找树的缺点解决⼆叉查找树多次插⼊新节点⽽导致的不平衡的⽅法,就是使⽤红⿊树。
红⿊树是⼀种⾃平衡的⼆叉查找树。
红⿊树 R-B Tree,全称是Red-Black Tree,⼜称为“红⿊树”,它⼀种特殊的⼆叉查找树。
红⿊树的每个节点上都有存储位表⽰节点的颜⾊,可以是红(Red)或⿊(Black)。
红⿊树的特性: (1)每个节点或者是⿊⾊,或者是红⾊。
(2)根节点是⿊⾊。
(3)每个叶⼦节点(NIL)是⿊⾊。
[注意:这⾥叶⼦节点,是指为空(NIL或NULL)的叶⼦节点!] (4)如果⼀个节点是红⾊的,则它的⼦节点必须是⿊⾊的。
(5)从⼀个节点到该节点的⼦孙节点的所有路径上包含相同数⽬的⿊节点。
上⾯⼀系列的规则,保证了红⿊树的⾃平衡。
红⿊树从根到叶⼦的最长路径不会超过最短路径的2倍当插⼊或删除节点的时候,红⿊树的规则有可能被打破,这个时候需要进⾏调整来维持红⿊树的规则。
如下图,如果向原红⿊树插⼊值为21的新节点,由于⽗节点22是红⾊节点,因此这种情况打破了红⿊树的规则4(每个红⾊节点的两个⼦节点都是⿊⾊),必须进⾏调整,使之重新符合红⿊树的规则。
调整的⽅法有两种:1. 变⾊:红变⿊,⿊变红2. 旋转:左旋转和右旋转变换规则旋转和颜⾊变换规则:所有插⼊的点默认为红⾊1. 变颜⾊的情况:当前结点的⽗亲是红⾊,且它的祖⽗结点的另⼀个⼦结点也是红⾊(叔叔结点):(1)把⽗节点设为⿊⾊(2)把叔叔也设为⿊⾊(3)把祖⽗也就是⽗亲的⽗亲设为红⾊(爷爷)(4)把指针定义到祖⽗结点设为当前要操作的(爷爷)分析的点变换的规则2. 左旋:当前⽗结点是红⾊,叔叔是⿊⾊的时候,且当前的结点是右⼦树。
红黑树面试题

红黑树面试题红黑树(Red-Black Tree)是一种自平衡的二叉搜索树,它能够保持在插入、删除等操作之后仍保持平衡。
在面试中,红黑树是常见的面试题目之一。
本文将通过解答一些常见的红黑树面试题来帮助读者更好地理解红黑树的性质和操作。
1. 什么是红黑树?红黑树是一种自平衡的二叉搜索树,它的每个节点都有一个额外的存储位来表示节点的颜色,可以是红色或黑色。
它满足以下性质:(1) 每个节点要么是红色,要么是黑色。
(2) 根节点是黑色。
(3) 每个叶子节点(NIL节点,空节点)是黑色。
(4) 如果一个节点是红色的,则它的两个子节点都是黑色的。
(5) 从任意节点到其每个叶子节点的所有路径都包含相同数目的黑色节点。
2. 如何实现红黑树的插入操作?红黑树的插入操作可以分为以下几个步骤:(1) 将节点插入到二叉搜索树中,按照二叉搜索树的规则找到合适的位置。
(2) 将插入的节点标记为红色。
(3) 根据红黑树的性质,调整树的结构来满足红黑树的要求,确保不会出现连续的红色节点。
具体的调整操作分为几种情况,我们以插入节点为A为例进行说明:(1) A是根节点,将A标记为黑色。
(2) A的父节点是黑色,不需要进行调整。
(3) A的父节点是红色:a. A的叔节点是红色:将A的父节点和叔节点都标记为黑色,将A的祖父节点标记为红色,然后以祖父节点为当前节点进行进一步的调整。
b. A的叔节点是黑色或不存在,且A是其父节点的右子节点:以A的父节点为支点进行左旋转,然后再以A的父节点为当前节点进行进一步的调整。
c. A的叔节点是黑色或不存在,且A是其父节点的左子节点:将A的父节点标记为黑色,将A的祖父节点标记为红色,以A的祖父节点为支点进行右旋转,最后整个树都符合红黑树的要求。
3. 如何实现红黑树的删除操作?红黑树的删除操作相对于插入操作要复杂一些。
删除操作可以分为以下几个步骤:(1) 根据删除节点的值,在红黑树中找到要删除的节点。
(2) 根据要删除的节点的情况进行不同的处理:a. 要删除的节点没有子节点或只有一个子节点:直接删除该节点,并将其子节点接替上来。
数据结构与算法(8):红黑树

// 前提:这里里里假设x的右孩子子为y。下面面开始正式操作 // 将 “y的左孩子子” 设为 “x的右孩子子”,即 将β设为x的右孩子子 // 将 “x” 设为 “y的左孩子子的父父亲”,即 将β的父父亲设为x // 将 “x的父父亲” 设为 “y的父父亲”
05 if p[x] = nil[T] 06 then root[T] ← y
的右孩子子”
10 left[y] ← x
// 将 “x” 设为 “y的左孩子子”
11 p[x] ← y
// 将 “x的父父节点” 设为 “y”
理理解左旋之后,看看下面面更更鲜明的例例子子。
2.2 右旋
对Y进行行行右旋,意味着“将Y变成一一个右节点”
右旋的伪代码《算法导论》:参考上面面的示意图和下面面的伪代码,理理解“红黑黑树T的节点y进行行行右 旋”是如何进行行行的。
1.2 红广泛,主要是用用它来存储有序的数据,它的时间复杂度是O(lgn),效率非非常之
高高。
例例如,Java集合中的TreeSet和TreeMap,C++的STL中的Set、Map,以及Linux虚拟内存的管
理理,都是通过红黑黑树去实现的。
二二、红黑黑树的基本操作:左旋和右旋
数据结构与算法(8):红黑黑树
红黑黑树,即R-B Tree,本文文的主要内容包括:红黑黑树的特性、红黑黑树的时间复杂度和它的证明, 红黑黑树的时间复杂度和它的证明,红黑黑树的左旋、右旋、插入入、删除等操作
一一、红黑黑树的定义
1.1 红黑黑树的定义
R-B Tree,全称是Red-black Tree,又又称为“红黑黑树”,它是一一种特殊的二二叉查找树。红黑黑树的每 个节点上都有存储位表示节点的颜色色,可以是红(Red)或黑黑(Black)
红黑树简介

红黑树简介1. 简介红黑树是一种自平衡二叉查找树。
它的统计性能要好于平衡二叉树(AVL树),因此,红黑树在很多地方都有应用。
在C++ STL中,很多部分(目前包括set, multiset, map, multimap)应用了红黑树的变体(SGI STL中的红黑树有一些变化,这些修改提供了更好的性能,以及对set操作的支持)。
它是复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除等操作。
本文介绍了红黑树的基本性质和基本操作。
2. 红黑树的性质红黑树,顾名思义,通过红黑两种颜色域保证树的高度近似平衡。
它的每个节点是一个五元组:color(颜色),key(数据),left(左孩子),right(右孩子)和p(父节点)。
红黑树的定义也是它的性质,有以下五条:性质1. 节点是红色或黑色性质2. 根是黑色性质3. 所有叶子都是黑色(叶子是NIL节点)性质4. 如果一个节点是红的,则它的两个儿子都是黑的性质5. 从任一节点到其叶子的所有简单路径都包含相同数目的黑色节点。
这五个性质强制了红黑树的关键性质: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。
为什么呢?性质4暗示着任何一个简单路径上不能有两个毗连的红色节点,这样,最短的可能路径全是黑色节点,最长的可能路径有交替的红色和黑色节点。
同时根据性质5知道:所有最长的路径都有相同数目的黑色节点,这就表明了没有路径能多于任何其他路径的两倍长。
3. 红黑树的基本操作因为红黑树也是二叉查找树,因此红黑树上的查找操作与普通二叉查找树上的查找操作相同。
然而,红黑树上的插入操作和删除操作会导致不再符合红黑树的性质。
恢复红黑树的性质需要少量(O(log n))的颜色变更(实际是非常快速的)和不超过三次树旋转(对于插入操作是两次)。
虽然插入和删除很复杂,但操作时间仍可以保持为O(log n) 次。
3.1 插入操作插入操作可以概括为以下几个步骤:(1) 查找要插入的位置,时间复杂度为:O(N)(2) 将新节点的color赋为红色(3) 自下而上重新调整该树为红黑树其中,第(1)步的查找方法跟普通二叉查找树一样,第(2)步之所以将新插入的节点的颜色赋为红色,是因为:如果设为黑色,就会导致根到叶子的路径上有一条路上,多一个额外的黑节点,这个是很难调整的。
红黑树

红黑树的删除
删除节点后对RBT性质的影响讨论:
若删除结点为红色,则对RBT性质没有影响,原因? • 树中各结点的黑高没有变化 • 不存在两个相邻的红色结点 • 因为删除结点为红色,就不可能是根,所以根仍然 为黑
若删除结点为黑色,则对RBT性质会产生影响,因此 需要调整
红黑树的删除
删除的调整算法 讨论
红黑树
目录
§.1 红黑树的定义
§.2 红黑树的性质
§.3 红黑树的旋转
§.4 红黑树的插入
§.5 红黑树的删除
红黑树的插入
step 1:将z节点按二叉查找树规则插入红 黑树中,z是叶子节点; step 2:将z涂红; step 3:调整使其满足红黑树的性质;
红黑树的插入
插入算法示例
• RBInsert(T, z) { y ← nil[T]; x ← root[T]; while x ≠ nil[T] do { y ← x; if key[z] < key[x] then x ← left[x]; else x ← right[x]; } p[z] ← y; if y = nil[T] then
红黑树的删除
Case1:z为叶结点 Case2:z只有一个孩子
处理方法:删除z,连接x。这里x是z的中序后继
注: • case 1是case 2的特例,因为处理模式是一样的 • z是p[z]的左孩子,类似讨论
红黑树的删除
Case3:z两个孩子均非空 实际删除的结点为y!
处理方法: (1)找z的中序后继,即找z的右子树中最左下节点y (2)删除y,将y的内容copy到z,再将y的右子连到 p[y]左下。
root[T] ← z;
//y用于记录当前扫描节点的双亲节点 //从根开始扫描 //查找插入位置 //z插入x的左边
数据结构与算法中的红黑树

数据结构与算法中的红黑树数据结构是计算机程序设计中的重要组成部分,用于存储和组织数据。
在计算机科学中,算法是解决问题的基础。
红黑树是一种常用的数据结构和算法,被广泛应用于计算机的操作系统、数据库、编译器、图形图像等领域。
本文将对红黑树的定义、实现、应用等方面进行详细介绍。
一、红黑树的定义红黑树是一种自平衡二叉查找树,它满足以下性质:1.每个节点要么是红色,要么是黑色。
2.根节点是黑色的。
3.每个叶节点(NIL节点,空节点)是黑色的。
4.如果一个节点是红色的,则它的两个子节点都是黑色的。
5.对于每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。
这意味着红黑树是一种平衡二叉查找树,它通过不断的旋转和节点着色来使树保持平衡。
二、红黑树的实现红黑树的实现有两个关键步骤:插入和删除。
①插入操作插入新节点时,首先按照二叉查找树的原则将它放入合适的位置,然后将它的颜色设置为红色。
如果新插入的节点是根节点,则直接将其颜色改为黑色;如果其父节点是黑色的,则不影响红黑树的性质,直接结束操作即可。
如果其父节点是红色的,则需要进行颜色调整。
具体来说,需要根据其祖父节点的颜色和叔父节点的颜色进行分类讨论:1.祖父节点为黑色,则不需要调整。
2.叔父节点是红色,则将父节点和叔父节点颜色都设置为黑色,将祖父节点颜色设置为红色,然后将当前节点指向祖父节点,重新开始操作。
3.叔父节点是黑色或为空,则需要旋转和着色,使得当前节点变成祖父节点,父节点变成红色,原来的祖父节点变成黑色。
此时,如果当前节点已经变成了根节点,则将其颜色设置为黑色,结束操作;否则,继续考虑其父节点的颜色和祖父节点的颜色,重复以上步骤。
②删除操作删除节点时,首先按照二叉查找树的原则找到它,然后根据其子节点的情况进行讨论。
如果删除的节点是叶子节点(没有子节点),直接将其删除即可。
如果删除的节点只有一个子节点,则将其子节点替换为该节点即可。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
红黑树系列,六篇文章于今日已经完成:1、教你透彻了解红黑树2、红黑树算法的实现与剖析3、红黑树的c源码实现与剖析4、一步一图一代码,R-B Tree5、红黑树插入和删除结点的全程演示6、红黑树的c++完整实现源码------------------------------一、红黑树的介绍先来看下算法导论对R-B Tree的介绍:红黑树,一种二叉查找树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red 或Black。
通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。
前面说了,红黑树,是一种二叉查找树,既然是二叉查找树,那么它必满足二叉查找树的一般性质。
下面,在具体介绍红黑树之前,咱们先来了解下二叉查找树的一般性质:1.在一棵二叉查找树上,执行查找、插入、删除等操作,的时间复杂度为O(lgn)。
因为,一棵由n个结点,随机构造的二叉查找树的高度为lgn,所以顺理成章,一般操作的执行时间为O(lgn)。
//至于n个结点的二叉树高度为lgn的证明,可参考算法导论第12章二叉查找树第12.4节。
2.但若是一棵具有n个结点的线性链,则此些操作最坏情况运行时间为O(n)。
而红黑树,能保证在最坏情况下,基本的动态几何操作的时间均为O(lgn)。
ok,我们知道,红黑树上每个结点内含五个域,color,key,left,right,p。
如果相应的指针域没有,则设为NIL。
一般的,红黑树,满足以下性质,即只有满足以下全部性质的树,我们才称之为红黑树:1)每个结点要么是红的,要么是黑的。
2)根结点是黑的。
3)每个叶结点(叶结点即指树尾端NIL指针或NULL结点)是黑的。
4)如果一个结点是红的,那么它的俩个儿子都是黑的。
5)对于任一结点而言,其到叶结点树尾端NIL指针的每一条路径都包含相同数目的黑结点。
(注:上述第3、5点性质中所说的NULL结点,包括wikipedia.算法导论上所认为的叶子结点即为树尾端的NIL指针,或者说NULL结点。
然百度百科以及网上一些其它博文直接说的叶结点,则易引起误会,因,此叶结点非子结点)如下图所示,即是一颗红黑树(下图引自wikipedia:/hgvH1l):此图忽略了叶子和根部的父结点。
同时,上文中我们所说的"叶结点" 或"NULL结点",如上图所示,它不包含数据而只充当树在此结束的指示,这些节点在绘图中经常被省略,望看到此文后的读者朋友注意。
二、树的旋转知识当我们在对红黑树进行插入和删除等操作时,对树做了修改,那么可能会违背红黑树的性质。
为了保持红黑树的性质,我们可以通过对树进行旋转,即修改树种某些结点的颜色及指针结构,以达到对红黑树进行插入、删除结点等操作时,红黑树依然能保持它特有的性质(如上文所述的,五点性质)。
树的旋转,分为左旋和右旋,以下借助图来做形象的解释和介绍:1.左旋如上图所示:当在某个结点pivot上,做左旋操作时,我们假设它的右孩子y不是NIL[T],pivot可以为树内任意右孩子而不是NIL[T]的结点。
左旋以pivot到y之间的链为“支轴”进行,它使y成为该孩子树新的根,而y的左孩子b则成为pivot的右孩子。
来看算法导论对此操作的算法实现(以x代替上述的pivot):1. LEFT-ROTATE(T, x)2. 1 y ← right[x] ▹ Set y.3. 2 right[x] ← left[y] ▹ Turn y's left subtree into x's right subtree.4. 3 p[left[y]] ← x5. 4 p[y] ← p[x] ▹ Link x's parent to y.6. 5 if p[x] = nil[T]7. 6 then root[T] ← y8.7 else if x = left[p[x]]9.8 then left[p[x]] ← y10.9 else right[p[x]] ← y11.10 left[y] ← x ▹ Put x on y's left.12.11 p[x] ← y2.右旋右旋与左旋差不多,再此不做详细介绍。
对于树的旋转,能保持不变的只有原树的搜索性质,而原树的红黑性质则不能保持,在红黑树的数据插入和删除后可利用旋转和颜色重涂来恢复树的红黑性质。
至于有些书如 STL源码剖析有对双旋的描述,其实双旋只是单旋的两次应用,并无新的内容,因此这里就不再介绍了,而且左右旋也是相互对称的,只要理解其中一种旋转就可以了。
三、红黑树插入、删除操作的具体实现I、ok,接下来,咱们来具体了解红黑树的插入操作。
向一棵含有n个结点的红黑树插入一个新结点的操作可以在O(lgn)时间内完成。
算法导论:1.RB-INSERT(T, z)2. 1 y ← nil[T]3. 2 x ← root[T]4. 3 while x ≠ nil[T]5. 4 do y ← x6. 5 if key[z] < key[x]7. 6 then x ← left[x]8. 7 else x ← right[x]9. 8 p[z] ← y10. 9 if y = nil[T]11.10 then root[T] ← z12.11 else if key[z] < key[y]13.12 then left[y] ← z14.13 else right[y] ← z15.14 left[z] ← nil[T]16.15 right[z] ← nil[T]17.16 color[z] ← RED18.17 RB-INSERT-FIXUP(T, z)咱们来具体分析下,此段代码:RB-INSERT(T, z),将z插入红黑树T 之内。
为保证红黑性质在插入操作后依然保持,上述代码调用了一个辅助程序RB-INSERT-FIXUP来对结点进行重新着色,并旋转。
14 left[z] ← nil[T]15 right[z] ← nil[T]//保持正确的树结构第16行,将z着为红色,由于将z着为红色可能会违背某一条红黑树的性质,所以,在第17行,调用RB-INSERT-FIXUP(T,z)来保持红黑树的性质。
RB-INSERT-FIXUP(T, z),如下所示:1. 1 while color[p[z]] = RED2. 2 do if p[z] = left[p[p[z]]]3. 3 then y ← right[p[p[z]]]4. 4 if color[y] = RED5. 5 then color[p[z]] ← BLACK ▹ Case 16. 6 color[y] ← BLACK ▹ Case 17. 7 color[p[p[z]]] ← RED ▹ Case 18. 8 z ← p[p[z]] ▹ Case 19. 9 else if z = right[p[z]]10.10 then z ← p[z] ▹ Case 211.11 LEFT-ROTATE(T, z) ▹ Case 212.12 color[p[z]] ← BLACK ▹ Case 313.13 color[p[p[z]]] ← RED ▹ Case 314.14 RIGHT-ROTATE(T, p[p[z]]) ▹ Case 315.15 else (same as then clause16. with "right" and "left" exchanged)17.16 color[root[T]] ← BLACKok,参考一网友的言论,用自己的语言,再来具体解剖下上述俩段代码。
为了保证阐述清晰,我再写下红黑树的5个性质:1)每个结点要么是红的,要么是黑的。
2)根结点是黑的。
3)每个叶结点,即空结点(NIL)是黑的。
4)如果一个结点是红的,那么它的俩个儿子都是黑的。
5)对每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点。
在对红黑树进行插入操作时,我们一般总是插入红色的结点,因为这样可以在插入过程中尽量避免对树的调整。
那么,我们插入一个结点后,可能会使原树的哪些性质改变列?由于,我们是按照二叉树的方式进行插入,因此元素的搜索性质不会改变。
如果插入的结点是根结点,性质2会被破坏,如果插入结点的父结点是红色,则会破坏性质4。
因此,总而言之,插入一个红色结点只会破坏性质2或性质4。
我们的回复策略很简单,其一、把出现违背红黑树性质的结点向上移,如果能移到根结点,那么很容易就能通过直接修改根结点来恢复红黑树的性质。
直接通过修改根结点来恢复红黑树应满足的性质。
其二、穷举所有的可能性,之后把能归于同一类方法处理的归为同一类,不能直接处理的化归到下面的几种情况,//注:以下情况3、4、5与上述算法导论上的代码RB-INSERT-FIXUP(T, z),相对应:插入修复具体操作情况情况1:插入的是根结点。
原树是空树,此情况只会违反性质2。
对策:直接把此结点涂为黑色。
情况2:插入的结点的父结点是黑色。
此不会违反性质2和性质4,红黑树没有被破坏。
对策:什么也不做。
情况3:当前结点的父结点是红色且祖父结点的另一个子结点(叔叔结点)是红色。
此时父结点的父结点一定存在,否则插入前就已不是红黑树。
与此同时,又分为父结点是祖父结点的左子还是右子,对于对称性,我们只要解开一个方向就可以了。
在此,我们只考虑父结点为祖父左子的情况。
同时,还可以分为当前结点是其父结点的左子还是右子,但是处理方式是一样的。
我们将此归为同一类。
对策:将当前节点的父节点和叔叔节点涂黑,祖父结点涂红,把当前结点指向祖父节点,从新的当前节点重新开始算法。
针对情况3,变化前(图片来源:saturnman)[当前节点为4节点]:变化后:情况4:当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的右子对策:当前节点的父节点做为新的当前节点,以新当前节点为支点左旋。
如下图所示,变化前[当前节点为7节点]:变化后:情况5:当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的左子解法:父节点变为黑色,祖父节点变为红色,在祖父节点为支点右旋如下图所示[当前节点为2节点]变化后:「回顾:经过上面情况3、情况4、情况5等3种插入修复情况的操作示意图,读者自会发现,后面的情况4、情况5都是针对情况3插入节点4以后,进行的一系列插入修复情况操作,不过,指向当前节点N 指针一直在变化。
所以,你可以想当然的认为:整个下来,情况3、4、5就是一个完整的插入修复情况的操作流程」1、没有儿子,即为叶结点。