红黑树的原理分析和算法设计(2)

明显违背了性质5!难道依葫芦画瓢,把11和19都改成黑色?这样从树根出发的左边路径黑高度还是2,而右边两条路径的黑高度将变成了3,老办法失效了!

红黑树的原理分析和算法设计

图-10

其实不然,改了新增节点的父亲和叔叔的颜色以后,右边路径黑高度全加一,但我们只要把它的爷爷改成红色不就又减去了多出来的黑高度吗?

红黑树的原理分析和算法设计

图-11

如果你认真看到这里,我想你的潜意识一定告诉你---这里存在某种规律等着我们去发现。

让我们再仔细审视一下图-5

红黑树的原理分析和算法设计

在生成树的过程中,我们已经两次遇到类似情况了,归纳一下,这个场景就是:新节点的父亲是红色,叔叔也是红色。

至于别的节点,我们大可不必关心,因为很显然,这个场景是原子的。

我们的处理办法是把7和15渲染成黑色,就像图-7那样,可是因为这是一个普遍适用的场景,所以要做一个扩展:假设在这个原子树的每个节点上还有别的分支。那么图-7就不能保证所有路径的黑高度相等了,即使把9改成红色也无济于事,因为9也许还有父节点,所以也许它的父节点又是红色,这就再次违反了性质5。我最喜欢的作家之一--柯南.道尔,曾说过:“历史就像车轮的辐条,每一根都终将再次转回来。”眼前的场景正是如此---我们设计的原子场景再次出现。

一个清晰的递归算法呈现在我们面前:

1. 新增节点渲染成红色;

2. 如果它的父亲是红色,则违反了性质5;

3. 如果它的叔叔也是红色,则通过同时修改其父亲和叔叔的颜色为黑色来恢复性质5;

4. 如果它的爷爷不是根节点,则有可能在另外的路径上再次违反性质5,于是我们把它的爷爷改成红色;

5. 可是如果他的太爷爷也是红色呢?很自然地,我们重新回到步骤2;

6. 不断循环,直到第二步满足就可以结束。

最后留给感兴趣的同学两个问题:

1. 如果新增节点的父亲是红色,但它的叔叔是黑色,该怎么办?(提示:使用旋转)

2. 有人说,下面这种场景,我设计的算法就失效了,真的吗?(粉色的6是新插入的节点)

红黑树的原理分析和算法设计

Linux内核之于红黑树and AVL树 

AVL树 VS 红黑树 

红黑树插入操作的C++实现 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/77451196aa958c668f94a19d08c436d6.html