红黑树

红黑树是一种特殊的二叉查找树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。红黑树,本质上来说就是一棵二叉查找树,但它在二叉查找树的基础上增加了着色和相关的性质使得红黑树相对平衡,从而保证了红黑树的查找、插入、删除的时间复杂度最坏为 \(O(log n)\)。

屏幕快照 2017-04-22 下午8.46.06

红黑树的性质

  1. 每个节点或者是黑色,或者是红色。

  2. 根节点是黑色。

  3. 每个叶子节点(NIL)是黑色。 注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点

  4. 如果一个节点是红色的,则它的子节点必须是黑色的。

  5. 对于任一结点而言,其到叶结点树尾端NIL指针的每一条路径都包含相同数目的黑结点。确保没有一条路径会比其他路径长出俩倍。因而,红黑树是相对是接近平衡的二叉树。

  6. 一棵含有n个节点的红黑树的高度至多为\(2log(n+1)\)。


左旋与右旋

无论 左旋 或 右旋,它们都是以某一个节点为中心点。注意:这里,我们理解成以节点(节点\(x\))进行旋转,而不是以一个分支(分支\(xy\) 轴 或 分支 \(xz\) 轴)进行旋转。

屏幕快照 2017-04-22 下午10.09.58


红黑树的插入

向一颗含有 \(n\) 个节点的红黑树中插入一个节点,可以在时间\(O(logn)\) 内完成。

将一个节点插入到红黑树中应该按照下面步骤来

  1. 将 \(T\) 当作一颗二叉树,将 \(z\) 插入

  2. 将 \(z\) 着色为红色:将 \(z\) 着色为红色之后因为要满足红黑树的定义

  3. 通过 RB-INSERT-FIXUP 来对节点重新着色并旋转,以此来保证插入节点后的树仍然是一颗红黑树。

    • 插入一个红色节点之后,虽然没有违背“特性(5)”,但是却可能违背了其它特性(例如,若被插入节点的父节点也是红色;插入后,则违背了“特性(4)”)。我们需要通过RB-INSERT-FIXUP进行节点颜色的调整以及旋转等工作,让树仍然是一颗红黑树。

当节点 \(z\) 被着色为红色节点,并插入二叉树时,有三种情况。

  1. 被插入的节点是根节点: 直接把此节点涂为黑色。

  2. 被插入的节点的父节点是黑色: 什么也不需要做。节点被插入后,仍然是红黑树。

  3. 被插入的节点的父节点是红色: 此时与红黑树的“特性(5)”相冲突: 它的处理思想是:将红色的节点移到根节点;然后,将根节点设为黑色。

    • 叔叔是红色

    • 叔叔是黑色,且当前节点是右孩子

    • 叔叔是黑色,且当前节点是左孩子


删除节点:将红黑树 \(T\) 内的节点 \(z\) 删除

  • 首先,将 \(T\) 当作一颗二叉树,将节点删除;
  • 然后,通过RB-DELETE-FIXUP来对节点重新着色并旋转,以此来保证删除节点后的树仍然是一颗红黑树。

参考文献

posted @ 2017-04-22 20:47  I呆呆  阅读(271)  评论(0)    收藏  举报