红黑树(Red-Black Tree)

  • 红黑树是一种BST,但是每个节点上增加一个存储位表示该节点的颜色(R或者B);通过对任何一条从root到leaf的路径上节点着色方式的显示,红黑树确保所有路径的差值不会超过一倍,最终使得BST接近平衡;
  • 红黑树内每个节点包含五个属性:color, key, left, right和p,p表示指向父亲节点的指针;一棵BST需要同时满足下述五个性质才能称作红黑树:

    每个节点只能是红色或者黑色节点中的一种;

    根节点必须是黑色;

    每个叶节点(NULL)必须是黑色;

    如果一个节点是红色,则它的两个子节点必须是黑色;

    对于树中任何一个节点,该节点到其叶节点的所有路径上的黑色节点数相同

  • 红黑树的空间复杂度为O(N);支持三种操作:search, insert, delete,并且所有操作的时间复杂度都为O(logN),最好情况跟最坏情况的复杂度相同。对于search操作而言,其依赖BST的性质,所以不需 要依赖节点的着色信息;着色信息仅为了保证BST的平衡性,insert和delete操作则可能破坏BST的平衡性,所以这两种操作需要对红黑树中节点 的着色信息进行调整。
     
 //左旋操作中,oldroot的右子节点成为新的root,root的左子节点成为oldroot的右子节点,
//oldroot成为新root的左子节点
template <class KeyType>
void Node<KeyType>::RotateLeft(Node<KeyType> * & root) {
Node<KeyType> * oldRoot = root;
root = root->mySubtree[RIGHT];
oldRoot->mySubtree[RIGHT] = root->mySubtree[LEFT];
root->mySubtree[LEFT] = oldRoot;
} //右旋操作中,oldroot的左子节点成为新的root,root的右子节点成为oldroot的左子节点,
//oldroot成为新root的右子节点
template <class KeyType>
void Node<KeyType>::RotateRight(Node<KeyType> * & root) {
Node<KeyType> * oldRoot = root;
root = root->mySubtree[LEFT];
oldRoot->mySubtree[LEFT] = root->mySubtree[RIGHT];
root->mySubtree[RIGHT] = oldRoot;
} //向T索引的红黑树中插入新节点z,使用BST的性质查找z的插入位置,并且将新节点z标
//注为红色;
RB-INSERT(T, z)
y ← nil[T]
x ← root[T]
while x ≠ nil[T]
do y ← x
if key[z] < key[x]
then x ← left[x]
else x ← right[x]
p[z] ← y
if y = nil[T]
then root[T] ← z
else if key[z] < key[y]
then left[y] ← z
else right[y] ← z
left[z] ← nil[T]
right[z] ← nil[T]
color[z] ← RED
RB-INSERT-FIXUP(T, z)

插入一个节点并标注为红色的操作可能破坏红黑树的性质2和性质4;当插入节点为根节点的时候破坏性质2,此时直接将其变成黑色就可以恢复;当破坏性质4的时候则需要一系列的恢复操作;
case1:原树为空,新节点为根节点;恢复策略为将其改成黑色;
case2:新节点的父节点是黑色;满足所有红黑树规则;
case3:新节点的父节点是红色,父节点的兄弟节点是红色;恢复策略为将新节点的父节点和父节点的兄弟节点改成黑色,其祖父节点改成红色,针对祖父节点重新调用该方法;
case4:新节点的父节点是红色,父节点的兄弟节点是黑色,新节点为父节点的右子;恢复策略为以新节点的父节点为支点左旋;
case5:新节点的父节点是红色,父节点的兄弟节点是黑色,新节点为父节点的左子;恢复策略为将新节点的父节点改成黑色,祖父节点改成红色,并以祖父节点为支点右旋;

 RB-INSERT-FIXUP(T, z)
