红黑树原理详解

合集下载

c++ 红黑树 map原理

c++ 红黑树 map原理

c++ 红黑树 map原理
C++中的红黑树是一种自平衡的二叉查找树,它常用于实现关联
容器中的map数据结构。

红黑树通过对节点进行着色和旋转操作来
保持树的平衡,从而确保在最坏情况下的查找、插入和删除操作的
时间复杂度为O(log n)。

红黑树的基本原理包括以下几点:
1. 节点着色,每个节点都被标记为红色或黑色,这些颜色标记
用于确保树的平衡。

2. 根节点和叶子节点,根节点是黑色的,叶子节点(NIL节点)是黑色的。

3. 红色节点规则,红色节点的子节点必须是黑色的,即不能出
现两个相连的红色节点。

4. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色
节点。

这保证了树的黑色平衡。

在C++中,STL中的map数据结构通常使用红黑树来实现。

map 是一种关联容器,它提供了一种将键和值关联起来的方式。

当我们向map中插入新的键值对时,红黑树会自动进行调整以保持平衡。

查找、插入和删除操作都能在O(log n)的时间复杂度内完成,这使得map非常高效。

总之,红黑树是一种高效的自平衡二叉查找树,它通过节点着色和旋转操作来维持平衡。

在C++中,map数据结构通常使用红黑树来实现,从而提供了高效的插入、删除和查找操作。

这些原理和实现细节都是为了确保数据结构的高效性和稳定性。

数据结构中的平衡二叉树AVL树和红黑树的原理与实现

数据结构中的平衡二叉树AVL树和红黑树的原理与实现

数据结构中的平衡二叉树AVL树和红黑树的原理与实现在计算机科学中,数据结构是指一种组织和存储数据的方式,同时也是一种操作数据的方法。

其中,平衡二叉树是一种常用的数据结构,在平衡二叉树中,每个节点的左子树和右子树的高度最多相差1。

然而,平衡二叉树在插入和删除节点时可能会出现树结构不平衡的问题,这就引出了AVL树和红黑树的概念。

一、AVL树的原理与实现AVL树是由G. M. Adelson-Velsky和E. M. Landis于1962年提出的一种自平衡二叉查找树。

它通过在每个节点中添加一个平衡因子来维持树的平衡性。

平衡因子可以是-1、0或1,对应于左子树比右子树高、左右子树高度相等以及右子树比左子树高的情况。

在插入或删除节点时,AVL树会通过旋转操作来调整树的结构,以保持平衡因子的平衡。

旋转操作有四种情况:左旋、右旋、先左旋后右旋和先右旋后左旋。

通过这些旋转操作,AVL树能够保持树的平衡性,从而提高查找、插入和删除操作的效率。

AVL树的实现需要考虑节点的旋转、平衡因子的更新以及树的遍历等问题。

在节点的插入和删除操作中,需要对节点进行平衡处理,并更新相应的平衡因子。

在树的遍历中,可以使用中序遍历、前序遍历或后序遍历等方式来访问树的节点。

二、红黑树的原理与实现红黑树是由Rudolf Bayer在1972年提出的一种平衡二叉查找树。

它通过在每个节点中添加一个额外的属性表示节点的颜色(红色或黑色)来保持树的平衡性。

红黑树具有以下性质:1. 每个节点要么是红色,要么是黑色。

2. 根节点是黑色。

3. 每个叶子节点(NIL节点)是黑色。

4. 如果一个节点是红色,则它的两个子节点都是黑色。

5. 对于每个节点,从该节点到其子孙节点的所有路径上包含相同数目的黑色节点。

通过这些性质,红黑树可以保持树的黑色平衡,在插入和删除节点时通过颜色变换和旋转操作来维持树的平衡性。

与AVL树相比,红黑树的调整操作较为简单,适用于动态插入和删除节点的情况。

教你透彻了解红黑树概论

教你透彻了解红黑树概论

