1.介绍

在本文中,我们将了解什么是红黑树,以及为什么它们是如此流行的数据结构。

我们将从二叉搜索树和2-3树开始。从这里,我们将看到红黑树是如何被视为平衡的2-3树的不同表现形式。

本文的目的是以简单的方式解释红黑树,因此我们不会深入研究代码示例或详细示例,以获取所有可能的插入和删除情况。

2.二进制搜索树

二进制搜索树(BST)是一个树,每个节点具有0,1或2个子节点。没有子节点的节点被称为叶子。此外,节点的左子节点的值必须小于节点的值,并且右侧子的值必须大于节点的值。

让我们从一个简单的例子开始:

我们有元素4 8 12 16 18 24 32.我们可以从元素开始树16作为根(a),然后插入824(b),最终插入元素4,12,18,32(C)。请注意左子子始终小于其父母,合适的孩子总是大于父母。我们可以很容易地看到树的高度是o (log n), 和n表示元素的个数

如果我们想搜索树中的一个元素,我们可以从根开始。如果我们要找的元素等于根,那就做完了。如果它更小,我们继续向左搜索,如果它更大,我们继续向右搜索。继续执行,直到找到该元素,或者直到到达一个叶节点(黄色部分)。很明显,我们搜索的时间复杂度是O (log n)

然而,树的结构高度依赖于元素插入的顺序.如果按顺序插入元素24 32 16 18 12 8 4,生成的树不再平衡(d)。如果我们以排序顺序插入元素,则结果是每个节点(e)只有一个子的树。这实际上是一个列表,而不是树。这意味着我们要查找和一个元素的最坏情况复杂性O (n)

3.平衡2 - 3树

3.1。2-3树的定义

我们现在将看看2-3棵树,这有助于我们保持平衡的树,无论我们将元素插入到树上。2-3树是具有两种类型节点的树。一个2节点有一个值和两个子节点(再次,左子子有一个较小的值,并且右侧的子节点具有更大的值),并且3节点具有两个值和三个子节点。

3-node的左子节点小于父节点的左值。中间的子节点的值位于两个父节点的值之间,右边的子节点的值大于父节点的右节点的值。

3.2。插入元素到2-3树

让我们看看如何插入元素32,24,18,16,12,8,4进入2-3棵树,同时保持树平衡。

我们从32,这为我们提供了一棵树,只有根节点(a)。然后我们插入24在根b处有3个结点。

接下来,我们插入下一个元素,18,作为根的左孩子(如18小于24).这将导致一棵不平衡的树。我们可以通过移动24在3节点中并使其成为根节点。

结果将是一个只有2个节点(b)的平衡树。

我们要插入的下一个元素是16.同样,我们以一个不平衡的树(a)结束16一个级别,形成一个3节点18(b)。

接下来,我们插入12作为我们刚刚创建的3结点(a)的左子结点。为了平衡树,我们首先移动12上一级形成临时的4节点(b)。

我们现在可以通过移动中间元素来拆分4节点,16到根结点,这就得到了一个平衡的树(c)

的插入8现在很简单了——我们首先创建12(a),然后将元素向上移动一层,形成一个3节点12(b)。

要插入的最后一个元素,4,导致一个稍微复杂的插入。首先,我们创建一个左元素(a)并将其向上移动一层,从而得到一个临时的4节点(b)。现在我们可以移动中间元素,8在根节点(c)上获得一个4节点。

在最后一步,我们通过提取对4个节点进行分割16作为根节点(d)

3.3。插入的复杂性

上面的例子表明,我们可以以这样一种方式插入元素,以维护一个平衡的树。然而,每次插入所执行的操作都非常复杂,难以用代码表示。原因是我们需要三种不同类型的节点(2节点、3节点和4节点)。

此外,为了将元素向上移动并合并为3个节点或将3个节点拆分为2个节点,我们需要区分几种不同的情况。

在下一节中,我们将看到红黑树木如何帮助我们降低这种复杂性。

4.红黑树

4.1。2-3棵树对应

红黑树本质上是2-3树的另一种表现形式。让我们直接来看一个例子:

(a)中的树显示了一个2-3树,正如我们在前一节中看到的那样。我们用红色标记了3个节点,这就直接指向了红黑树。我们把每个3个节点分成两个2个节点,并用红色标记它们之间的联系。

这也直接引出了红黑树的两个主要属性:

  • 一个红色链接后面总是跟着两个黑色链接(因为我们拆分的3个节点后面跟着三个黑色链接)。
  • 从根节点到叶节点的路径总是包含相同数量的黑色链接(这直接源于我们的2-3树是平衡的)。

在此基础上,我们添加了以下两个条件:

  • 只能链接到左子子(较小的子节点)可以是红色的。此条件简化了更长时间的实现。
  • 所有叶节点都有空链接(nil)。

4.2。为什么这种表示方法?

