Sedgewick的红黑树

  红黑树一直是数据结构中的难点,大部分关于红黑树的学习资料(包括《算法导论》)对于这部分的讲解都是上来就下定义,告诉我们红黑树这个性质那个性质,插入删除要注意1234点,但是基本没有讲为什么这样定义红色和黑色,让人理解起来十分费力。直到我看了下图这本树中关于红黑树部分的讲解,一时间豁然开朗,上网查了下这本书的作者Sedgewick,他是伟大的高德纳的学生!红黑树的发明者!

  他在这本书中告诉了我们红黑树的根本模型:以二叉树的形式实现2-3树,通过红黑树与2-3树之间的一一对应,让我们对红黑树有了更直观的理解。

  这本树里所讲的是左偏红黑树模型,理解了这个模型,再理解算法导论的完整红黑树模型就容易的多了。

  

  2-3树

  

  定义2-3查找树允许树中的一个结点保存多个键,一棵2-3查找树或为一棵空树,或由以下结点组成:

  2-结点,含有一个键(及其对应的值)和两条链接,左链接指向的2-3树中的键都小于该结点,右链接指向的2-3树中的键都大于该结点。

  3-结点,含有两个键(及其对应的值)和三条链接,左链接指向的2-3树中的键都小于该结点,中链接指向的2-3树中的键都位于该结点的两个键之间,右链接指向的2-3树中的键都大于该结点。

  一棵完美平衡的2-3查找树中的所有空链接到根结点的距离都应该是相同的。这里我们用2-3树指代一棵完美平衡的2-3查找树,如下图所示。

  

  查找。将二叉查找树的查找算法一般化我们就能够直接得到2-3树的查找算法。要判断一个键是否在树中,我们先将它和根节点中的键比较。如果它和其中任意一个相等,查找命中;否则我们就根据比较的结果找到指向相应区间的链接,并在其指向的子树中递归地继续查找。如果这个是空连接,查找未命中。

  

  插入。要在2-3树中插入一个新结点,我们可以和二叉查找树一样先进行一次未命中的查找,如果未命中的查找结束于一个2-结点,事情就好办了:我们只要把这个2-结点替换为一个3-结点,将要插入的键保存在其中即可。如果未命中的查找结束于一个3-结点,事情就要麻烦一些。

    向2-结点中插入新键

    

    向一棵只含有一个3-结点的树中插入新键

    

    

    向一个父节点为2-结点的3-结点中插入新键

    

    向一个父节点为3-结点的3-结点中插入新键

    

    插入结点到根节点的路径上全都是3-结点

    

  

  和标准的二叉查找树由上向下生长不同,2-3树的生长是由下向上的:随着结点的插入,临时4-结点的中键不断上浮,一旦根节点变成临时4-结点,我们可以分解根结点完成树的生长,使得树高加1。
  下图给出了我们的标准索引测试用例中产生的一系列2-3树,以及一系列由同一组键按照升序一次插入到树中时所产生的所有2-3树。如果是在二叉查找树中,按照升序插入10个键会得到高度为9的一棵最差查找树,而使用2-3树,树的高度是2。

  

  在一棵大小为N的2-3树中,查找和插入操作访问的结点必然不超过lgN个
  尽管我们可以用不同的数据类型表示2-结点和3-结点并写出变换所需的代码,这样我们需要维护两种不同类型的结点,将被查找的键和结点中的每个键进行比较,将链接和其他信息从一种结点复制到另一种结点,将结点从一种数据类型转换到另一种数据类型等等。实现这些不仅需要大量的代码,而且它们所产生的额外开销可能会使算法比标准的二叉查找树更慢。幸运的是我们可以使用红黑树来解决这个问题,它以二叉树的形式实现了2-3树。

  

  红黑树

  定义。红黑树的一种定义是含有红黑链接并满足下列条件的二叉查找树:

  红链接均为左链接(左偏红黑树);
  没有任何一个结点同时和两条红链接相连;
  该树是完美黑色平衡的,即任意空链接到根节点的路径上的黑链接数量相同。

  满足这样定义的红黑树和相应的2-3树是一一对应的。
  如果我们将一棵红黑树中的红链接画平,那么所有的空链接到根节点的距离都将是相同的。如果我们将有红链接相连的结点合并,得到的就是一棵2-3树。
  相反,如果将一棵2-3树中的3-结点画作由红色左链接相连的两个2-结点,那么不会存在能够和两条红链接相连的结点,且树必然是完美黑色平衡的。
  红黑树既是二叉查找树,也是2-3树。因此如果我们能够在保持一一对应关系的基础上实现2-3树的插入算法,那么我们就能够将两个算法的优点结合起来:二叉查找树中简洁高效的查找算法和2-3树中高效的平衡插入算法。

  

  颜色表示。因为每个结点都只会有一条指向自己的链接(从它的父结点指向它),我们将链接的颜色保存在表示结点的Node数据类型的布尔变量color中。如果指向它的链接是红色的,那么该变量为true,黑色则为false。我们约定空链接为黑色。

  

  

  旋转。首先,假设我们有一条红色的右链接需要被转化为左链接,这个操作叫左旋转。它只是将用两个键中的较小者作为根节点变为将较大者作为根节点。
     实现将一个红色左链接转换为红色右链接的右旋转的代码完全相同,只需要将left换成right即可。

    

  插入。在插入新的键时我们可以使用旋转操作帮助我们保证红黑树和2-3树之间的一一对应关系,因为旋转操作可以保持红黑树的两个重要性质:有序性完美平衡性。我们只需考虑如何使用旋转操作来保持红黑树的另外两个重要性质:不存在两条连续的红链接不存在红色的右链接
  用和二叉查找树相同的方式向一棵红黑树中插入一个新键会在树的底部新增一个结点,但总是用红链接将新结点和它的父结点相连
    向2-结点中插入新键

    

    向树底部的2-结点插入新键

    

    向一个3-结点中插入新键。这种情况又可分为三种子情况:新键大于树中的两个键小于树中的两个键,或是在两者之间

    

    颜色转换。我们专门用一个方法flipColors()来转换一个结点的两个红色子结点的颜色。颜色转换会使根结点变成红色,两个子结点变成黑色。

    

    向树底部的3-结点插入新键

    

  红黑树构造轨迹。

  

  删除。和插入操作一样,我们也可以定义一系列局部变换来在删除一个结点的同时保持树的完美平衡性。这一过程比插入一个结点更加复杂,因为我们不仅要在(为了删除一个结点而)构造临时4-结点时沿着查找路径向下进行变换,还要在分解遗留的临时4-结点时沿着查找路径向上进行变换(同插入操作)。

    删除最小键。从树底部的3-结点中删除键是很简单的,但2-结点则不然。从2-结点中删除一个键会留下一个空结点,一般我们会将它替换为一个空链接,但这样会破坏树的完美平衡性。为了保证我们不会删除一个2-结点,我们沿着左链接向下进行变换(最小键一定在左链接上),确保当前结点不是2-结点(即左链接上的结点可以是3-结点,也可以是临时的4-结点),最后能够得到一个含有最小键的3-结点或者临时4-结点,然后我们就可以直接从中将其删除,将3-结点变为2-结点,或者将临时4-结点变为3-结点。然后我们再回头向上分解所有临时的4结点。

    

    删除任意键。在查找路径上进行和删除最小键相同的变换同样可以保证在查找过程中任意当前结点均不是2-结点。如果被查找的的键在树的底部,我们可以直接删除它。如果不在,我们需要将它和它的后继结点交换。因为当前结点必然不是2-结点,问题已经转化为在一棵根节点不是2-结点的子树中删除最小的键,我们可以在这棵子树中使用上述的算法,删除之后我们需要向上回溯并分解余下的4-结点。

