JAVA中基于红黑树实现TreeMap的说明

Posted

技术标签:

【中文标题】JAVA中基于红黑树实现TreeMap的说明【英文标题】:Explanation of Red-Black tree based implementation of TreeMap in JAVA 【发布时间】: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;
        ....

关于红黑树的定义。从***我发现:

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

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

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

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

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

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

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

【问题讨论】:

你看过 JSE 源码吗?一切都清楚了。 【参考方案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
    

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

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

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

【讨论】:

我一直在尝试查找 TreeMap 的迭代是如何在内部完成的,但无法在线找到它。你能帮我理解一下使用什么遍历算法来遍历内部存在的红黑树。 遍历很简单:以根节点为当前节点,如果要查找的值为当前节点,则返回,否则低于当前节点,左元素为当前节点并重复,如果值大于当前节点,则使右元素为当前节点并重复。

以上是关于JAVA中基于红黑树实现TreeMap的说明的主要内容,如果未能解决你的问题,请参考以下文章

Java - HashTree源码解析 + 红黑树

27.TreeMap

TreeMap源码分析,看了都说好

Java提高篇(二七)-----TreeMap

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

JAVA集合:TreeMap红黑树深度解析