红黑树详解(一)红黑树的介绍和操作

摘要:

    在很多源码涉及到大量数据处理的时候,通常都是用红黑树这一数据结构。红黑树是一种自平衡的二叉查找树,它能在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,获得较高的查找性能。本文将使用图文详细的分析红黑树

一、红黑树解决了什么问题

首先,我们要知道二叉搜索树,在不为空的情况下,左子树上所有结点的值均小于它的根结点的值,右子树上所有结点的值均大于它的根结点的值。它使得数据查找起来不是线性查找(O(n)),平均复杂度仅仅为O(log(n)).

红黑树 Redis 红黑树解决了什么问题_算法

但是在最快情况下,二叉搜索树可能变为线性搜索,退化为链表,复杂度为O(n),那就没有意义了,如下图的情况所示。

红黑树 Redis 红黑树解决了什么问题_红黑树 Redis_02

为了避免这种情况发生,就到了我们的主角红黑树,它规定了一些性质使得这种情况不会发生。

二、红黑树的性质

红黑树主要有这五条性质。

  • 1.节点不是红色就是黑色
  • 2.根节点是黑色
  • 3.叶子节点(NIL)为黑色
  • 4.每个红色节点的两个子节点都是黑色。((从每个叶子到根的所有路径上不能有两个连续的红色节点)
  • 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点

如下图所示

红黑树 Redis 红黑树解决了什么问题_红黑树 Redis_03

三、红黑树的操作

在进行红黑树的插入、删除时候,很可能会破坏红黑树的五条性质。因此,我们需要一些操作来维护红黑树五条性质不被破坏。主要有三种操作,变色、左旋右旋.

为了更好的理解以下操作,这里规定一些叫法。

1.变色

顾名思义,就是改变树结点的颜色。如果不能仅仅通过变色解决问题,就需要旋转操作。

2.左旋

以结点p作为支点进行左旋,其左子结点不变,右子结点变为p的右子节点的左子结点,且p的父结点变为右子结点。

支点为p,其父结点为pp,右子结点和左子结点为r和l,r的左右孩子分别为rl和rr。则示意图如下:

红黑树 Redis 红黑树解决了什么问题_算法_04

3.右旋

        以结点p作为支点右旋,其右子结点不变,左子结点变为其左子结点的右子结点,且p的父结点变为左子结点。

        支点为p,其父结点为pp,右子结点和左子结点为r和l,l的左右孩子分别为ll和lr。则示意图如下:

        如图所示

红黑树 Redis 红黑树解决了什么问题_数据结构_05


左旋右旋实际上是一边子树的结点少了,向另外一边子树借结点。