【问题标题】:Explanation of Red-Black tree based implementation of TreeMap in JAVAJAVA中基于红黑树实现TreeMap的说明
【发布时间】:2014-02-15 06:28:04
【问题描述】:

我正在浏览 JAVA 中的 TreeMap 的源代码。 根据 JAVA 文档:

基于红黑树的 NavigableMap 实现。地图根据其键的自然顺序或在地图创建时提供的 Comparator 进行排序,具体取决于使用的构造函数。

此实现为 containsKey、get、put 和 remove 操作提供有保证的 log(n) 时间成本。算法是对 Cormen、Leiserson 和 Rivest 的算法简介中的算法的改编。

在源代码中我发现一个内部类Entry被用作节点

static final class Entry<K,V> implements Map.Entry<K,V> {
        K key;
        V value;
        Entry<K,V> left = null;
        Entry<K,V> right = null;
        Entry<K,V> parent;
        boolean color = BLACK;
        ....

关于红黑树的定义。从维基百科我发现:

红黑树是一种自平衡二叉搜索树,是计算机科学中使用的一种数据结构。

通过使用两种颜色(通常称为“红色”和“黑色”,因此树的名称)中的一种来绘制每个节点来提供自平衡,以使生成的绘制树满足某些属性不允许它变得明显不平衡。当树被修改时,新树随后被重新排列并重新绘制以恢复着色属性。这些属性的设计方式使得这种重新排列和重新着色可以有效地执行。

我试图分析源代码但无法理解以下内容:

  1. 假设我已经在树中有两个键“C”和“E”,然后我添加了“D”。节点将如何排列(使用自然排序)。

  2. java源码中Tree的自平衡是如何实现的。

我尝试搜索TreeMap的详细实现,但找不到任何文章,例如我为HashMap找到的following article

从昨天开始我就挂在这棵树上:(有人可以帮我下来吗...

【问题讨论】:

  • 你看过 JSE 源码吗?一切都清楚了。

标签: java treemap red-black-tree


【解决方案1】:
  1. TreeMap 的目标是创建一个键树,其中低于父键的键位于左侧,高于父键的键位于右侧。因此,如果您添加C,然后添加E,您将拥有这棵树:

    C
     \
      E
    

    如果您随后添加D,最初您将拥有:

    C
     \
      E
     /
    D
    

    但是这棵树是不平衡的,因此搜索会比较慢。因此,树被重新平衡。平衡后,树现在变得更加高效:

    C                     C
     \        rotate       \         rotate         D
      E   --- right --->    D    ---  left --->    / \
     /        around         \       around       C   E
    D           E             E        D
    
  2. 重新平衡发生在fixAfterInsertion() 方法中,该方法检查插入后树的红黑属性是否仍然保持。并且,如果没有,那么它会重新平衡在有问题的分支上执行rotateLeft()rotateRight() 的树以恢复平衡。然后它向上移动树并检查余额等等,直到它到达根节点。

互联网上有多种资源可以深入解释红黑树。但是,我认为理解这个过程的最好方法是遵循这样的动画教程:http://www.csanimated.com/animation.php?t=Red-black_tree

TreeMap 的 RBT 实现没有什么特别之处。它紧跟 CLRS(Cormen、Leiserson、Rivest 和 Stein)一书中给出的伪代码,这是 99% 的实现。

【讨论】:

  • 我一直在尝试查找 TreeMap 的迭代是如何在内部完成的,但无法在线找到它。你能帮我理解一下使用什么遍历算法来遍历内部存在的红黑树。
  • 遍历很简单:以根节点为当前节点,如果要查找的值为当前节点,则返回,否则低于当前节点,左元素为当前节点并重复,如果值大于当前节点,则使右元素为当前节点并重复。
猜你喜欢
  • 2016-07-15
  • 2012-08-20
  • 1970-01-01
  • 2010-12-14
  • 2016-06-28
  • 2012-12-24
  • 2021-06-27
  • 2013-02-28
相关资源
最近更新 更多