【问题标题】:Should I use TreeSet or HashSet?我应该使用 TreeSet 还是 HashSet?
【发布时间】:2016-04-20 22:31:55
【问题描述】:

我有大量字符串,我需要按排序顺序打印唯一的字符串。 TreeSet 按排序顺序存储它们,但每次插入的插入时间为 O(Logn)。 HashSet 需要 O(1) 时间来添加,但是我必须获取集合列表,然后使用需要 O(nLogn) 的 Collections.sort() 进行排序(我假设这里没有内存开销,因为只有字符串的引用将被复制到新集合中,即列表)。是否可以公平地说总体上任何选择都是相同的,因为最终总时间会相同?

【问题讨论】:

标签: java sorting collections hashset treeset


【解决方案1】:

这取决于你看起来有多近。是的,在任何一种情况下,渐近时间复杂度都是 O(n log n),但常数因子不同。因此,并不是一种方法可以比另一种方法快 100 倍,但一种方法肯定有可能是另一种方法的两倍。

对于程序的大多数部分,因子 2 完全无关紧要,但如果您的程序实际上在该算法中花费了大部分运行时间,那么实现这两种方法并衡量它们的性能将是一个好主意.

【讨论】:

    【解决方案2】:

    测量是要走的路,但如果你只是在理论上谈论并忽略排序后的读取,那么考虑字符串数 = x:

    哈希集x * O(1) 添加操作 + 1 O(n log n) (其中 n 是 x)排序操作 = 大约 O(n + n log n) (好吧,这太简单了,但是..)

    树集x * O(log n)(其中 n 从 1 增加到 x)+O(0) 排序操作 = 大约为 O(n log (n/2))(也过于简单化了,但是..)

    继续过于简单化,O(n + n log n) > O(n log (n/2))。也许 TreeSet 是要走的路?

    【讨论】:

    • 插入树集中的是x * O(log n),而不是x * O(n log n)。真正归结为实现细节,比如散列集的散列函数有多快,Collection.sort()的排序算法有多快(这也取决于数据的分布)。
    • 啊,这不是 OP 所说的。这扭曲了我的归纳:)
    【解决方案3】:

    如果您区分字符串总数 (n) 和唯一字符串数 (m),您将获得两种方法的更详细结果:

    哈希集+排序:O(n) + O(m log m)

    树集:O(n log m)

    所以如果 n 比 m 大很多,使用散列集和排序结果应该会稍微好一点。

    【讨论】:

      【解决方案4】:

      您应该考虑哪些方法会更频繁地执行,并以此为基础做出决定。

      除了HashSetTreeSet,您还可以使用LinkedHashSet,它为排序集提供了更好的性能。如果您想了解更多关于它们在性能上的差异,我建议您阅读6 Differences between TreeSet HashSet and LinkedHashSet in Java

      【讨论】:

      • LinkedHashSet 没有为排序集提供更好的性能。它只是跟踪插入顺序(以内存为代价)。
      • 是的,就其元素的访问时间而言,它比TreeSet。当然,它的性能并不比HashSet 好,但你不能保证最后一个的任何顺序
      猜你喜欢
      • 2015-10-26
      • 2020-10-10
      • 1970-01-01
      • 1970-01-01
      • 2017-06-13
      • 2018-09-05
      • 1970-01-01
      • 2015-12-29
      • 2015-10-16
      相关资源
      最近更新 更多