红黑树Red/Black Tree

红黑树Red/Black Tree

建立二进制搜索树,我们得到红/黑树,旨在解决BST可能变得不平衡的问题。BST二叉搜索树】,是对于任意的node x,如果node y是node x的左边的节点, 那么Key(y) <= Key(x); 对于任意的node x, 如果node y 是node x的右边的节点, 那么key(y)>=key(x).

红色/黑色树的简短版本是它是一个BST,其中包含一系列规则,可帮助我们保持良好的性能。

回想一下BST,当我们进行插入和删除时,在某些时候,我们需要重新平衡树以确保我们保持用于搜索的O(log n)性能。 什么时候进行重新平衡?

红/黑树通过向每个节点添加一位信息来扩展BST; 对于那些跟踪,我们现在节点拥有的数据,键,和标志。

该标志或者是红/黑,有7规则BST应该遵循(有5种与颜色相关的官方规则,下面的前5项,但BST本身还有两种规则):

1.每个节点是红色或黑色。

2.根节点是黑色的。

所有的叶子都是黑色的。 这些叶子可以是节点之外的空点,也可以是显式节点。

4.红色节点只能有黑人孩子。

从节点到叶子的任何路径都包含相同数量的黑色节点。

6.添加的新节点总是红色。

7.如果路径的深度是短路径的两倍,我们需要进行旋转。

因此,使用这些规则,插入和删除会变得更复杂,因为您需要检查这些规则,如果规则不起作用,您就开始纠正问题。 对此有用的是,由于规则,您可以非常有效地纠正问题。

那么让我们来看一个非常简单的BST:

红黑树Red/Black Tree

接下来,按照我们的规则,让它成为红/黑树。 我还将在此图像中添加离开节点以帮助解释它,但是会将它们从剩余的节点中取出。

红黑树Red/Black Tree

注意:

·*从根节点开始,无论路径如何,都需要经过一个黑色节点才能到达叶节点。

·*所有红色节点只有黑色子节点。

·*黑色节点可以有黑人孩子。

现在我们将添加一个值为11的节点。它被添加到正确的位置并作为红色节点添加。

红黑树Red/Black Tree

然而,9是红色并且有一个红色的孩子,所以我们需要触发它重绘为黑色。 这导致了一个新问题,即从根节点到叶子,你可以通过向左走过一个黑色节点,或者通过向右走过两个黑色节点,所以我们需要将9的父节点(即7)绘制成红色。 最后,由于7现在为红色,因此必须将6重新绘制为黑色。 最后,我们有一个正确的红/黑树。

红黑树Red/Black Tree

最后,让我们添加10,即11以下。我们立即注意到从5到10的叶子的长度是4步,而最短的路径(左侧)是2.我们知道我们需要做一个旋转。

红黑树Red/Black Tree

旋转是容易的,我们采取较长边的孩子(即7)并使其成为根并使原始根(即5)成为它的孩子。 由于7已经有两个孩子(5和9),它的原始孩子6在5下移动。接下来,我们只是触发一个重绘,从7需要为黑色的事实开始,你最终得到以下结果:

红黑树Red/Black Tree

这可能看起来真的很昂贵,但它并不太糟糕,因为你只是更改指针而且只有少数插入的性能变为O(log n)。