数据结构之读懂红黑树

    红黑树是一个平衡的二叉树,但不是一个完美的平衡二叉树。虽然我们希望一个所有查找都能在~lgN次比较内结束,但是这样在动态插入中保持树的完美平衡代价太高,所以,我们稍微放松逛一下限制,希望找到一个能在对数时间内完成查找的数据结构。这个时候,红黑树站了出来。

    阅读以下需要了解普通二叉树的插入以及删除操作。

红黑树是在普通二叉树上,对没个节点添加一个颜色属性形成的,同时整个红黑二叉树需要同时满足以下五条性质:

红黑树需要满足的五条性质:

性质一:节点是红色或者是黑色;

在树里面的节点不是红色的就是黑色的,没有其他颜色,要不怎么叫红黑树呢,是吧。

红黑树需要满足的五条性质:

性质二:根节点是黑色;

根节点总是黑色的。它不能为红。

性质三:每个叶节点(NIL或空节点)是黑色;

这个可能有点理解困难,可以看图:

图片发自简书App

这个图片就是一个红黑树,NIL节点是个空节点,并且是黑色的。

性质四:每个红色节点的两个子节点都是黑色的(也就是说不存在两个连续的红色节点);

就是连续的两个节点不能是连续的红色,连续的两个节点的意思就是父节点与子节点不能是连续的红色。

性质五:从任一节点到其没个叶节点的所有路径都包含相同数目的黑色节点;

图片发自简书App

从上图可以看见相同数量的黑色节点有三个;

当我们进行插入或者删除操作时所作的一切操作都是为了调整树使之符合这五条性质。

下面我们先介绍两个基本操作,旋转。

旋转的目的是将节点多的一支出让节点给另一个节点少的一支,旋转操作在插入和删除操作中经常会用到,所以要熟记。

下面是左旋和右旋:

左旋:

图片发自简书App

右旋:

图片发自简书App

插入:

下面讲讲插入

我们先明确一下各节点的叫法

图片发自简书App

    因为要满足红黑树的这五条性质,如果我们插入的是黑色节点,那就违反了性质五,需要进行大规模调整,如果我们插入的是红色节点,那就只有在要插入节点的父节点也是红色的时候违反性质四或者是当插入的节点是根节点时,违反性质二,所以,我们把要插入的节点的颜色变成红色。

下面是可能遇到的插入的几种状况:

1、当插入的节点是根节点时,直接涂黑即可;

2、当要插入的节点的父节点是黑色的时候。

图片发自简书App

这个时候插入一个红色的节点并没有对这五个性质产生破坏。所以直接插入不用在进行调整操作。

3、如果要插入的节点的父节点是红色且父节点是祖父节点的左支的时候。

这个要分两种情况,一种是叔叔节点为黑的情况,一种是叔叔节点为红的情况。

当叔叔为黑时,也分为两种情况,一种是要插入的节点是父节点的左支,另一种是要插入的节点是父亲的右支。

我们先看一下当要插入的节点是父节点的左支的情况:

图片发自简书App

这个时候违反了性质四,我们就需要进行调整操作,使之符合性质四,我们可以通过对祖父节点进行右旋同时将祖父节点和父节点的颜色进行互换,这样就变成了:

图片发自简书App

经过这样的调整可以符合性质四并且不对其他性质产生破坏。

当插入的节点是父节点的右支的时候:


图片发自简书App

当要插入的节点是父节点的右支的时候,我们可以先对父节点进行左旋,变成如下:

图片发自简书App

如果我们把原先的父节点看做是新的要插入的节点,把原先要插入的节点看做是新的父节点,那就变成了当要插入的节点在父节点的左支的情况,对,是的,就是按照当要插入的节点在父节点的左支的情况进行旋转,旋转完之后变成如下:

图片发自简书App

4、如果要插入的节点的父节点是红色且父节点是祖父节点的右支的时候;

这个时候的情况跟情况3所表述的情况是一个镜像,将情况3的左和右互换一下就可以了。

5、如果要插入的节点的父节点是红色并且叔叔节点也为红色,如下:

图片发自简书App

这个时候,只需将父亲节点和叔叔节点涂黑,将祖父节点涂红。

以上就是插入的全部过程。

删除:

首先你要了解普通二叉树的删除操作:

1.如果删除的是叶节点,可以直接删除;

2.如果被删除的元素有一个子节点,可以将子节点直接移到被删除元素的位置;

3.如果有两个子节点,这时候就可以把被删除元素的右支的最小节点(被删除元素右支的最左边的节点)和被删除元素互换,我们把被删除元素右支的最左边的节点称之为后继节点(后继元素),然后在根据情况1或者情况2进行操作。如图:

图片发自简书App

将被删除元素与其右支的最小元素互换,变成如下图所示:

图片发自简书App

然后再将被删除元素删除:

图片发自简书App

我们下面所称的被删除元素,皆是指已经互换之后的被删除元素。

加入颜色之后,被删除元素和后继元素互换只是值得互换,并不互换颜色,这个要注意。

下面开始讲一下红黑树删除的规则:

1.当被删除元素为红时,对五条性质没有什么影响,直接删除。

2.当被删除元素为黑且为根节点时,直接删除。

