c \

一、红黑树的基本性质

  1、红黑树本质上是一种二叉查找树BST,满足左孩子均小于根,右孩子均大于(等于)根的性质,但是它从根节点到最远叶子节点的长度不会超过到最近叶子节点的两倍,所以是近似平衡的。

    【证明】由于性质5  假如说一个黑高度为3的红黑树,  最短路径定为 黑-黑-黑  长度为2    最长路径 为黑-红-黑-红-黑  长度为4     所以可证明

  2、红黑树的每个节点要么为黑色要么为红色

  3、树根一定为黑色

  4、如果一个节点为红色,那么它的两个孩子一定为黑色

  5、从任意节点出发往下到达叶子节点的路径一定包含相同数目的黑节点,这个数目成为黑高度。

  

  构造一颗红黑树的话也就是两个方面  一个是构造一颗二叉查找树  一个是对于节点的染色。

  之上的这些性之中  最关键的就是性质5了   从任意节点出发往下到达叶子节点的路径一定包含相同数目的黑节点   我们所做的调整工作的基本就是以该性质为基准进行操作的

二、初识红黑树

首先以{9,7,15,6,11,19}看一下如何建立一颗红黑树

声明:我们将插入节点初始化为红色,

【原因】  因为之前的红黑树满足从根节点到叶子节点的黑节点数目相同   如果插入黑色的节点会违背性质5   所以插入红色节点  如果有违反性质再做其它调整

      首先是第一个节点9,我们直接把它当做树根,

            

      我们发现它违背性质3  所以将其改为黑色

            

      然后是插入7

                  插入之后满足所有性质  不做改变

      然后是15

          

      然后是6

          

                     此时我们发现违背了红节点两个儿子必须为黑这条性质

       该如何调整?

        首先想到的就是直接将6节点改为黑色

        但是改为黑色之后性质5又违背了

        我们考虑 没有6的时候   原有的红黑树以满足 性质5   而且仙子阿来说   同一层的7和15均为红色  

        假如说我们将他们全部变为黑色会怎么样?  只会多一层黑高   

        所以我们将7和15改为黑色

          

        发现满足所有性质

        

        插入11和19

          

        插入10

          

      此时我们发现又出现了之前的问题

      同样的吧11和19变为黑色

      

      但是问题来了  

      这么做之后  9的右孩子明天比左孩子黑高多1

      我们回想一下为什么会出现这样的状况

      由于把11   19 改成了黑色  使得原来的右侧黑色层数多了一层  那么该怎么办?

      可以把11  19变成黑色之后  把父亲改为红色  

      

    1. 新增节点渲染成红色;

    2. 如果它的父亲是红色,则违反了性质5;

    3. 如果它的叔叔也是红色,则通过同时修改其父亲和叔叔的颜色为黑色来恢复性质5;

    4. 如果它的爷爷不是根节点,则有可能在另外的路径上再次违反性质5,于是我们把它的爷爷改成红色;

    5. 可是如果他的太爷爷也是红色呢?很自然地,我们重新回到步骤2;

    6. 不断循环,直到第二步满足就可以结束。

 

三、插入操作

①插入节点没有父节点  即插入节点为根节点 

   将该节点直接插入  然后变为黑色即可

②插入节点的父节点为黑色  

   无需进行任何操作   因为插入的节点为红色   不会影响任何性质

③插入节点的父节点为红色  其叔叔节点也为红色

  将父节点跟叔叔节点均变成黑色  然后将其祖父节点变为红色   递归其祖父节点直到满足条件

                           

 ④插入节点的父亲节点为红色,其叔叔为黑色或者是null    父亲为做孩子  新插入节点为父亲的左孩子【左左模式】或【右右模式】

    此时祖父节点一定为红色 将p和g变色  然后执行左左旋转或者右右旋转即可  见图

                       

⑤差入节点父节点为红色  叔叔节点为黑色或者为空   父节点为左孩子,插入节点为父节点的右孩子【左右】或者【右左】

       左右模式  先往左旋  再往右旋   右左模式  先往右旋  再往左旋

                     

四、删除操作

删除操作首先要解决一个问题   如果  要删除的节点有两个儿子  该怎么解决

对于二叉查找树  我们要删除一个有两个儿子节点的节点  可以从左子树中找一个最大值或者是右子树中找一个最小值   然后将这两点互换  然后再删除  这样的话  问题就转化成了最多删除只有一个儿子节点的节点问题

                                          1

                                  /               \

                                2                  3

                             /      \             /     \

                            4       5           6        7

                         /  \       /           / \        / \

                       8    9   10         12  13  14   15

 比如  要删除3号节点  可以将 3跟5调换  然后再删除2

要删除7   现将7跟13互换   再删除7

 

所以只讨论删除一个儿子节点的问题(如果两个儿子节点均为空,我们将其中一个看做其儿子)

再次  如果要删除节点N为红色  那么它两个叶子节点一定都为null【一定】  所以我们讨论的只是要删除节点n为黑色的情况

 

①  要删除节点为根节点  我们只是从所有的路径上都删除了一个黑节点  新根又是黑节点  所以不会改变  也就是做完了

 ②要删除节点的兄弟节点s为红色  则P以及s的儿子一定为黑色  我们的做法是  将ps变色  然后左旋或者右旋

③N  P  S都为黑色  S的两个儿子也为黑色 

此时我们要删除的是N节点  所以P的左孩子路径黑节点数一定是减一的 所以我们考虑也让右节点孩子数减一  我们把S也变成红色

此时 从P往下的黑色节点倒是相同了  

但是有一个问题  此时 p往下的所有的黑高都减少了1   可能导致以上的左右树的不平衡  所以  我们要以P作为节点  继续往上调整

④P为红 (S一定为黑) S的两个儿子为黑

将S变为红色  P变为黑色  结束 

这种情况下最为简单  S变为红色  P变为黑色  左右黑高相同  同时  P变为黑色不会影响之上的  一举两得

⑤P为任意颜色 S为黑色  SR为红色  SL为任意颜色  N为P的左孩子

操作:将SR变为黑色  S跟P颜色互换  然后PS做左左旋转

 

分析:  N的删除 左边少一个黑节点  但是  P变为黑节点放到左边之后  左边黑节点数目未变     同时   SR变为黑色之后   右边黑节点也没有变  同时   根节点位置的染色也没有变化  所以是平衡的

posted @ 2016-03-07 09:56  悠悠我心。  阅读(339)  评论(0编辑  收藏  举报