红黑树,超强动静图详解,简单易懂

写在前面

红黑树,对很多童鞋来说,是既熟悉又陌生。学校中学过,只了解大概;工作中不怎么使用,但面试又是重点。每次需要查看红黑树内容时都很难以更生动形象的方式来理解其内容。没错,本文内容就是要解决这个问题,用简单的语言,搭配静图和动图(利用大脑图形记忆方式),让你对红黑树有更深入的了解和更清晰的记忆,希望小伙伴们再次遇到红黑树的问题不至于头大,建议读该文章姿势: 打开两个页面,一个页面看图片和内容,一个页面看公式,像玩魔方一样,多玩几次就明白了

通过工具 (公众号回复「工具」—>那些可以提高效率的工具—>红黑树) 动态感受红黑树的转换过程

image

俺家司令买完东西后,我俩经常会发生这样的一段对话:

司令:你猜我买的这个多少钱?
我: 1000
司令: 高了
我: 500
司令: 低了:
我: 750
...... 直到最后猜中

这样说大家应该已经猜到了是「二分查找法」,通过这个例子我想要引出的是 ,来看图片

image

程序中的树其实是我们日常看到的树的倒影,或者发挥一下想象,倒影也可以是树根

二叉查找树

二叉查找树,Binary Search Tree 「BST」,要想了解二叉查找树,我们首先看下二叉查找树有哪些特性呢?

  1. 某节点的左子树节点值仅包含小于该节点值
  2. 某节点的右子树节点值仅包含大于该节点值
  3. 左右子树每个也必须是二叉查找树
    看个图就轻松理解上面三句话的意思了:
image

上图,结合二叉查找树的三条约束来看,非常好,没有什么问题。再来看一个图,依旧符合上面三条约束,感觉有问题吗?

image
  1. 这是一个走路一米六,一米八的树
  2. 这是一个畸形的树,大风一挂很可能被折断的树
    从程序的角度来说这个树不够平衡,查找次数或时间复杂度 O(h)可能会随着一条腿长无限增长

理科生在高中学习生物时学过一个关键字「去除顶端优势」,通过去除植物顶端优势,侧芽会迅速生长,慢慢变得强壮和平衡, 红黑树其实就是去除二叉查找树顶端优势的解决方案,从而达到树的平衡

红黑树