时间: 2024-10-13 11:46:35

Sedgewick的红黑树的相关文章

B-树、B+树、红黑树

B-树 B-tree树即B树,B即Balanced,平衡的意思,B-树又称为多路平衡查找树.因为B树的原英文名称为B-tree,而国内很多人喜欢把B-tree译作B-树,其实,这是个非常不好的直译,很容易让人产生误解.如人们可能会以为B-树是一种树,而B树又是另一种树.而事实上是,B-tree就是指的B树. 一.定义 B-树是一种多路搜索树(并不一定是二叉的) 1970年,R.Bayer和E.mccreight提出了一种适用于外查找的树,它是一种平衡的多叉树,称为B树(或B-树.B_树). 一棵

红黑树学习

红黑树是工程中用的比较多的一个数据结构,它的优点是查找的复杂度是O(lgN), 而且红黑树会在插入 数据的时候保持平衡,抑制复杂度的暴涨.虽然它没有hashtable那样高效,但是不用事先规划并分配空间.那么它是怎么做到的呢? 下面是它的特性: 1.红黑树由红色和黑色的元素构成(着色) 2.红色节点没有红色的子节点(红色与红色是宿敌) 3.所有从根节点到叶子节点的黑色节点数量相等(左右平衡). 可以推出: 1根节点是黑色的. 2.红色节点的两个子节点都是黑色的 插入操作 数据是怎么插入呢?这里忘

