Red Black Tree 的一点感想

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

红黑树的基本性质

  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 为中心左旋。

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

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • PostgreSQL

    PostgreSQL 是一款功能强大的企业级数据库系统,在 BSD 开源许可证下发布。

    21 引用 • 22 回帖
  • SEO

    发布对别人有帮助的原创内容是最好的 SEO 方式。

    35 引用 • 200 回帖 • 24 关注
  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    198 引用 • 120 回帖
  • 微软

    微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。

    8 引用 • 44 回帖
  • Chrome

    Chrome 又称 Google 浏览器,是一个由谷歌公司开发的网页浏览器。该浏览器是基于其他开源软件所编写,包括 WebKit,目标是提升稳定性、速度和安全性,并创造出简单且有效率的使用者界面。

    60 引用 • 287 回帖
  • uTools

    uTools 是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。

    5 引用 • 13 回帖
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 9 关注
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    53 引用 • 85 回帖
  • Q&A

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

    6510 引用 • 29259 回帖 • 247 关注
  • RYMCU

    RYMCU 致力于打造一个即严谨又活泼、专业又不失有趣,为数百万人服务的开源嵌入式知识学习交流平台。

    4 引用 • 6 回帖 • 38 关注
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 455 关注
  • 酷鸟浏览器

    安全 · 稳定 · 快速
    为跨境从业人员提供专业的跨境浏览器

    3 引用 • 59 回帖 • 22 关注
  • Ngui

    Ngui 是一个 GUI 的排版显示引擎和跨平台的 GUI 应用程序开发框架,基于
    Node.js / OpenGL。目标是在此基础上开发 GUI 应用程序可拥有开发 WEB 应用般简单与速度同时兼顾 Native 应用程序的性能与体验。

    7 引用 • 9 回帖 • 345 关注
  • 支付宝

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

    29 引用 • 347 回帖 • 1 关注
  • JSON

    JSON (JavaScript Object Notation)是一种轻量级的数据交换格式。易于人类阅读和编写。同时也易于机器解析和生成。

    51 引用 • 190 回帖
  • SendCloud

    SendCloud 由搜狐武汉研发中心孵化的项目,是致力于为开发者提供高质量的触发邮件服务的云端邮件发送平台,为开发者提供便利的 API 接口来调用服务,让邮件准确迅速到达用户收件箱并获得强大的追踪数据。

    2 引用 • 8 回帖 • 438 关注
  • 游戏

    沉迷游戏伤身,强撸灰飞烟灭。

    169 引用 • 799 回帖
  • 倾城之链
    23 引用 • 66 回帖 • 96 关注
  • webpack

    webpack 是一个用于前端开发的模块加载器和打包工具,它能把各种资源,例如 JS、CSS(less/sass)、图片等都作为模块来使用和处理。

    41 引用 • 130 回帖 • 298 关注
  • Firefox

    Mozilla Firefox 中文俗称“火狐”(正式缩写为 Fx 或 fx,非正式缩写为 FF),是一个开源的网页浏览器,使用 Gecko 排版引擎,支持多种操作系统,如 Windows、OSX 及 Linux 等。

    7 引用 • 30 回帖 • 454 关注
  • 自由行
    1 关注
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    129 引用 • 793 回帖
  • GitBook

    GitBook 使您的团队可以轻松编写和维护高质量的文档。 分享知识,提高团队的工作效率,让用户满意。

    3 引用 • 8 回帖 • 1 关注
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    51 引用 • 37 回帖 • 1 关注
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 458 关注
  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    284 引用 • 247 回帖 • 182 关注