红黑树系列,六篇文章于今日已经完成:1、教你透彻了解红黑树2、红黑树算法的实现与剖析3、红黑树的c源码实现与剖析4、一步一图一代码,R-B Tree5、红黑树插入和删除结点的全程演示6、红黑树的c++完整实现源码------------------------------一、红黑树的介绍先来看下算法导论对R-B Tree的介绍:红黑树,一种二叉查找树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red 或Black。

通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。

前面说了,红黑树,是一种二叉查找树,既然是二叉查找树,那么它必满足二叉查找树的一般性质。

下面,在具体介绍红黑树之前,咱们先来了解下二叉查找树的一般性质:1.在一棵二叉查找树上,执行查找、插入、删除等操作,的时间复杂度为O(lgn)。

因为,一棵由n个结点,随机构造的二叉查找树的高度为lgn,所以顺理成章,一般操作的执行时间为O(lgn)。

//至于n个结点的二叉树高度为lgn的证明,可参考算法导论第12章二叉查找树第12.4节。

2.但若是一棵具有n个结点的线性链,则此些操作最坏情况运行时间为O(n)。

而红黑树,能保证在最坏情况下,基本的动态几何操作的时间均为O(lgn)。

ok,我们知道,红黑树上每个结点内含五个域,color,key,left,right,p。

如果相应的指针域没有,则设为NIL。

一般的,红黑树,满足以下性质,即只有满足以下全部性质的树,我们才称之为红黑树:1)每个结点要么是红的,要么是黑的。

2)根结点是黑的。

3)每个叶结点(叶结点即指树尾端NIL指针或NULL结点)是黑的。

4)如果一个结点是红的,那么它的俩个儿子都是黑的。

5)对于任一结点而言,其到叶结点树尾端NIL指针的每一条路径都包含相同数目的黑结点。

