我在Coursera算法课程中碰到了这个问题,并意识到我不知道该怎么做。但是,我仍然有一些想法。我想到的第一件事是使用优化的位集(如Java的BitSet
)来获取映射节点的key -> color
。因此,我们所需要的是为整个树分配一个位集并将其用作颜色信息源。如果树中没有重复元素 - 它应该可以工作。
很高兴看到其他人关于这项任务的想法。
答案 0 :(得分:15)
只需修改BST树。对于黑色节点,请不要。而对于红色节点,交换其左孩子和右孩子。在这种情况下,根据节点的右子是否大于其左子节点,可以将节点称为红色或黑色。
答案 1 :(得分:10)
使用节点中某个指针的最低有效位来存储颜色信息。节点指针应该在大多数平台上包含偶数地址。详情请见here。
答案 2 :(得分:1)
一种选择是使用需要较少簿记的树,例如一个splay tree。但是,splay树尤其不适合迭代(它们在随机查找方面要好得多),因此它们可能不适合您正在使用的域。
您还可以根据节点位置为整个红黑树使用一个BitSet,例如:根是第0位,根的左分支是第1位,右分支是第2位,左分支的左分支是第3位,等等;这样,如果有重复的元素就没关系。遍历树时记下你所处的位置。
在空间方面使用一个bitset而不是为每个节点分配布尔值更有效率;每个布尔值将占用至少一个字节,并且可能占用一个字取决于对齐,而位集将仅占用每个节点一位(加上2x位以考虑最大不平衡树,其中最短分支是一半的长度)最长的分支)。
答案 3 :(得分:1)
我们可以使用2条规则:
由于根节点始终为黑色,因此红色节点将始终具有父节点。
RB BST始终具有left_child<的顺序父母< right_child
然后我们会这样做:
保持黑色节点不变。
对于红色节点,我们将其称为R,我们将其视为其父节点的左子节点,称为P.
将红色节点值从R
更改为R'
,而R' = P + P - R
现在是R' > P
,但由于它是左子树,我们会发现订单不匹配。
如果我们发现订单不匹配,那么我们就知道它是一个红色节点。
并且很容易回到原来的R = P + P - R'
答案 4 :(得分:0)
我们可以将红色节点定义为错误位置的孩子,而不是在子节点上使用布尔属性。
如果我们这样做,所有叶子节点都保证是黑色的,我们应该在插入一个新节点时将父节点与他的兄弟交换(让他变红)。