hashmap中为什么使用红黑树?

问题1:为什么不使用二叉排序树?
问题主要出现在二叉排序树在添加元素的时候极端情况下会出现线性结构。

举例说明:由于二叉排序树左子树所有节点的值均小于根节点的特点,如果我们添加的元素都比根节点小,会导致左子树线性增长,这样就失去了用树型结构替换链表的初衷,导致查询时间增长。所以这是不用二叉查找树的原因。

问题2:为什么不使用平衡二叉树呢?
①红黑树不追求"完全平衡",即不像AVL那样要求节点的 |balFact| <= 1,它只要求部分达到平衡,但是提出了为节点增加颜色,红黑是用非严格的平衡来换取增删节点时候旋转次数的降低,任何不平衡都会在三次旋转之内解决,而AVL是严格平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转的次数比红黑树要多。
就插入节点导致树失衡的情况,AVL和RB-Tree都是最多两次树旋转来实现复衡rebalance,旋转的量级是O(1)
删除节点导致失衡,AVL需要维护从被删除节点到根节点root这条路径上所有节点的平衡,旋转的量级为O(logN),而RB-Tree最多只需要旋转3次实现复衡,只需O(1),所以说RB-Tree删除节点的rebalance的效率更高,开销更小!
AVL的结构相较于RB-Tree更为平衡,插入和删除引起失衡,如2所述,RB-Tree复衡效率更高;当然,由于AVL高度平衡,因此AVL的Search效率更高啦。
针对插入和删除节点导致失衡后的rebalance操作,红黑树能够提供一个比较"便宜"的解决方案,降低开销,是对search,insert ,以及delete效率的折衷,总体来说,RB-Tree的统计性能高于AVL.
故引入RB-Tree是功能、性能、空间开销的折中结果。
② AVL更平衡,结构上更加直观,时间效能针对读取而言更高;维护稍慢,空间开销较大。
③ 红黑树,读取略逊于AVL,维护强于AVL,空间开销与AVL类似,内容极多时略优于AVL,维护优于AVL。
基本上主要的几种平衡树看来,红黑树有着良好的稳定性和完整的功能,性能表现也很不错,综合实力强,在诸如STL的场景中需要稳定表现。

问题3:为什么不使用b+树呢?
B+树在数据库中被应用的原因是其“矮胖”的特点,B+树的非叶子结点不存储数据,所以每个结点能存储的关键字更多。所以B+树更能应对大量数据的情况。jdk1.7中的HashMap本来是数组+链表的形式,链表由于其查找慢的特点,所以需要被查找效率更高的树结构来替换。如果用B+树的话,在数据量不是很多的情况下,数据都会“挤在”一个结点里面。这个时候遍历效率就退化成了链表。
结论:b+树不属于二叉树,因为二叉查找树的查找效率是最高的,如果内存能装下完整的树,最好使用二叉查找树,b+树是退而求其次的方式。

问题4:为什么不使用跳表呢?
跳跃表也可以很快的查询数据,但是 HashMap 的 各个Entry 之间并没有内在的排序关系,跳表需要元素之间存在排序关系,否则就无法跳跃查找不是吗?

TreeMap 的并发实现 ConcurrentSkipListMap 就是使用的跳表。

再者就是跳跃表因为要定义多级指针,是以空间换时间的数据结构,红黑树树不需要额外的空间。
 

你可能感兴趣的:(数据结构)