我只是RB Tree的新手。我刚刚在旋转后对树进行重新着色时被绞死了。
让我们考虑以下情况: -
插入顺序:34,32,56,30,31
34 (B)
32 (B) 56 (B)
30 (R)
31 (R)
在上述情况下,插入31时会发生颜色冲突,发生在30的父级,并且高度不稳定也会发生。
因此,对于树32,30,31,我们正在进行左右旋转,这与在AVL树中进行相同。
直到这个轮换,对我来说似乎很好。
但轮换后,树会变得像,
34 (B)
31 (R) 56 (B)
30 (R) 32 (B)
所以在这里,红色 - 红色冲突发生在31和30.而且左子树的黑度也受到影响。
我可以知道,我必须应用哪些公式/条件的步骤来纠正这种着色和黑度问题。
提前致谢。
答案 0 :(得分:5)
我已经教了几年算法和数据结构了,我对红/黑树的诚实建议如下:
知道旋转规则和颜色翻转的来源,但不要记住它们。
实际上需要手动追踪红/黑树旋转或者必须对它们进行编码是非常罕见的。在这些情况下,我建议做大多数人所做的事情,即打开CLRS的副本并复制他们所包含的伪代码。
在我看来,更有价值的是要了解这些规则从何而来,以及如何设法推导出这些规则。虽然这并不经常教,但红/黑树的原始规则是通过使用红/黑树和称为2-3-4 tree的相关数据结构之间的连接得出的。 2-3-4树比红/黑树更容易理解,一旦你看到它们之间的连接,你实际上可以重新启动所有的旋转和颜色翻转,你需要修复一个红色/黑色的树飞行,没有太多困难。我把a set of lecture slides outlining the connection between these data structures and how to use it放在一起,如果你有兴趣,这可能是理解红/黑树如何工作的好方法。
答案 1 :(得分:2)
在 RED BLACK 树中插入键时要记住的不变量是:
1 。根始终是黑色。
2 。两个红色节点都不能连续。
3 。从每个根到空路径访问的黑色节点数必须相等。
记住以上几点,让我们进行插入:
插入(34)强>
34(B)
插入(32)强>
34(B)
/
32(R)
插入(56)强>
34(B)
/ \
32(R) 56(R)
插入(30)强>
34(B)
/ \
32(R) 56(R)
/
30(R)
违反不变量2 。
为了解决这个问题,我们将节点32和56重新着色为黑色并使其父红色。
但是通过让父母红色违反不变1 ,我们将他们的父母保持黑色,我们有以下树。
34(B)
/ \
32(B) 56(B)
/
30(R)
上面的树满足所有不变量,我们继续插入。
插入(31)强>
34(B)
/ \
32(B) 56(B)
/
30(R)
\
31(R)
违反不变量2 。
要处理此违规行为,我们会对node 32 and node 31
执行左旋转(它会影响这2个节点的单次旋转)。
34(B)
/ \
32(B) 56(B)
/
31(R)
/
30(R)
现在我们在node 31 and node 32
34(B)
/ \
31(R) 56(B)
/ \
30(R) 32(B)
现在我们在node 31 and node 34
31(R)
/ \
30(R) 34(B)
/ \
32(B) 56(B)
现在,我们将node 31
和node 30
重新定为黑色,将node 32
和node 56
重新定为红色。我们得到以下树:
31(B)
/ \
30(B) 34(B)
/ \
32(R) 56(R)
我们的最终树满足RED BLACK树的所有属性并且也是平衡的。