红黑树Read-Black Tree

一、

红黑树也是一颗AVL树(平衡二叉树),树中的节点只有两种颜色:红色和黑色。

红黑树具有以下的特性:

  1. 每个节点要么是红色,要么是黑色;
  2. 根节点是黑色的
  3. 每个叶子节点(NULL)都是黑色的空节点
  4. 从根节点到叶子节点,不会出现两个连续的红色节点(即两个红色节点不能直接相连);
  5. 从任何一个节点出发,到叶子节点,这条路径上都有相同数量的黑色节点

其实红黑树并不是严格意义下的平衡树(左右子树的高度差的绝对值不超过1)(这个我们可以从之后的图看到),通过性质5我们可以看到,从根节点到叶子节点的每条路径上,黑节点的的数目是相同的,所以红黑树可以称为是黑色完美平衡

可以对照上面5点性质,下图是一棵红黑树

对照上述5条性质,这的确是一颗红黑树,具有平衡树的特点。

 

二、 

红黑树能够实现自平衡,主要靠一下三种操作:左旋、右旋和变色

 

2.1 红黑树的查询操作

因为红黑树本身也是一棵二叉搜索树,所以红黑树的搜索查询的过程和二叉搜索树是相同的:比较查询节点和当前节点的Value大小,然后递归地比较下去;

 

2.2 红黑树的插入节点

红黑树的节点插入是最复杂的。我们首先按照二叉搜索树插入的规则插入新节点,然后为了满足红黑树的所有性质,我们再进行调整,可以按照以下情形分类讨论。

有一点需要大家注意:插入的节点一定是红色的,因为受到了性质5的限制。

  2.2.1 插入一棵空树

  插入节点作为整棵树的根节点,并且把根节点涂成黑色(满足性质2)

  2.2.2 插入节点的父亲节点是黑色的

  插入节点是红色的,其父亲节点本身就是黑色的,对照红黑树的5条特性,我们发现直接插入节点即可,不需要进行调整。如下图所示(插入节点14):

  

  2.2.3 插入节点的父亲节点是红色的

  我们先按照二叉搜索树的插入规则进行插入,如下图所示:

我们观察一下,这种情况下会出现哪些问题?

我们发现现在这棵红黑树违反了性质4(红色节点不能直接相连),我们需要在此基础上调整:变色+旋转

    2.2.3.1 父亲节点的兄弟节点,即叔叔节点(节点27)是红色的

  1. 把父亲节点设置为黑色(22)
  2. 把叔叔节点设置为黑色(27)
  3. 把祖父节点设置为红色(25)
  4. 把祖父节点设置为当前要操作的节点      

  通过这次变色处理,我们发现方框中的子树满足了红黑树的特性,但放到整棵树中依然有问题(父亲节点(17)和叔叔节点(8)是红色的),我们再调整一次,如下图所示:

  这里需要注意:祖父节点(13)是根节点,根节点要保证是黑色的,所以祖父节点我们就并不变色了。

    2.2.3.2 父亲节点的兄弟节点,即叔叔节点(节点27)是黑色的

    这种情况下又分为两种情况

    2.2.3.2.1 新插入的节点为父节点的左子节点,右旋

        (1)、把父节点变成黑色;

        (2)、把祖父节点变成红色;

        (3)、以祖父节点旋转

    

    2.2.3.2.1 新插入的节点为父节点的右子节点,左旋

    

    这里发现左旋后,又回到了父亲节点为红色和叔叔节点为黑色,并且 新插入的节点为父节点的左子节点,那么我们再进行右旋操作即可;

总结如下:

   

 

 

 

 

 

 

 

 

 

 

 

 

到此位置,红黑树的插入操作就总结完了,至于红黑树的删除操作,后续再总结。

链接1

链接2

链接3

posted @ 2021-03-27 11:47  Peterxiazhen  阅读(86)  评论(0编辑  收藏  举报