数据结构基础(18) --红黑树的设计与实现(1)

红黑树是一种自平衡的二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组(C++ STL 中的map/set).它是在1972年由Rudolf Bayer发明的,他称之为"对称二叉B树",它现代的名字是 Leo J. Guibas 和 Robert Sedgewick 于1978年写的一篇论文中获得的.红黑树虽然很复杂,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目(来源百度

D&F学数据结构系列——红黑树

红黑树 定义:一棵二叉查找树如果满足下面的红黑性质,则为一棵红黑树: 1)每个结点不是红的就是黑的 2)根结点是黑的 3)每个叶结点是黑的 4)如果一个结点是红的,它的两个儿子都是黑的(即不可能有两个连续的红色结点) 5)对于每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点 性质: 这些约束确保了红黑树的关键特性: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长.结果是这个树大致上是平衡的.因为操作比如插入.删除和查找某个值的最坏情况时间都要求与树的高度成比例,这个在高度上

数据结构拾遗(1) --红黑树的设计与实现(上)

红黑树是一种自平衡的二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组(C++ STL 中的map/set).它是在1972年由Rudolf Bayer发明的,他称之为"对称二叉B树",它现代的名字是在 Leo J. Guibas 和 Robert Sedgewick 于1978年写的一篇论文中获得的.红黑树虽然很复杂,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目(来源:

java中treemap和treeset实现(红黑树)

TreeMap 的实现就是红黑树数据结构,也就说是一棵自平衡的排序二叉树,这样就可以保证当需要快速检索指定节点. TreeSet 和 TreeMap 的关系 为了让大家了解 TreeMap 和 TreeSet 之间的关系,下面先看 TreeSet 类的部分源代码: public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializab

红黑树(Red Black Tree)

介绍另一种平衡二叉树:红黑树(Red Black Tree),红黑树由Rudolf Bayer于1972年发明,当时被称为平衡二叉B树(symmetric binary B-trees),1978年被Leonidas J. Guibas 和 Robert Sedgewick改成一个比较摩登的名字:红黑树. 红黑树和之前所讲的AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能.自从红黑树出来后,AVL树就被放到了博物馆里,据说是红黑树有更好的效率,更高

数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树

在上一篇数据结构的博文<数据结构(三):非线性逻辑结构-二叉树>中已经对二叉树的概念.遍历等基本的概念和操作进行了介绍.本篇博文主要介绍几个特殊的二叉树,堆.哈夫曼树.二叉搜索树.平衡二叉搜索树.红黑树.线索二叉树,它们在解决实际问题中有着非常重要的应用.本文主要从概念和一些基本操作上进行分类和总结. 一.概念总揽 (1) 堆 堆(heap order)是一种特殊的表,如果将它看做是一颗完全二叉树的层次序列,那么它具有如下的性质:每个节点的值都不大于其孩子的值,或每个节点的值都不小于其孩子的值

Atitit 常见的树形结构 红黑树 &#160;二叉树 &#160;&#160;B树 B+树 &#160;Trie树&#160;attilax理解与总结

Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结 1.1. 树形结构-- 一对多的关系1 1.2. 树的相关术语: 1 1.3. 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树2 1.4. 满二叉树和完全二叉树..完全二叉树说明深度达到完全了.2 1.5. 属的逻辑表示 树形比奥死,括号表示,文氏图,凹镜法表示3 1.6. 二叉树是数据结构中一种重要的数据结构,也是树表家族最为基础的结构.3 1.6.1. 3.2 平衡二叉