vlambda博客
学习文章列表

红黑树的特性与插入操作

1 红黑树特点与性质

红黑树是一种使用键值对来快速查找元素的 自平衡的排序二叉树,其结点的增删改查效率优良,都为logn,比起AVL来说它对于平衡的要求没那么严格,因此旋转和调整次数也会相应少一些,但是左子树和右子树的黑色结点层数是相等的,实现了黑色完美平衡。
正因为红黑树这些的优点使用也非常广泛
1、Linux内核进程调度由红黑树管理进程模块控制
2、nginx服务器用红黑树管理定时器
3、Java8开始,HashMap中,bucket的链表长度大于8时改为红黑树进行存储 我们总结红黑树的特点如下:

  • 每个结点要么黑色要么是红色
  • 根结点是黑色
  • 每个叶子结点NIL是黑色
  • 每个红色结点的两个子结点一定是黑色,不能有两个红色结点相连//即红色结点要么有两个孩子,要么0个孩子
  • 任意一结点到每个叶子结点的路径都包含相同数量的黑色结点,即为黑高
  • 新插入的结点标记为红色,并且从叶子结点插入 实现自平衡主要靠:左旋,右旋 ,变色三种操作来实现。
    变色:结点的颜色由红变黑或由黑变红
    左旋:以某个结点为支点,其右子节点变为旋转结点的父结点,右子节点的左子节点变为旋转结点的右子节点,左子节点保持不变。
    过程如下: 右旋:同理 红黑树的特性与插入操作

2 红黑树插入

情形1:插入空树

直接把插入结点作为根节点,然后将插入节点颜色变为黑色。

情形2:插入节点的key值已存在

相当于更新当前节点的值,将其value变为插入结点的value。对应的图如下:红黑树的特性与插入操作

情形3:插入的结点父节点为黑结点

由于插入的结点是红色的,当插入结点的父节点为黑色时,不影响红黑树的平衡,此时直接插入即可。
红黑树的特性与插入操作发现此时黑树的平衡不受影响。

插入情形4:插入结点的父节点为红色

插入情形4.1:叔结点存在且为红色结点

由红黑树的性质我们可知祖父节点肯定为黑色。此时从祖父结点开始数到插入节点红黑色为:黑红红。最简单的处理方式就是将其变为红黑红(插入结点优先为红色)即:
1、将P和U//即父节点和叔结点//改为黑色
2、将PP//祖父结点//改为红色
3、此时PP结点设为当前结点,进行后续处理

插入情形4.2:叔结点不存在或为黑色结点,且插入前结点的父结点是祖父节点的左子节点

注意:从黑树平衡性来看,叔结点非红即空,否接破坏了红黑树的平衡性,此节点会比其他路径多个黑色结点。

插入情形4.21:插入结点为其父结点的左子节点

此时即为LL情形

  • 变颜色:将P结点设置为黑色,将PP结点设置为红色
  • 对PP结点右旋 红黑树的特性与插入操作

插入情形4.22:插入结点为其父结点的右子节点

此时即为LR情形

  • 对p进行左旋
  • 将p设置为当前节点得到LL红色情况
  • 按照LL红色情况处理//变色,右旋 红黑树的特性与插入操作

插入情形4.3:叔结点不存在或为黑色结点,且插入前结点的父结点是祖父节点的右子节点

操作参照情形4.2

插入情形4.31:插入结点为其父结点的右子节点

此时即为RR情况

  • 将p设置为黑色,pp设置为红色
  • 对pp进行左旋

插入情形4.32:插入结点为其父结点的左子节点

此时为RL情况

  • 对p进行右旋
  • 将p设置为当前结点,即可得到RR红色情况
  • 按照RR红色情况处理//变色,左旋pp

接下来使用一个完整的红黑树插入事例回顾红黑树的插入过程。