红黑树,Red-Black Tree 「RBT」是一个自平衡(不是绝对的平衡)的二叉查找树(BST),树上的每个节点都遵循下面的规则:

  1. 每个节点都有红色或黑色
  2. 树的根始终是黑色的 (黑土地孕育黑树根,😄)
  3. 没有两个相邻的红色节点(红色节点不能有红色父节点或红色子节点,并没有说不能出现连续的黑色节点
  4. 从节点(包括根)到其任何后代NULL节点(叶子结点下方挂的两个空节点,并且认为他们是黑色的)的每条路径都具有相同数量的黑色节点

瞬间懵逼?了解一下印象就行,开始玩魔方都是要照着魔方公式一点点玩的,多玩几次就熟悉了。红黑树也一样,红黑树有两大操作:

  1. recolor (重新标记黑色或红色)
  2. rotation (旋转,这是树达到平衡的关键)
    我们会先尝试 recolor,如果 recolor 不能达到红黑树的 4 点要求,然后我们尝试 rotation,其实红黑树的关键玩法就是弄清楚 recolor 和 rotation 的规则,接下来看看详细的算法公式吧 千万别着急记忆公式,有图示会逐步说明,就像魔方一样,多玩几次就懂了:
    假设我们插入的新节点为 X
    1. 将新插入的节点标记为红色
    1. 如果 X 是根结点(root),则标记为黑色
    1. 如果 X 的 parent 不是黑色,同时 X 也不是 root:
    • 3.1 如果 X 的 uncle (叔叔) 是红色
      • 3.1.1 将 parent 和 uncle 标记为黑色
      • 3.1.2 将 grand parent (祖父) 标记为红色
      • 3.1.3 让 X 节点的颜色与 X 祖父的颜色相同,然后重复步骤 2、3

话不多说,看下图


image

跟着上面的公式走:

  1. 将新插入的 X 节点标记为红色
  2. 发现 X 的 parent (P) 同样为红色,这违反了红黑树的第三条规则「不能有两个连续相邻的红色节点」
  3. 发现 X 的 uncle (U) 同样为红色
  4. 将 P 和 U 标记为黑色
  5. 将 X 和 X 的 grand parent (G) 标记为相同的颜色,即红色,继续重复公式 2、3
  6. 发现 G 是根结点,标记为黑色
  7. 结束

刚刚说了 X 的 uncle 是红色的情况,接下来要说是黑色的情况

    1. 如果 X 的 parent 不是黑色,同时 X 也不是 root:
    • 3.2 如果 X 的 uncle (叔叔) 是黑色,我们要分四种情况处理
      • 3.2.1 左左 (P 是 G 的左孩子,并且 X 是 P 的左孩子)
      • 3.2.2 左右 (P 是 G 的左孩子,并且 X 是 P 的右孩子)
      • 3.2.3 右右 (和 3.2.1 镜像过来,恰好相反)
      • 3.2.4 右左 (和 3.2.2 镜像过来,恰好相反)
        当出现 uncle 是黑色的时候我们第一步要考虑的是 旋转 ,这里先请小伙伴不要关注红黑树的第 4 条规则,主要是为了演示如何旋转的,来一点点看,不要看图就慌,有解释的😜:

左左情况

这种情况很简单,想象这是一根绳子,手提起 P 节点,然后变色即可

image

左右

左旋: 使 X 的父节点 P 被 X 取代,同时父节点 P 成为 X 的左孩子,然后再应用 左左情况

image

右右

与左左情况一样,想象成一根绳子


image

右左

右旋: 使 X 的父节点 P 被 X 取代,同时父节点 P 成为 X 的右孩子,然后再应用 右右情况

image

你说的动图在哪里,你个大骗子,别着急,现在就为小伙伴们奉上动图演示,来说明公式的使用:

案例一

插入 10,20,30,15 到一个空树中

  1. 向空树中第一次插入数字 10,肯定是 root 节点

  2. root 节点标记成黑色


    image
  3. 向树中插入新节点 20,标记为红色

  4. 20 > 10,并发现 10 没有叶子节点,将新节点 20 作为 10 的右孩子


    image
  5. 向树中插入新节点 30,标记为红色

  6. 30 > 10,查找 10 的右子树,找到 20

  7. 30 > 20,继续查找 20 的右子树,发现 20 没有叶子节点,将值插在此处

  8. 30 和 20 节点都为红色,30 为右孩子,20 也为右孩子,触发了 右右情况

  9. 通过一次旋转,提起 20 节点

  10. 20 节点是根结点,标记为黑色


    image
  11. 向树中插入新节点 15,标记为红色

  12. 通过比对大小和判断是否有叶子节点,最终插值为 10 节点的右孩子

  13. 15 和 10 节点都为红色,15 的 uncle 节点 30 也为红色

  14. 按照公式,将 15 的 parent 10 和 uncle 30 更改为黑色

  15. 让 15 节点 grand parent 20 的颜色与 15 节点的颜色一样,变为红色

  16. 20 为根结点,将其改为黑色


    image

继续插入其他节点只不过反复应用上面的公式,上面应用到的红黑树工具,可以暂停动画效果,一帧一帧的看红黑树的转换过程,这样通过练习,查看公式,观察变化三管齐下,红黑树的入门理解应该完全不再是问题了

灵魂追问

  1. jdk 1.8 HashMap 中有使用到红黑树,你知道触发条件是什么吗?有读过源码是如何 put 和 remove 的吗?
  2. 这里讲的是红黑树的 insert,delete 又是什么规则呢?
  3. 哪些场景可以应用红黑树?
  4. 你了解各种树的时间复杂度吗?
  5. 留个小作业,应用工具将 [10 70 32 34 13 56 32 56 21 3 62 4 ] 逐个插入到树中,理解红黑树 recolor 和 rotation 的转换规则

提高效率工具

image

[center]


推荐阅读


欢迎持续关注公众号:「日拱一兵」

  • 前沿 Java 技术干货分享
  • 高效工具汇总
  • 面试问题分析与解答
  • 技术资料领取

后续文章会为你讲解各种时间空间复杂度,以及多线程,ElasticSearch 等问题

以读侦探小说思维轻松趣味学习 Java 技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,请持续关注......

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

推荐阅读更多精彩内容