简而言之,它简化了树和操作的实现。我们可以使用与二进制树相同的操作(例如,查找值与“正常”二叉树中的方式完全相同的操作。

4.3。插入

要向红黑树中插入新值,需要添加一个新节点作为新的叶节点。这当然会导致一棵树不平衡。为了平衡树,我们首先将到新节点的链接着色为红色。

然后我们只需要三种操作来重新平衡我们的树。让我们来看看这些操作。

第一个操作是左旋转。在这里,我们通过移动两个连杆将子树(a)转换为子树(b)。

第二操作是右旋转,其与左旋转完全相反。

第三个操作是一种颜色的翻转。我们可以将两个红色链接更改为两个黑色链接,并将父链路更改为红色链接。

这里重要的是,所有三个操作都是本地操作,这意味着它们没有对整个树的影响。

在本文中,我们不会看一下插入的完整示例。下划线的主要点是这三个简单的操作允许我们轻松重新平衡树。

4.4。插入示例

让我们来看一个将元素插入红黑树的示例。我们想要插入的元素是37(橙色背景)和根部显示有蓝色背景。

首先,我们从根开始,然后走下树,直到我们找到插入元素的叶子节点。在我们的案件中,37将是树中最大的元素,所以它在很右边。到新节点的链接是红色的,我们得到一棵树,如(a)所示。

因为父元素36现在有两个红色的链接,第二步是flip-colors操作,导致我们进入树,如(b)所示。

现在是具有值的节点28有两个红色的环节,第三个环节是flip-colors再次操作,导致树如(c)所示。

当我们想让所有的红色链接向左倾斜时,我们做a左转,它导致(d)的树,有28作为根。我们很容易看到树是平衡的。

4.5。删除

在删除一个节点之后,我们可以使用相同的三个操作来重新平衡树。在本文中,我们将不讨论完整的实现,而只是概述其思想并给出几个删除元素的示例。

对于所有的例子,我们将从以下(有效的)红黑树开始:

微小案例是删除具有红色链路的叶节点。让我们来看看两个可能的情况,删除236

删除2

这是最简单的案例。元素2是一个红色链接的左节点,因此我们可以删除它,直接得到一个有效的红黑树,而不需要重新平衡。

删除36

如果我们想要删除36,我们再次删除节点,如36是红色链接的右边节点,我们需要更改链接吗2836要点32.同样,我们得到了一个有效的红黑树。

删除8

如果要删除一个非叶节点,可以先将其设置为叶节点。要做到这一点,我们需要找到左子树的最大元素或者右子树的最小元素。这个交换不会改变红黑树属性。因为我们可以将每个节点移动到树的底部,因此理解如何删除叶节点就足够了。

让我们看看如何删除元素8.左子树的最大值是4(a)我们交换节点84并删除它。随着8有一个红色的链接,我们具有与我们删除的相同的琐碎案例4(b)。

同样,最后一棵树是有效的红黑树(c)。

删除24

如果我们想要删除一个叶节点它不是红色链接的左节点或右节点,事情就会变得有点复杂。

作为一个例子,让我们看看删除24(一种)。首先,我们翻转24,1818是左子树的最大元素)。

现在我们需要移除24在树(b)中,没有红色链接。

的树24删除(c)不是有效的红黑树18只有一个孩子,所以树不平衡。

我们可以通过旋转(d)来平衡树。

5.复杂性

红黑树为插入、搜索和删除提供了对数平均和最坏情况下的时间复杂度。

再平衡的平均时间复杂度为O (1)最坏情况的复杂性O (log n)

此外,红黑树在批量和并行操作方面具有有趣的特性。例如,可以从具有时间复杂度的排序列表中构建红黑树日志(O (log n))和(n /日志(o (log n)))处理器。

6.红黑树的应用

红黑树的实际应用包括TreeSettreemp.,Hashmap在Java集合库中。此外,Linux内核中的完全公平调度器也使用这种数据结构。Linux也使用红黑树mmapMunmap.文件/内存映射的操作。

此外,红黑树用于几何范围搜索、k-means聚类和文本挖掘。

从上面的例子中,我们可以看到红黑树主要是在幕后使用的,作为开发人员,我们并不经常接触到它们,即使我们每天都在使用它们。

7.结论

在本文中,我们了解了红黑树是什么以及它们基本上是如何不同的2-3棵树的表达。

我们还看到了一个表,它总结了树上操作的复杂性,最后,我们简要地总结了红黑树的一些实际应用。

然而,当涉及到为特定用例选择数据结构时,有许多因素需要考虑。如果我们需要良好的插入和搜索的平均代价,以及保证这两个操作的对数最坏情况代价,红黑树是特别有用的。

此外,如果我们频繁更新树,红黑树是一个很好的选择,因为再平衡的成本比其他平衡树(比如AVL或b -树)要低。

2评论
最老的
最新
内联反馈
查看所有评论
Ashutosh Thakur
Ashutosh Thakur
10个月前

如3.3节中所述,对于2-3棵树,“我们需要有三种不同类型的节点(2节点,3个节点和4个节点)。”。但是,2-3棵树 - 2个节点和3节点中不仅有2种类型的节点?我们也可以创建一个临时4节点吗?

Loredana Crusoveanu
Loredana Crusoveanu
9个月前

嗨Ashutosh,
是的,可以在平衡树期间创建一个4节点。虽然它是暂时的,而不是持续存储在树中。

查看3.2节中的示例。更多细节。

评论在本文上关闭!