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的说明的主要内容,如果未能解决你的问题,请参考以下文章