写在前面
学习和掌握红黑树,不是一朝一夕之功。我也看到很多优秀的红黑树讲解之作,例如:
不过篇幅太长了,特别难记住重要的点,所以自己又整理了一下。
记性质
- 性质1:“红黑树”顾名思义,由红色结点和黑色结点组成。每个结点要么是红色结点,要么是黑色结点。
接下来的几条性质倒不是不好记忆,而是常常会“丢三落四”,所以我得先说明一下,这个“红黑树”是科学家研究出来的,性质之间相辅相成,缺一不可。当然也不会存在多余的条件。
假设根结点是红色,合理吗?
假设根结点是红色的
好家伙,我对照了一下 5 条性质,除了性质 2 不满足,其他都满足。
当我们向红色根结点插入一个黑色结点时,如图所示:
此时,根结点 P 到右叶子结点 NIL 路径中的黑色结点数量为 1。根结点 P 到 左子树叶子结点 NIL 的路径中的黑色结点数量为 2。
违反性质5,需要进行调整,此时“变色” 即可解决:
没想到因为根结点设定为黑色,第一次插入就需要对红黑树进行调整,这可不是一个好兆头。
你要知道,红黑树的诞生,就是为了解决“二叉平衡树”每次插入或者删除元素都要对树进行调整,造成性能低下的问题。
既然插入黑色结点不行,那我们向红色根结点插入一个红色子结点 试试呢?
红色根结点的左子结点是红色,但是右子结点是黑色。这不满足性质4————每个红色结点的每个子结点都是黑色的。
所以,性质2:根结点是黑色的。
假设叶子结点都是红色,行吗?
假设每个叶子结点都是红色,行不行呢?
根据性质4,每个红色结点的每个子结点都是黑色的。那么叶子结点 NIL 的父节点不能是红色。
所以说,假如每个叶子结点都是红色:
-
如果为根结点插入一个红色子结点,不满足性质4
-
如果为根结点插入一个黑色子结点,不满足性质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,那么任意一个结点的高度是相等的。)
如果觉得本文对你有所启发,不妨点个赞~