while color[p[z] = RED
do if p[z] = left[p[p[z]]
then y ← right[p[p[z]]
if color[y] = RED
then color[p[z] ← BLACK ▹ Case
color[y] ← BLACK ▹ Case
color[p[p[z]] ← RED ▹ Case
z ← p[p[z] ▹ Case
else if z = right[p[z]
then z ← p[z] ▹ Case
LEFT-ROTATE(T, z) ▹ Case
color[p[z] ← BLACK ▹ Case
color[p[p[z]] ← RED ▹ Case
RIGHT-ROTATE(T, p[p[z]) ▹ Case
else (same as then clause with "right" and "left" exchanged)
color[root[T] ← BLACK //
RB-DELETE(T, z)
if left[z] = nil[T] or right[z] = nil[T]
then y ← z
else y ← TREE-SUCCESSOR(z)
if left[y] ≠ nil[T]
then x ← left[y]
else x ← right[y]
p[x] ← p[y]
if p[y] = nil[T]
then root[T] ← x
else if y = left[p[y]
then left[p[y] ← x
else right[p[y] ← x
if y ≠ z
then key[z] ← key[y]
copy y's satellite data into z
if color[y] = BLACK
then RB-DELETE-FIXUP(T, x)
return y

case1:x的兄弟w是红色
case2:x的兄弟w是黑色,并且w的两个孩子是黑色
case3:x的兄弟w是黑色,并且w的左孩子是红色,w的右孩子是黑色
case4:x的兄弟w是黑色,并且w的右孩子是红色

 RB-DELETE-FIXUP(T, x)
while x ≠ root[T] and color[x] = BLACK
do if x = left[p[x]
then w ← right[p[x]
if color[w] = RED
then color[w] ← BLACK ▹ Case
color[p[x] ← RED ▹ Case
LEFT-ROTATE(T, p[x]) ▹ Case
w ← right[p[x] ▹ Case
if color[left[w] = BLACK and color[right[w] = BLACK
then color[w] ← RED ▹ Case
x ← p[x] ▹ Case
else if color[right[w] = BLACK
then color[left[w] ← BLACK ▹ Case
color[w] ← RED ▹ Case
RIGHT-ROTATE(T, w) ▹ Case
w ← right[p[x] ▹ Case
color[w] ← color[p[x] ▹ Case
color[p[x] ← BLACK ▹ Case
color[right[w] ← BLACK ▹ Case
LEFT-ROTATE(T, p[x]) ▹ Case
x ← root[T] ▹ Case
else (same as then clause with "right" and "left" exchanged)
color[x] ← BLACK

笔试算法题(51):简介 - 红黑树(RedBlack Tree)的更多相关文章

  1. [Data Structure] 红黑树( Red-Black Tree ) - 笔记

    1.  红黑树属性:根到叶子的路径中,最长路径不大于最短路径的两倍. 2. 红黑树是一个二叉搜索树,并且有 a. 每个节点除了有左.右.父节点的属性外,还有颜色属性,红色或者黑色. b. ( 根属性 ...

  2. [转]SGI STL 红黑树(Red-Black Tree)源代码分析

    STL提供了许多好用的数据结构与算法,使我们不必为做许许多多的重复劳动.STL里实现了一个树结构-Red-Black Tree,它也是STL里唯一实现的一个树状数据结构,并且它是map, multim ...

  3. 红黑树red-black tree

    书籍:<算法导论>第13章 红黑树性质:1. 每个节点要么red要么black.2. 根节点是black节点.3. 叶子节点是black节点.4. red节点的左右儿子节点都是black节 ...

  4. 红黑树(Red-Black Tree),B树,B-树,B+树,B*树

    (一)红黑树(Red-Black Tree) http://www.cnblogs.com/skywang12345/p/3245399.html#a1 它一种特殊的二叉查找树.红黑树的每个节点上都有 ...

  5. 红黑树( Red-Black Tree ) - 笔记

    1.  红黑树属性:根到叶子的路径中,最长路径不大于最短路径的两倍. 2. 红黑树是一个二叉搜索树,并且有 a. 每个节点除了有左.右.父节点的属性外,还有颜色属性,红色或者黑色. b. ( 根属性  ...

  6. 红黑树(Red-Black Tree)

    概念解析: 红黑树是一种自平衡二叉查找树(self-balancing binary search tree).因此,红黑树本身就是二叉树的一个变种.典型的用途是实现关联数组(Associative ...

  7. 手撸红黑树-Red-Black Tree 入门

    一.学习红黑树前的准备: 熟悉基础数据结构 了解二叉树概念 二.红黑树的规则和规则分析: 根节点是黑色的 所有叶子节点(Null)是黑色的,一般会认定节点下空节点全部为黑色 如果节点为红色,那么子节点 ...

  8. 笔试算法题(47):简介 - B树 & B+树 & B*树

    B树(B-Tree) 1970年由R. Bayer和E. Mccreight提出的一种适用于外查找的树,一种由BST推广到多叉查找的平衡查找树,由于磁盘的操作速度远小于存储器的读写速度,所以要求在尽量 ...

  9. Java数据结构和算法(十一)——红黑树

    上一篇博客我们介绍了二叉搜索树,二叉搜索树对于某个节点而言,其左子树的节点关键值都小于该节点关键值,右子树的所有节点关键值都大于该节点关键值.二叉搜索树作为一种数据结构,其查找.插入和删除操作的时间复 ...

随机推荐

  1. 【193】◀▶ PowerShell 官方资料索引

    Microsoft.PowerShell.Core 模块 Windows PowerShell 核心 Cmdlet Windows PowerShell 核心函数 Windows PowerShell ...

  2. git合并相关问题(copy)

    [说明:资料来自http://gitbook.liuhui998.com/3_3.html] 一个Git仓库可以维护很多开发分支.现在我们来创建一个新的叫”experimental”的分支: $ gi ...

  3. HDU1244:Max Sum Plus Plus Plus

    题目链接:Max Sum Plus Plus Plus 题意:在n个数中取m段数使得这m段数之和最大,段与段之间不能重叠 分析:见代码 //dp[i][j]表示前i个数取了j段的最大值 //状态转移: ...

  4. 【插件开发】—— 5 SWT控件以及布局使用

    前文回顾: 1 插件学习篇 2 简单的建立插件工程以及模型文件分析 3 利用扩展点,开发透视图 4 SWT编程须知 经过前几篇的介绍,多少对SWT又有了一些认识,那么这篇继续来看一下一些控件的组合使用 ...

  5. [App Store Connect帮助]七、在 App Store 上发行(3.2)提交至“App 审核”:查看 App 状态历史记录

    您可以查看您 App 的某一版本的 App 状态历史记录.在历史记录表中的每一行都包含 App 状态.App 状态更改时间,以及更改的发起人.使用此信息追踪“App 审核”流程中的 App. 若想在 ...

  6. 支持宕机自动恢复触发一次性或周期性任务执行的组件包首次介绍-easyTask

    easyTask介绍 一个方便触发一次性或周期性任务执行的工具包,支持海量,高并发,高可用,宕机自动恢复任务 使用场景 需要精确到秒的某一时刻触发任务执行.比如订单交易完成24小时后如果客户未评价,则 ...

  7. 采购发票检验MIRO差异科目设置

    采购订单发票检验时,最终的金额可能跟采购订单的价格不一样,对于这部分差异,系统提供了后台配置科目的方式. 配置科目可通过OBYC,在BSX存货差异配置相关评估类型对应科目. 当库存商品少于采购订单数量 ...

  8. quickpow || 快速幂

    洛谷例题 推荐自行脑补:百度百科 如果  ,那么 : 前言:快速幂就是快速算底数的n次幂.其时间复杂度为 O(log₂N), 与朴素的O(N)相比效率有了极大的提高. 拿题目样例 Input :2 1 ...

  9. [AHOI2007]密码箱

    Description 在一次偶然的情况下,小可可得到了一个密码箱,听说里面藏着一份古代流传下来的藏宝图,只要能破解密码就能打开箱子,而箱子背面刻着的古代图标,就是对密码的提示.经过艰苦的破译,小可可 ...

  10. 暑期训练狂刷系列——poj 3468 A Simple Problem with Integers (线段树+区间更新)

    题目连接: http://poj.org/problem?id=3468 题目大意: 给出n个数,有两种操作: 1:"C a b c",[a,b]中的每一个数都加上c. 2:&qu ...