【问题标题】:Java Map realizations asymptotic complexity (HashMap, LinkedHashMap, TreeMap)Java Map 实现渐近复杂度(HashMap、LinkedHashMap、TreeMap)
【发布时间】:2019-06-12 12:52:22
【问题描述】:

我正在尝试处理HashMapLinkedHashMapTreeMap 的渐近复杂性。在不同的网站和文章上平均写到get = O(1),最糟糕的是 - O(n)。 (如果所有键都添加到一个桶中)。

但是我看书Bruce Eckel thinking in java有一个比较的例子

如果您查看此数据,则它会输出O(n)

我完全糊涂了。谁能解释Map 实现的渐近复杂性-HashMapLinkedHashMapTreeMap,至少对于getput? (也许有一篇好文章,把所有的东西都说清楚并放在一起?)

编辑

put 方法最感兴趣。因为当某个大小出现时resize()ArrayList 类似。

【问题讨论】:

  • 老实说,我不知道这些没有任何单位的数字应该告诉我什么。它们甚至看起来都不一致。此外,HashMapTreeMap 具有根本不同的时间复杂度,因此一次性要求它们是没有意义的。

标签: java algorithm collections hashmap time-complexity


【解决方案1】:

它被称为摊销O(1),意思是在一段时间内有很多条目并且你经常这样做get。您似乎也缺乏对O(1) 的理解——这意味着,它是不变的。如果我向 HashMap 添加更多条目 - 检索条目所需的时间是相同的,无论是 HashMap 中的 10 或 1000 万个条目,并考虑到 hashCode 已实现并且没有有一个return 1 的虚拟实现(例如,条目将被放入同一个存储桶中)。

在某些情况下确实会发生调整大小,但它甚至与ArrayList 的做法相差甚远。 ArrayList 只会使内部数组更大,总是HashMap 会将内部存储桶加倍到某个点 (see when exactly here),之后它将某个存储桶转换为 Tree,从而加快搜索速度 - 这是在 java-8 中添加的。

【讨论】:

  • HashMap 的调整大小操作将使桶的数量增加一倍,这反过来会降低在特定桶中需要树的可能性,而不是增加它。将存储桶的列表转换为树可能会发生在 put 操作中,独立于调整大小操作。
  • @Holger resize 将加倍,直到达到TREEIFY_THRESHOLDMIN_TREEIFY_CAPACITY 的阈值,之后,该特定桶被转换为一棵树并保持这种方式(除非条目被删除到某一点);这是我的观点 vs 调整ArrayList 的大小,它总是会增加大小。我对您的第二点也有些困惑(“独立”让我感到困惑),因为 resize 将从 put 内部调用
  • 当容量翻倍时,每个旧桶的项目会根据它们的实际哈希码转移到两个新桶中。因此,在每个新桶中,至多与旧桶中的项目数量相同,但可能更少。所以提高容量可能会导致结果桶中的项目数低于UNTREEIFY_THRESHOLD,但不会高于TREEIFY_THRESHOLD,因为它之前没有高于它。你似乎太关心小地图会发生什么,但在讨论渐近时间复杂度时,小地图是无关紧要的。
  • @Holger 啊!现在我明白你的意思了,谢谢你的cmets
猜你喜欢
  • 2011-02-22
  • 2012-05-13
  • 2013-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多