
正文
红黑树的go语言 红黑树csdn
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
Go语言map是怎么比较key是否存在的
首先,不推荐使用[]来判断key是否存在,因为使用操作符[]会向map容器里插入一个元素.map红黑树的go语言的operator[]重载大致是这样一个内容红黑树的go语言:
data_type operator[]( const key_type k ){value_type v(k,data_type());
iterator it = insert(v).first;
} 大致是这样,如果没有找到的话就插入一个,然后返回它的second.正确的判断方法是使用map的find函数,由于map是一个红黑树,find的时间复杂度是logn,可以接受.bool i***ist(constString keyName) { return( mRegistryMap.find(keyName)!= mRegistryMap.end()); }
相关问答
Q1: 红黑树——一个自平衡的二叉搜索树
普通红黑树的go语言的二叉搜索树在最坏的情况下红黑树的go语言,可能退化成一个链表。而又因为二叉搜索树的所有操作的性能(添加,删除,查找等),与二叉搜索树的高度有关。在最坏的情况下,二叉搜索树的高度和元素个数相同,此时二叉搜索树的效率降为了O(n)级别。
所以为了防止我们的二叉搜索树退化成一个链表,就产生了 平衡二叉树 。 平衡二叉树 可以保证它的左右两个子树的高度差不会超过1。平衡二叉树有很多实现,一个经典实现就是 红黑树 。
在红黑树中将树中的节点划分为两种状态,分别用黑色和红色来表示。
红黑树为了保证自己能够平衡子树,所以制订以下五个规则:
1、每个节点必须有颜色,要么黑色,要么红色,没有别的颜色。
2、根节点必须是黑色
3、所有的空节点(nil节点)都认为是黑色节点。
4、红色的节点不能连续,即一个红色的节点,它的父节点和子节点不能也是红色的,
5、无论从哪一个节点起始,到它每个叶子节点的路径中,黑色节点数量必须相同。
在对红黑树进行添加、删除等操作之后,必须使红黑树符合这5个规则。
那么问题来了,在添加删除操作之后,树中节点的数量都变了,是怎么保证整个树满足上述这些规则呢?
这里涉及到3种操作, 变色 、 左旋 和 右旋 。通过这个三种操作,在增删节点之后调整树的形状结构,使它满足上述5个规则。这也是红黑树能保持平衡的原因。
变色操作 我们在下文的添加、删除节点的实际操作中,再进行在描述。
先来说一下左右旋。
文字描述一下就是,2的右孩子节点4,变为了2的父节点,2由父节点变为4的左孩子。同时,4原来的左孩子变为2的右孩子。
右旋与左旋相反,即以某节点为支点进行顺时针旋转。同样,我们看下图,是以5为支点进行的右旋:
文字描述同样反过来,5的左孩子节点3,变为5的父节点,5由父节点变为3的右孩子。3原来的右孩子变为5的左孩子。
首先是在树中找到新节点正确的位置,寻找位置的过程与普通的二叉搜索树相同,只是将新插入的节点默认为 红色节点 。为什么默认为红色?因为如果你将新节点默认为黑色,则插入后肯定会打破原本符合规则的红黑树(上述第5条规则)。但是,如果你将新节点定为红色,则有可能不用任何操作就符合红黑树规则,如下图,当新插入的红色节点,它的父亲节点为黑色时候,此时已经满足红黑树规则了。所以用红色比黑色好。
如果很不巧,新插入的节点的父亲节点也为红色,因为红色节点不能连续,所以我们需要调整红黑树的结构使其满足规则。在调整的过程中我们会遇到3种需要处理的情况,我们来一一进行说明。
情况1:
插入新节点40, 此时它的父节点为红色,并且它的叔叔节点(即51)也为红色 。此时我们需要进行 变色 操作。 将该节点的父亲节点、叔叔节点都变为黑色,祖父节点变为红色 。
此时上图已经满足红黑树的规则。但有的时候我们经过了变色操作后,仍不满足红黑树的规则,会遇到下面的情况。
情况2:
如图,我们插入新的节点53,在按情况1的操作变色后,变成了这样:
最后我们说一下情况3的情景,如下图:
我们向树中插入新节点37,在按情况1的操作变色后,变成了这样:
情况3:
3种情况我们说明完了,但是你可能还会有这样的疑问,什么时候进行左旋,什么时候进行右旋红黑树的go语言;什么时候以父节点为支点旋转,什么时候又以祖父节点为支点旋转?
那么我们可以总结一下,当遇到连续的红色节点应该怎么办: 当前节点我们叫它X,如果X相对于父节点的左右位置和父节点相对于祖父节点的左右位置相同,此时,就以祖父节点为支点,进行反向旋转。例如:X为父节点的左孩子,X的父节点同样也是其祖父节点的左孩子,此时以祖父节点为支点进行右旋红黑树的go语言;
如果X相对于父节点的左右位置和父节点相对于祖父节点的左右位置不同,则以X的父节点为支点,进行旋转,旋转方向与X相对于父节点左右位置相反。例如:X为其父节点的左孩子,X的父节点为祖父节点的右孩子,此时以X的父节点为支点进行一次右旋。
在红黑树中删除节点,肯定要涉及到要删的这个节点是红色的还是黑色的。删除红色比较简单,我们先说一下删除红色节点。
删除节点要考虑这个节点所处的位置,所以我们罗列一下红色的节点所有可能的位置情况。
你可能会发现为什么少了一种情况?它不能只有左子树或者只有右子树吗?我们可以看下图:
很明显,这四种情况都不符合红黑树的规则,所以根本不会出现这种情况。
而对于既有左子树也有右子树的情况。 我们可以先和普通的二叉搜索树的删除操作一样,将它与前驱或者后继交换一下 。它就又变成第一种情况——成为了一个叶子节点。所以我们只需考虑当它是叶子节点的情况。
接下来我们看一下当要删除的节点是黑色的时候应该怎么办。
同样我们列一下节点位置可能的情况:
第三种情况和删除红色节点时的处理方法一样,可以转换成第一种或第二种情况,所以我们只关心前两种情况。
当要删除的黑色节点只有一个子树时:
最后我们看一下最难处理的一种情况。
要删除的黑色节点是叶子节点时:
情况1:待删除黑色节点20,它的兄弟节点为红色。
操作方法为:将远侄子节点变黑,兄弟节点与父亲节点互换颜色,最后以父节点为支点进行 左旋 。(为什么是左旋?因为待删除的20是左孩子,我们要将左子树长度拉长,将它沉下来,使它变成多余的节点好删除它,如果它是右孩子,则进行右旋)
操作后如下图就完成了。
情况3:待删除黑色节点20,它的兄弟节点为黑色,但它没有红色的远侄子节点(即nil点,记住,nil点算黑色),只有红色的近侄子节点。
操作后如下图:
此时有了红色的远侄子,就满足了情况2,再按情况2进行一次操作就完成了。
情况4:待删除黑色节点20,它的兄弟节点为黑色,远侄子、近侄子节点都没有。(即两个nil节点,nil节点算黑色)
我们将上图红黑树按流程演示一下:
第一步按情况4操作,将55变红。并将父节点50看做当前节点,继续操作。
此时有关红黑树的知识就说完了。
以上所有内容都为自己查阅资料学习理解之后手敲的。尽量得采用通俗易懂的描述和解释让读者更明白。27张图都是自己亲自画的,花费了四天才写完,如果觉得写的还可以,麻烦点亮喜欢支持一下,如果还是不懂,可以下方留言QQ等联系方式,我亲自告诉你。
Q2: 红黑树怎么实现对历史版本的访问
红黑树的出现可以解决对历史版本的访问问题。主要是将插入和删除控制在常数范围内。
多版本,大量数据共享。少量更新。
绝大多数的树,在动态操作过程当中如果不超过常数比较难。主要是旋转。插入式满足的,一次旋转性能就可以复原,但是很可惜,删除可能需要多大logn的旋转。任何动态操作都能控制在常数的范围,就是红黑树。
第三个对控制深度比较重要,第四个对于平衡性比较重要。
使用(2,3)b树对红黑树进行分析。
提升变换对于红黑树的意义。底层节点比那成同一水平节点平齐高度。
Q3: 红黑树的用途
红黑树用在关联数组、字典红黑树的go语言的实现上。需要的空间比散列表小。 任何键值对应,需要随机存储和键有序的情况都可以用。
一. 基本概念
1.红黑树(Red Black Tree) 是一种自平衡二叉查找树红黑树的go语言,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。
2.它是在1972年由Rudolf Bayer发明的,当时被称为平衡二叉B树(symmetric binary B-trees)。后来,在1978年被 Leo J. Guibas 和 Robert Sedgewick 修改为如今的"红黑树"。
3.红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。
4.它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。
二. 数据结构
它的统计性能要好于平衡二叉树(有些书籍根红黑树据作者姓名,Adelson-Velskii和Landis,将其称为AVL-树),因此,红黑树在很多地方都有应用。在C++ STL中,很多部分(包括set, multiset, map, multimap)应用红黑树的go语言了红黑树的变体(SGI STL中的红黑树有一些变化,这些修改提供了更好的性能,以及对set操作的支持)。其红黑树的go语言他平衡树还有:AVL,SBT,伸展树,TREAP 等等。
三. 性质
性质1. 节点是红色或黑色。
性质2. 根节点是黑色。
性质3.每个叶节点(NIL节点,空节点)是黑色的。
性质4.每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
性质5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
Q4: 在linux操作系统内核实现里经常使用的红黑树
在linux操作系统内核实现里经常使用的红黑树如下:
二叉树,按中序遍历后为一递增数组,自平衡意味着树的高度有一个上限,对于红黑树,其为2log(n+1),所以时间复杂度为最差为Olog(n)。
赋予二叉搜索树自平衡特性的方法有多种,红黑树通过一下4条约束实现自平衡:
Every node is either red or black.
All NIL nodes (figure 1) are considered black.
A red node does not have a red child.
Every path from a given node to any of its descendant NIL nodes goes through the same number of black nodes.
其中根节点为黑色。
红黑树的搜索与二叉搜索树无异,但是插入和删除可能会违背上述四条原则。需要用到左旋右旋操作。左旋右旋上图,可以看到左旋右旋本身不改变二叉搜索树的特性,旋转后必要时改变节点的颜色可消除插入或者删除带来的红冲突和黑冲突,有时红黑树的重新平衡需要迭代进行。
红黑树比较适合的应用场景:
需要动态插入、删除、查找的场景,包括但不限于:
某些数据库的增删改查,比如select * from xxx where 这类条件检索。
linux内核中进程通过红黑树组织管理,便于快速插入、删除、查找进程的task_struct。
linux内存中内存的管理:分配和回收。用红黑树组织已经分配的内存块,当应用程序调用free释放内存的时候,可以根据内存地址在红黑树中快速找到目标内存块。
hashmap中(key,value)增、删、改查的实现;java 8就采用了RBTree替代链表。
Ext3文件系统,通过红黑树组织目录项。
红黑树的go语言的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于红黑树csdn、红黑树的go语言的信息别忘了在本站进行查找喔。







