死磕红黑树——如何理解记忆红黑树性质?

写在前面

学习和掌握红黑树,不是一朝一夕之功。我也看到很多优秀的红黑树讲解之作,例如:

  1. 30张图带你彻底理解红黑树

  2. 面试常问:什么是红黑树?

不过篇幅太长了,特别难记住重要的点,所以自己又整理了一下。

记性质

  • 性质1:“红黑树”顾名思义,由红色结点和黑色结点组成。每个结点要么是红色结点,要么是黑色结点。

接下来的几条性质倒不是不好记忆,而是常常会“丢三落四”,所以我得先说明一下,这个“红黑树”是科学家研究出来的,性质之间相辅相成,缺一不可。当然也不会存在多余的条件。

假设根结点是红色,合理吗?

假设根结点是红色的

好家伙,我对照了一下 5 条性质,除了性质 2 不满足,其他都满足。

当我们向红色根结点插入一个黑色结点时,如图所示:

此时,根结点 P 到右叶子结点 NIL 路径中的黑色结点数量为 1。根结点 P 到 左子树叶子结点 NIL 的路径中的黑色结点数量为 2。

违反性质5,需要进行调整,此时“变色” 即可解决:

没想到因为根结点设定为黑色,第一次插入就需要对红黑树进行调整,这可不是一个好兆头。

你要知道,红黑树的诞生,就是为了解决“二叉平衡树”每次插入或者删除元素都要对树进行调整,造成性能低下的问题。

既然插入黑色结点不行,那我们向红色根结点插入一个红色子结点 试试呢?

红色根结点的左子结点是红色,但是右子结点是黑色。这不满足性质4————每个红色结点的每个子结点都是黑色的。

所以,性质2:根结点是黑色的。

假设叶子结点都是红色,行吗?

假设每个叶子结点都是红色,行不行呢?

根据性质4,每个红色结点的每个子结点都是黑色的。那么叶子结点 NIL 的父节点不能是红色。

所以说,假如每个叶子结点都是红色:

  1. 如果为根结点插入一个红色子结点,不满足性质4

  2. 如果为根结点插入一个黑色子结点,不满足性质5

巧记性质2和性质3

性质2:根结点是黑色的;性质3:每个叶子结点 NIL 都是黑色的。

抽象一下:黑脑袋,黑鞋子,根结点就像一个黑色的脑袋,叶子结点 NIL 就像一对黑皮鞋。

性质4防止“链化”

性质4是这样描述的,每个红色结点的每个子结点一定都是黑色的。

假设允许红色结点的子结点允许是红色的?

删除性质4,这就意味着可能存在“红黑树” 链化 的风险。

一旦形成了这种“链表”结构,查询的时间复杂度由 O(\(\log_2{N}\)) 直接变为 O(N)

红黑树也失去它该有的平衡性。

所以说,为了防止红黑树“链表化”,每个红色结点的每个子结点一定都是黑色的!

一红一黑的子结点组合违反性质5

  • 根结点到 K 的叶子结点的路径上的黑色结点数量为 2

  • 根结点到 L 的叶子结点的路径上的黑色结点数量为 3

性质5黑色等高

假设任意结点到叶子结点的路径可以包含不同数量的黑结点?

如果说性质4是为了防止红色子结点过多,导致树结构链表化

那么,性质5则是为了防止黑和红色相间,导致树结构链表化

树的高度:指的是从 该结点叶子结点 的最长路径。

定义参考:树的高度与深度

记忆口诀:

红黑树,黑脑袋,穿黑鞋。
红子双黑,黑色等高。

  • 性质1:红黑树:每个结点要么是红色,要么是黑色。

  • 性质2:黑脑袋:根结点是黑色的

  • 性质3:穿黑鞋/黑足:每个叶子结点 NIL 是黑色的。

  • 性质4;红子双黑:红色结点的每个子结点一定是黑的。(假如一个是子结点,另一个是叶子结点 NIL,也是双黑)

  • 性质5:黑色等高:任意一个结点到叶子结点的路径包含相同数量的黑色结点。(如果说黑色结点高度算1,红色结点高度算0,那么任意一个结点的高度是相等的。)

如果觉得本文对你有所启发,不妨点个赞~

posted @ 2021-03-02 23:41  极客子羽  阅读(524)  评论(0编辑  收藏  举报