为什么Java的TreeMap不允许初始大小?

时间:2013-08-26 00:20:25

标签: java treemap

加载1 000 000个数字需要2秒才能加载到树形图(二叉搜索树)中,但需要几毫秒才能加载到hashmap中(在java中)。
两者之间的唯一区别是我可以看到我可以设置一个hashmap的初始大小,因此它不需要经常重新调整大小。

我认为应该能够设置TreeMap的数组初始大小是错误的吗?它有这么慢的原因吗? 是否存在逻辑上的原因导致无法设置TreeMap或任何通用二进制搜索树的大小或错误?

4 个答案:

答案 0 :(得分:11)

HashMap重新分配其内部结构时不同,TreeMap通常不会在添加新节点时重新分配其节点。差异可以非常宽松地说明为ArrayListLinkedList之间的差异:第一个重新分配以调整大小,而第二个不重新分配。这就是设置TreeMap的初始大小与尝试设置LinkedList的初始大小毫无意义的原因。

速度差异是由于两个容器的时间复杂度不同:将N节点插入HashMapO(n),而TreeMap插入O(N*LogN) {{1}} 1}},对于1000000个节点大约是渐近差异的20倍。虽然渐近复杂度的差异并不直接转化为时序差异,因为各个算法决定了不同的常数,但它可以作为决定哪种算法在非常大的输入上更快的好方法。

答案 1 :(得分:4)

  

我认为应该能够设置TreeMap的数组初始大小是错误的吗?

是。 TreeMap没有数组。 TreeMap使用包含2个子节点的二进制节点。

如果您建议树节点中的子节点数应该是参数,那么您需要弄清楚它对搜索时间的影响。我认为它将搜索时间从O(log2N)变为O(log2M * log2(N/M)),其中N是数字元素,M是节点子节点的平均数。 (我正在做一些乐观的假设......)这不是“胜利”。

  

它有这么慢的原因吗?

是。在最佳情况下(大)TreeMap相对于(大)HashMap慢的原因是使用平衡二叉树的查找需要查看log2N树节点。通过约束,在最佳HashMap(良好的负载因子和无冲突热点)中,查找涉及1个哈希码计算并查看O(1)哈希链节点。

注意:

  1. TreeMap使用提供平衡树的二叉树组织,因此O(log2N)是最差的查找时间。
  2. HashMap性能取决于散列函数和密钥空间的冲突率。在最糟糕的情况下,所有密钥都在同一个哈希链上,HashMapO(N)个查找。

答案 2 :(得分:3)

树图总是平衡的。每次向树中添加节点时,都必须确保所提供的比较器按顺序完成节点。您没有指定的大小,因为树图是为平滑排序的节点组而设计的,并且可以轻松遍历节点。

Hashmap需要为您存储的内容提供足够大小的可用空间。我的教授一直告诉我,它需要的空间量是你在hashmap中存储的对象或任何东西的5倍。因此,从最初创建Hashmap开始指定大小可以提高hashmap的速度。否则,如果你有更多的对象进入哈希映射而不是你计划的,那么hashmap必须“调整大小”。

(为拼写编辑)

答案 3 :(得分:2)

我错误地认为应该能够设置TreeMap数组的初始大小吗?

是。它没有拥有数组。它有一棵树。