Red Black Tree 的一点感想

本贴最后更新于 2321 天前,其中的信息可能已经天翻地覆

红黑树的基本性质

  1. 每个节点或是红色的,或是黑色的。
     2) 根节点是黑色的。
     3) 每个叶节点(NIL)是黑色的。
     4) 如果一个节点是红色的,则它的两个子节点都是黑色的。
     5) 对每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。

红黑树插入时,如果插入红色节点则
(由于插入黑色节点一定会导致性质五被破坏,所以考虑插入为红色节点的情况)

  1. 性质一不会破坏
  2. 性质二可能破坏
  3. 性质三不会被破坏
  4. 性质四可能被破坏
  5. 性质五不会被破坏

当插入导致性质被破坏时需要调整:
由上面所述,只有性质二和四可能被破坏,而性质二只有在插入之前为空树时可能被破坏。所以我们需要关注性质四,即插入导致两个红色节点连在了一起。下面分情况表述:

  • **1.插入的节点为根节点:**若插入前无任何节点,则插入后的节点为根节点直接设置为黑色即可。
  • **2.插入的节点的父节点为黑色节点:**无需做任何改变因为不会影响红黑树性质
  • 3.插入的节点的父节点为红色且 uncle 节点也是红色: 此时将导致两个红色节点连接到了一起,此时我们考虑改变两个红色节点之中的一个,然而改变插入节点的颜色显然是无意义的,(如果改变相当于插入黑色节点),所以我们将插入节点的父节点设置为黑色,然而这样同时会导致性质五的违背,所以我们将其 uncle 节点也设置为黑色,并将 parent 的 parent 节点设置为红色,此时调整完成。插入节点为 M,如下图:
    3d65bdf1eef44c8d9856bcc9dba0f572-image.png
    (图片来源于网络)
  • **4.插入节点的父节点为红色且 uncle 节点为黑色(T.nil 也为黑色),插入节点为右节点:**以插入节点的的父节点作为支点左旋变成情况 5,再调整

    (图片来源于网络)
  • **5.插入节点父节点为红色,uncle 节点为黑色(T.nil 为黑色),插入节点为的左子节点:**将 parent 节点设置为黑色,parent 的 parent 节点设置为红色,并以 parent 节点为支点右旋。

    (图片来源于网络)
    删除节点:
    当我们删除一个节点时,z 指向删除节点,y 指向替换删除删除节点的节点,x 指向 y 的右子树,首先按照二叉搜索树的的删除方式进行删除,并在其中加入部分代码记录 Y 的踪迹和 y 的初始颜色,还有 x 的踪迹(见《算法导论》第三版 183 页)。
    删除节点的过程:当 z 只有一个子树时,y 指向该子树,并直接将子树 y 替换 z,当 z 有两个子树时选择右子树的最左侧节点作为 y,并用 y 替换 z,并用 x 替换 y,并进行 red-black tree 调整。
    所以实际过程相当于删除 Y

当 y 是红色时,删除后不会影响红黑树的基本性质,可直接删除

当如果 y 是黑色,会出现如下三种情况:
1.如果原先的 y 是根节点,y 的红色 x 替换 y 将导致违反性质 2
2.如果替换后 x 和 x 的父节点都为红色则违反性质 4
3.y 在树中移动将导致包含 y 的任何简单路径和高度减一。

所以我们需要对 y 为黑色节点时被 x 替换后的树进行调整。
由于懒得画图使用网络图片~~~~这时 N 上文所述的 x
1.如果 N 的兄弟节点为红色时
将 B 设置为黑色,N 的父节点 P 设置为红色,然后以 P 为中心左旋转,则转换情况 2

(图片来源于网络)

2.如果 N 的兄弟节点为黑色,并且两个子节点都为黑色(包括 T.nil):
将 N 的兄弟节点 B 变红,然后用 N 的父节点 P 作为新的 N,进行递归操作。因为 N 是 P 的左子树,P 的左子树路径中,删除 N 后,会缺少一个黑色节点,因此递归的将右树上的路径也减少一个黑色节点,知道 N 的颜色为红色。最后把当前的 N 节点置为黑色。最后产生的结果就是将右侧的黑色节点上移,这样右子树和左子树都没有减少黑色节点。