3.当被删除元素为黑,且有一个右子节点为红时,将右子节点涂黑放到被删除元素的位置,如图:

由:

图片发自简书App

变成:

图片发自简书App

4.当被删除元素为黑,且兄弟节点为黑,兄弟节点两个孩子也为黑,父节点为红,此时,交换兄弟节点与父节点的颜色;NIL元素是指每个叶节点都有两个空的,颜色为黑的NIL元素,需要他的时候就可以把它看成两个黑元素,不需要的时候可以忽视他。

如图:

由:

图片发自简书App

变成:

图片发自简书App

5.当被删除元素为黑、并且为父节点的左支,且兄弟颜色为黑,兄弟的右支为红色,这个时候需要交换兄弟与父亲的颜色,并把父亲涂黑、兄弟的右支涂黑,并以父节点为中心左转。如图:

由:

图片发自简书App

变成:

图片发自简书App

6.当被删除元素为黑、并且为父节点的左支,且兄弟颜色为黑,兄弟的左支为红色,这个时候需要先把兄弟与兄弟的左子节点颜色互换,进行右转,然后就变成了规则5一样了,在按照规则5进行旋转。如图:

由:

图片发自简书App

先兄弟与兄弟的左子节点颜色互换,进行右转,变成:

图片发自简书App

然后在按照规则5进行旋转,变成:

图片发自简书App

7.当被删除元素为黑且为父元素的右支时,跟情况5.情况6 互为镜像。


8.被删除元素为黑且兄弟节点为黑,兄弟节点的孩子为黑,父亲为黑,这个时候需要将兄弟节点变为红,再把父亲看做那个被删除的元素(只是看做,实际上不删除),看看父亲符和哪一条删除规则,进行处理变化如图:

由:

图片发自简书App

变成:

图片发自简书App

8.当被删除的元素为黑,且为父元素的左支,兄弟节点为红色的时候,需要交换兄弟节点与父亲结点的颜色,以父亲结点进行左旋,就变成了情况4,在按照情况四进行操作即可,变化如下:

由:

图片发自简书App

交换兄弟节点与父亲结点的颜色,以父亲结点进行左旋 变成:

图片发自简书App

在按照情况四进行操作,变成:

图片发自简书App

好了,删除的步骤也讲完,没有讲到的一点就是,在添加删除的时候,时刻要记得更改根元素的颜色为黑。

这里并没有语言实现,只是讲了一下红黑树的插入删除步骤,你可以根据步骤自己把红黑树实现。

我们一起照着规则一步一步的构建一个红黑树吧。

最后:


1.红黑树的实现其实是一个2、3、4树,只是将双节点或者三节点用红色进行了标示,如果你将红色节点放到和它父元素相同的高度,并把它和父元素看做是一个元素,你就会发现,变成了一个高度为lgN的二叉树,这个2.3.4树对红黑树很有启发意义。

2.上面的步骤其实可以不用死记硬背,是可以推导出来的,因为我们是把一个平衡但通过插入或者删除破坏了平衡的红黑树再次平衡,同过旋转让位,改变红黑颜色,使之符合那五条基本性质。比如遇到删除操作情况四的时候,我们可以把那个删除元素去除,发现左边比右边少一个黑元素,这个时候,怎么办,我们发现兄弟节点的子元素有一个红元素,操作这个不会影响那五条性质,所以我们通过变换颜色,旋转,即可让左右两边的的黑色数目一样。

3.旋转操作的目的是出让一个元素到另外的地方并且符合二叉树左小右大的性质,交换颜色的目的是为了保持红黑树的那五条性质。

4.要时刻记得 ,一切的操作都是为了保持那五条性质。

最后的最后,其实还有一种更为简单的红黑二叉树,这个简单的红黑二叉树实际上是一个2.3树,他只允许左节点为红节点,但是性能上肯定是不如这个红黑树。这个简单的红黑二叉树在《算法》第四版有介绍,掌握完之后再看这个简单的红黑二叉树,就会觉着简单 easy。

最后的最后的最后,一定要尝试着自己推导一下插入删除规则啊,不然经常忘,是睡一觉起来再看就有点懵逼的那种忘。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • D9 行程 Day 9:巴斯 (皇家新月- 普尔特尼桥 - 罗马浴场 - 圣约翰教堂) - 巨石阵 又出城了。。。...
    肖庆in上海阅读 648评论 1 2
  • 一个事情坚持坚持做,是为了完成任务而去做的,会不会,就觉得继续坚持下去没有必要? 算了,姑且还是坚持下去吧~有时候...
    知知木子阅读 268评论 0 0
  • 清风绵绵吹过我的脸庞, 两三行人漫步在静谧的小巷, 岁月将思念打扫得很干净, 绕过这条河, 有间青砖的瓦房。 你露...
    折柳丶待卿归阅读 404评论 0 6
  • 路的左右是草甸,风从草间过,平野里蛙声虫鸣此起彼伏,星光像珠帘一样从高高的深蓝色里缀下,我们走在星垂下的平野里。 ...
    怪兽出来吓人了阅读 360评论 0 1
  • 当我们感到伤痛时,会经常听到朋友对我们说不要难过,开心一点嘛。 细想朋友虽然是出于好心,但在当下对我们并没有太大的...
    周程程爱说大实话阅读 331评论 0 0