red-black-tree
目录
红黑树的规则
红黑树的效率
红黑树的插入规则
调整
情况一:u存在且为red
情况二:u不存在 或者 u存在但为black
情况1:使用右单旋+变色处理
情况2:使用左单旋+变色处理
情况3:使用左右双选+变色处理
情况4:使用右左双旋+变色处理
代码:
红黑树的规则
-
每个节点要么是红色,要么是黑色。
-
根节点必须是黑色的。
-
所有的叶子节点都是黑色的。在红黑树的定义中,通常将 nullptr 指针视为黑色的叶子节点 。这意味着实际存储数据的节点都有两个黑色的
NIL
孩子。 -
红色节点的两个子节点都必须是黑色的。这条规则也意味着不能有两个连续的红色节点。
-
黑高规则 (Black-Height): 从任意一个节点到其所有后代叶子节点 (
NIL
) 的简单路径上,经过的黑色节点的数量必须相同。这个数量被称为该节点的黑高。这个规则是红黑树保持平衡的关键。它确保没有一条路径会比其他路径长出两倍以上(因为路径上的黑色节点数相同,而红色节点不能连续,所以最长的路径最多是最短路径的两倍长 - 最短路径全黑,最长路径红黑交替)
红黑树的效率
由于规则5的限制我们知道红黑树的最短的路径是全黑的,如果这个树n个节点,那么他的最短路径最长不能超过就是log(n),那么他的最长路径最长就不能超过2*log(n)。所以效率是log(n)。
红黑树的插入规则
1.插入一个值按照二叉搜索树的规则进行插入,插入后我们需要判断是否符合红黑树的规则。
2. 如果是空树插入,那么新增的节点就是黑色的。如果是非空树插入,那么插入的节点就必须是红色的,因为非空树的插入是黑色的话就破坏了黑规则,而黑稿规则是很难维护的。
3.非空树的插入,如果他的父亲节点是黑色的,那么没有问题;如果他的父亲是红色的那么破坏了规则4,需要进行相应的变色调整和左旋右旋调整。
调整
核心思想:插入的newnode一定是红色的,一定不能时黑色的,因为黑高是很难维护的。既然插入的都是红色的那么就肯定需要调整,调整是从newnode开始向上调整。
出现需要调整时的情况一定是:newnoded=red,p=red,g=black(我所使用的newnode不全是代表新增节点,理解为一个特殊位置的节点就好,p为父亲节点,g给父亲节点的父亲节点,u为父亲节点的兄弟节点)
情况一:u存在且为red
将g变为red,p和u变成black。但是还没有结束,要将g当作新的c继续向上更新。但是如果g是根了,那么要将g再变回黑色。(图中c的位置就是newnode的位置)
情况二:u不存在 或者 u存在但为black
如果u不存在那么newnode是新增节点,如果u存在且为黑那么newnode不是新增的节点是由原来的黑色变成的红色。(原因:若u不存在且newnode是由原来的黑色变成的红色,那么原来经过newnode节点的路径的黑高就一定大于经过p的黑高,不满足黑高条件;若u存在且为黑且newnode是新增的红色叶子节点那么就经过newnode的路径的黑高就一定小于经过u的黑高,不满足黑高条件。)
下面分四种情况来处理,情况的分类跟AVL树一致,可以参考博主的这篇文章:AVL树中的旋转-CSDN博客
情况1:使用右单旋+变色处理
情况2:使用左单旋+变色处理
跟情况1类似,略。
情况3:使用左右双选+变色处理
情况4:使用右左双旋+变色处理
跟情况3类似,略。
代码
red_black_tree.cpp · VEwater/cpp - 码云 - 开源中国