(图片来源于网络)
3.如果 N 的兄弟节点 B 是黑色的他的左孩子为红色,右孩子为黑色
将 B 变红,b1 变黑,然后以 B 为中心右旋,则转换为情况 4

(图片来源于网络)
4.如果 N 的兄弟节点 B 是黑色他的右孩子为红色,左孩子可红可黑
将 B 的颜色设置为与 P 的颜色一致,然后 P 和 b2 设置为黑色,以 P 为中心左旋。

(图片来源于网络)
至此正文结束
分割线------------------------------------------------------------------------
花了我整整一下午加一晚上时间才看懂了此算法,并立刻跟新博客,也为以后如果忘记也是一个不错的复习资料,不过很开心今晚的迎新晚会很棒棒~~~~~~,不早了再不睡要猝死啦。。。。。

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 319 关注
  • 京东

    京东是中国最大的自营式电商企业,2015 年第一季度在中国自营式 B2C 电商市场的占有率为 56.3%。2014 年 5 月,京东在美国纳斯达克证券交易所正式挂牌上市(股票代码:JD),是中国第一个成功赴美上市的大型综合型电商平台,与腾讯、百度等中国互联网巨头共同跻身全球前十大互联网公司排行榜。

    14 引用 • 102 回帖 • 405 关注
  • 互联网

    互联网(Internet),又称网际网络,或音译因特网、英特网。互联网始于 1969 年美国的阿帕网,是网络与网络之间所串连成的庞大网络,这些网络以一组通用的协议相连,形成逻辑上的单一巨大国际网络。

    96 引用 • 330 回帖
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    131 引用 • 1114 回帖 • 151 关注
  • Shell

    Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。

    122 引用 • 73 回帖
  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    77 引用 • 1741 回帖
  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    18709 引用 • 69853 回帖 • 1 关注
  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    313 引用 • 1667 回帖 • 1 关注
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    138 引用 • 268 回帖 • 194 关注
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 443 关注
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 697 关注
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖
  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    180 引用 • 400 回帖
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    16 引用 • 53 回帖 • 123 关注
  • OnlyOffice
    4 引用 • 23 关注
  • wolai

    我来 wolai:不仅仅是未来的云端笔记!

    1 引用 • 11 回帖 • 2 关注
  • 阿里云

    阿里云是阿里巴巴集团旗下公司,是全球领先的云计算及人工智能科技公司。提供云服务器、云数据库、云安全等云计算服务,以及大数据、人工智能服务、精准定制基于场景的行业解决方案。

    89 引用 • 345 回帖
  • SpaceVim

    SpaceVim 是一个社区驱动的模块化 vim/neovim 配置集合,以模块的方式组织管理插件以
    及相关配置,为不同的语言开发量身定制了相关的开发模块,该模块提供代码自动补全,
    语法检查、格式化、调试、REPL 等特性。用户仅需载入相关语言的模块即可得到一个开箱
    即用的 Vim-IDE。

    3 引用 • 31 回帖 • 71 关注
  • 持续集成

    持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

    14 引用 • 7 回帖
  • 招聘

    哪里都缺人,哪里都不缺人。

    189 引用 • 1056 回帖
  • Logseq

    Logseq 是一个隐私优先、开源的知识库工具。

    Logseq is a joyful, open-source outliner that works on top of local plain-text Markdown and Org-mode files. Use it to write, organize and share your thoughts, keep your to-do list, and build your own digital garden.

    4 引用 • 55 回帖 • 10 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    6554 引用 • 29428 回帖 • 246 关注
  • Ruby

    Ruby 是一种开源的面向对象程序设计的服务器端脚本语言,在 20 世纪 90 年代中期由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)设计并开发。在 Ruby 社区,松本也被称为马茨(Matz)。

    7 引用 • 31 回帖 • 175 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3168 引用 • 8207 回帖
  • 支付宝

    支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。

    29 引用 • 347 回帖
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖 • 2 关注
  • Typecho

    Typecho 是一款博客程序,它在 GPLv2 许可证下发行,基于 PHP 构建,可以运行在各种平台上,支持多种数据库(MySQL、PostgreSQL、SQLite)。

    12 引用 • 60 回帖 • 465 关注