(注:上述第3、5点性质中所说的NULL结点,包括wikipedia.算法导论上所认为的叶子结点即为树尾端的NIL指针,或者说NULL结点。

TreeMap底层实现和原理-红黑树

TreeMap底层实现和原理-红黑树

TreeMap底层实现和原理-红⿊树
TreeMap实现了SotredMap接⼝,它是有序的集合。

⽽且是⼀个红⿊树结构,每个key-value都作为⼀个红⿊树的节点。

如果在调⽤TreeMap的构造函数时没有指定⽐较器,则根据key执⾏⾃然排序,如果指定了⽐较器则按照⽐较器来进⾏排序。

红⿊树是⼀个更⾼效的检索⼆叉树,有如下特点:
1. 每个节点只能是红⾊或者⿊⾊
2. 根节点永远是⿊⾊的
3. 所有的叶⼦的⼦节点都是空节点,并且都是⿊⾊的
4. 每个红⾊节点的两个⼦节点都是⿊⾊的(不会有两个连续的红⾊节点)
5. 从任⼀个节点到其⼦树中每个叶⼦节点的路径都包含相同数量的⿊⾊节点(叶⼦节点到根节点的⿊⾊节点数量每条路径都相同)
关于红⿊树的节点插⼊操作,⾸先是改变新节点,新节点的⽗节点,祖⽗节点,和新节点的颜⾊,能在当前分⽀通过节点的旋转改变的,则通过此种操作,来满⾜红⿊书的特点。

如果当前相关节点的旋转解决不了红⿊树的冲突,则通过将红⾊的节点移动到根节点解决,最后在将根节点设置为⿊⾊
对于红⿊⼆叉树⽽⾔它主要包括三⼤基本操作:左旋、右旋、着⾊。

红黑树的例子

红黑树的例子

红黑树的例子
红黑树是一种自平衡二叉搜索树,它具有以下特性:
1. 节点为红色或者黑色;
2. 根节点为黑色;
3. 叶子节点为黑色(叶子节点指的是NULL节点);
4. 如果一个节点为红色,那么它的子节点必须是黑色;
5. 从任何一个节点到它的每个叶子节点的所有路径都包含相同数目的
黑色节点。

下面是一棵红黑树的例子:
```
11B
/ \
7R 15B
/ \ / \
5B 9B 13R 20R
/ \
8R 10R
```
解释如下:
- 根节点是11,颜色为黑色。

- 左子树的根节点是7,颜色为红色。

它的左子树节点是5,颜色为黑色,右子树节点是9,颜色为黑色。

9的左子树为节点8,颜色为红色,右子树节点是10,颜色为红色。

- 右子树的根节点是15,颜色为黑色。

它的左子树节点是13,颜色为
红色,右子树节点是20,颜色为红色。

红黑树的特性可以保证在进行插入、删除等操作时,树的深度始
终不会超过2倍,所以其操作效率非常高。

c++中map的实现原理

c++中map的实现原理

c++中map的实现原理
C++中的map是通过红黑树(Red-Black Tree)实现的。

红黑树是一种自平衡二叉搜索树,它具有以下特性:
1. 每个节点都有一个颜色,要么是红色,要么是黑色。

2. 根节点是黑色的。

3. 叶节点(即空节点)是黑色的。

4. 如果一个节点是红色的,那么它的两个子节点都是黑色的。

5. 对于任意一个节点,从该节点到其子孙节点的所有路径上的黑色节点数量是相同的。

红黑树的特性保证了它的平衡性,使得查找、插入和删除操作的时间复杂度都是O(log n)。

在C++中,map是使用红黑树实现的。

红黑树通过节点的key 值来进行排序和查找。

每个节点包含一个key和一个value,通过key来进行查找和插入操作。

当进行插入操作时,先按照红黑树的插入规则将节点插入到正确的位置上,然后通过旋转和重新染色等操作来保持树的平衡性。

当进行查找操作时,按照红黑树的查找规则进行查找。

查找操作的时间复杂度为O(log n)。

总结来说,C++中的map通过红黑树实现,利用红黑树的平衡性和查找特性实现了高效的插入和查找操作。

红黑树算法原理与实现

红黑树算法原理与实现

红黑树算法原理与实现红黑树是一种自平衡二叉查找树,它能够保证查找、插入和删除操作最坏情况下的时间复杂度都为O(log n),是一种十分高效的数据结构。

本文将对红黑树算法的原理和实现进行介绍,帮助读者深入了解红黑树的运作流程和应用场景。

一、红黑树的定义和性质红黑树和其他的自平衡二叉查找树(如AVL树)一样,能够自动调整树的结构以保证平衡,并且能够保持树中每个节点的黑高相等。

下面是红黑树的具体定义:(1)每个节点要么是红色,要么是黑色。

(2)根节点是黑色。

(3)每个叶子节点(NIL节点,空节点)都是黑色的。

(4)如果一个节点是红色的,则它的子节点必须是黑色的。

(5)任意一个节点到每个叶子节点所经过的黑色节点数都相同。

这些性质确保了红黑树的平衡,在插入和删除节点时能够自动平衡而不需要人工干预,从而保证了树的性能。

二、红黑树的基本操作红黑树的插入和删除操作是它最为关键和难点的部分,下面我们将针对这两个操作进行介绍。

(1)插入操作插入节点时,首先按照二叉查找树的方式将新节点插入到树中。

接下来需要进行的操作是将节点的颜色进行调整,保证该节点符合红黑树的五大性质。

如果插入的节点不满足性质(4),需要执行进行一系列颜色调整和旋转操作,使得节点重新满足红黑树性质。

一般情况下,情况分为两种:(a)情况1:插入的节点为根节点此时只需要将节点的颜色设置为黑色即可。

(b)情况2:插入的节点的父节点为红色此时需要进行一系列的旋转和颜色调整操作。

可以分为以下三种情况:①插入节点的叔叔节点是红色的,此时需要进行颜色调整和旋转。

②插入节点的叔叔节点是黑色的,并且插入节点为父节点的右子节点,此时需要进行左旋操作。

③插入节点的叔叔节点是黑色的,并且插入节点为父节点的左子节点,此时需要进行颜色调整、右旋操作。

(2)删除操作删除节点时,首先按照二叉查找树的方式删除节点。

接着需要对树进行自平衡操作,使之重新满足红黑树性质。

与插入操作相比,删除操作需要考虑更多的情况。

java红黑树的原理

java红黑树的原理

java红黑树的原理Java红黑树(Red-BlackTree)是一种自平衡二叉查找树,其中任何节点的左子树都小于它的父节点,右子树都大于它的父节点。

它可以被用来存储有序的键值对,并具有高效的查找、插入和删除操作性能。

它被广泛用于编程语言编程,例如Java。

Java红黑树的概念由Leo J. Guibas和Robert Sedgewick在1978年的一篇论文中提出。

它是一种基于二叉查找树的红黑树结构,它具有自平衡特性,表现出比二叉查找树更高的性能。

在维护红黑树树结构方面,实现者需要满足两个基本要求:(1)红黑树中的所有节点必须是黑色或红色。

(2)根节点必须是黑色。

(3)每个叶节点(最后的空节点)都是黑色的。

(4)如果一个节点是红色的,那么它的子节点必须是黑色的。

(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑色节点。

红黑树的这些特性可以使它成为一种高效的数据结构。

它们能够确保树总是处于“平衡”状态,这意味着所有叶节点到根节点的距离都相同,搜索时间复杂度也能得到最优化。

Java红黑树的实现有多种方式,其中最常见的是经典的红黑树,它使用指针来存储节点之间的关系,并且为每个节点设置颜色位来指示其是红节点还是黑节点。

另一种实现方式是使用链表存储红黑树,也就是使用孩子兄弟法或CS树。

在这种实现方式中,每个节点都有两个指针,一个指向其左孩子,另一个指向其右孩子,同时增加一个指向其兄弟节点的指针。

这种实现方式会更加空间高效,因为它只需要使用一个孩子节点来存储其兄弟节点。

除了经典红黑树和链表红黑树外,还有另一种称为AA树的红黑树实现。

AA树是一种平衡的多叉查找树,它维护着若干红黑树的平衡,以此提高查找性能。

在AA树中,每个节点都有一个表示节点的红黑树状态的标志位,用于检测其是否满足红黑树的约束条件。

Java红黑树的优点在于它的查找、插入和删除操作性能优于二叉查找树,它能更快速地处理数据。

它还能更有效地存储键值对,因为它们节点中附带了更多的数据,尤其是颜色位。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

红黑树原理详解(上)前言:之所以要写这篇文章,第一个目的是为了各位朋友在查看我写的源代码之前有一个可以理解理论的文章因为红黑树还是有点难的,如果不想搞懂理论,而直接看代码,那绝对是云里雾里,不知所云。

第二个目的是我觉得网上虽然后不少我文章也在讲,但是我就是理解不上有点困难,在我参考了很多文章之后,认真阅读才慢慢摸透了其中的原理,所以我想用自己的方式来表达,希望有助于各位的朋友理解。

你可以在这里获得配套源代码红黑树由来:他是在1972年由Rudolf Bayer发明的,他称之为“对称二叉B树”,它现代的名字是Leo J. Guibas和 Robert Sedgewick 于1978年写的一篇论文中获得的。

它是复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。

红黑树性质:1. 每个结点或红或黑。

2. 根结点为黑色。

3. 每个叶结点(实际上就是NULL指针)都是黑色的。

4. 如果一个结点是红色的,那么它的周边3个节点都是黑色的。

5. 对于每个结点,从该结点到其所有子孙叶结点的路径中所包含的黑色结点个数都一样。

讨论的前提:1,我们只讨论往树的左边和从树的左边删除的情况,与之对称的情况一样。

2,假设我们要删除一个元素的方法都是采取删除后继节点,而非前驱节点。

3,NL或全黑表示黑空节点,也可以不用画出。

4,“=>”这个符号我们用来表示“变成”的意思。

一.插入当红黑树中没有节点的时候,新节点直接涂黑就可以了。

当树中已有节点,我们就将新节点涂红,并且底下挂两个黑空节点。

1.1 新节点的父亲为黑色这种情况最简单,只接插入将新节点可以了,不会出现红色警戒。

1.2 新节点的父亲为红色这种情况出现红色警戒,并且通过红色的父亲,我们可以推出一定有一个黑色的父,并且父亲不可能为树根(树根必须为黑)。

这种情况需要修复。

1.2.1 新节点的叔叔是红色。

(红叔)图1.2.1-1图1.2.1-2注解:在这种情况下,我们可以通过这样的方式来修复红黑树的性质。

因为遇到红色警戒所以我们首先可以想到的就是将父亲变成黑色,但这样祖父的左子树的黑高就增加了,为了达到祖父的平衡,我们红叔变成黑色,这样祖父就平衡了。

但是整个祖父这颗树的高度增高了,所以再此将祖父的颜色变成红色来保持祖父这颗树的高度不变。

因为祖父变成了红色,因此往上遍历。

方法:父=>黑;叔=>黑;祖=>红;往上遍历;1.2.2 新节点的叔叔是黑色(黑叔)图1.2.2-1图1.2.2-2注解:首先可以说明的是,这种情况下我们都可以通过改变颜色和旋转的方式到达平衡,并且不再出现红色警戒,因为无需往上遍历。

图1.2.2-1:首先我们将红父变成黑色,祖父变成红色,然后对祖父进行右旋转。

这样我们可以看到,整颗树的黑高不变,并且这颗树的左右子树也达到平衡。

新的树根为黑色。

因此无需往上遍历。

方法:图1.2.2-1 父=>黑;祖=>红;祖父右旋转;图1.2.2-2 新=>黑;祖=>红;父左旋转;祖右旋转;插入我们就算做完了,与之对称的右边插入的情况完全一样,请自己下来分析;一.删除删除是比较经典但也是最困难的一件事了,所以我们必须一步一步地理解。

为了中途思想不混乱,请始终记住一点,下面我们删除的节点都已经表示的是实际要删除的后继节点了。

因此可以得出一下结论。

首先,可以肯定的是我们要删除的节点要么是红色,要么是黑色。

其次,既然我们要删除的结点是后继节点,那么要删除的节点的左子树一定为空。

所以当删除的节点为黑色时只剩下两种情况。

最后,如果删除的节点为红色,那么它必为叶子节点。

(自己好好想象为什么)。

请在看下面的内容前先牢记上面的结论,这样更加方便让你理解下面的知识。

a:当删除的节点为黑色时删黑a 删黑bb:当删除的节点为红色时上面的几附图都是很简单的。

因为你可以将空节点去掉不看。

所就形成了要删除的节点要么有一个右孩子,要么为叶子节点。

下面我们就开始真正的删除操作了。

2.1 删除红色节点注解:这种情况是最简单的,因为根据上面的结论我们可以推出子节点一定为空,也就是说删除的红色节点为叶子节点。

只需将这个旧节点的右孩子付给父亲的左孩子就可以了,高度不变。

方法:略2.2 删除黑色节点遇到黑色节点情况就将变得复杂起来,因此我们一定要慢慢来,仔细分析。

2.2.1当删除的节点有一个红色子孩子注解:这种情况其实就是上面我们分析的三种情况之一,如图"删黑b"。

这种情况是非常简单的,只需将旧节点的右孩子取代旧节点,并将子孩子的颜色变为黑色,树平衡;方法:子取代旧;子=>黑;2.2.2当删除的节点无左右孩子这种情况其实就是上面我们分析的三种情况之一,如图"删黑a"。

我们推出子节点一定为空,请务必记住这点,不然在后面你将很容易被混淆,父亲的颜色我们标记为绿色,是表示,父亲的颜色可为红或黑。

黄色的子节点其实就是一个黑空节点,这样方便后面分析。

a:红兄注解:当我们删除的节点拥有一个红色的兄弟时,这种情况还相对比较简单,因为兄弟为黑色,我们可以推出父亲一定为黑色。

因为父节点的左树高度减一,所以我们可以通过左旋转父节点,来将节点1旋转到左边来恢复左边的高度。

然后将父变成红,兄变成黑。

这样整颗树的高度不变,父节点也平衡记住子节点为空所以可以删除看,这样便于理解。

其实我们也可以推出1,2为空,但这里没有必要。

方法:父=>红;兄=>黑;左旋转父节点;红黑树原理详解(下)b :黑兄遇到黑兄就又麻烦了,我们又必须引入要删除的节点的侄子了。

所以我们这里再次细分为b1: 黑兄双黑侄 b2: 黑兄左黑侄右红侄 b3: 黑兄右黑侄左红侄。

可能你会问b4呢,双红侄的情况呢?其实双红侄的情况同属于b2,b3的情况,所以可以默认用 b2,b3其中一种情况来处理就可以了。

现在我们开始了b1黑兄双黑侄注解:我们首先可以肯定的是父节点的左子树高度减一了,所以我们必须想方设法来弥补这个缺陷。

如果我们把父节点的右子树高度也减一(兄变成红色)那么父节点这颗树就可以保持平衡了,但整颗树的高度减一,所以我们可以判断,如果父亲是红色,那么我们可以通过把父亲变成黑色来弥补这一缺陷。

但如果父亲是黑色呢,既然遇到到黑色了我们就只好往上遍历了。

方法:兄=>红;子=黑;红父=>黑;往上遍历(黑父);补充:其实子节点就是空节点,没有必要变。

就算遍历上去,父节点也为黑b2 黑兄左黑侄右红侄注解:绿色表示,颜色不影响修复的方式。

依然我们可以肯定父节点的左子树高度减一,所以我们可以通过将父节点旋转下来并且变为黑色来弥补,但由于兄弟被旋转上去了,又导致右子树高度减一,但我们这有一个红侄,所以可以通过红侄变成黑色来弥补。

父亲所在位置的颜色不变;(子为空)方法:兄=>父色;父=>黑;侄=>黑;(子=>黑);左旋转父节点;b3 黑兄左红侄右黑侄注解:绿色表示,颜色不影响修复的方式。

依然我们可以肯定父节点的左子树高度减一,同样我们通过父节点左旋转到左子树来弥补这一缺陷。

但如果直接旋转的话,我们可以推出左右子树将不平衡(黑父),或者两个红色节点相遇(红父);这样将会更加的复杂,甚至不可行。

因此,我们考虑首先将兄弟所在子树右旋转,然后再左旋转父子树。

这样我们就可以得到旋转后的树。

然后通过修改颜色来使其达到平衡,且高度不变。

方法:侄=>父色;父=>黑;右旋转兄;左旋转父;总结:如果我们通过上面的情况画出所有的分支图,我们可以得出如下结论插入操作:解决的是红-红问题删除操作:解决的是黑-黑问题即你可以从分支图中看出,需要往上遍历的情况为红红(插入);或者为黑黑黑(删除)的情况,,如果你认真分析并总结所有的情况后,并坚持下来,红黑树也就没有想象中的那么恐怖了,并且很美妙;程序样列:点击这里下载源码声明:此文档为《C语言常用数据结构源代码全注解-红黑树源码》所写,此文档遵循GNU FDL协议,你可以修改重发,但因保留原始版权信息;此文档版本V1.0为初次发布,所以难面有错误的地方,如果你发现任何错误或缺点,非常感谢你发信息联系我。

此文档仅供学习使用。

参考文献:《百度百科红黑树》地址:/view/133754.htm《C#与数据结构-树论—红黑树》地址:/2008-12/1229486123100653_7.html《資料結構與演算法(上)》作者:呂學一《資料結構與演算法(上)》红黑树大部分图片来源版权信息:本文来源:『20065562's Blog』有水的地方就有余文章转载自20065562's Blog请点击这里查看原文地址:/20065562/blog/item/8777467e5292f30229388a0f.html。

相关文档
最新文档