【问题标题】:Set time and speed complexity设置时间和速度的复杂性
【发布时间】:2011-07-09 12:47:37
【问题描述】:

我正在复习算法和数据结构,并有一些问题和陈述希望您检查。

ArrayList - O(1) (size, get, set, ...), O(n) - 添加操作。
LinkedList - 所有操作O(1) (包括 add() ),但检索第 n 个元素除外,即 O(n)。我假设 size() 操作也在 O(1) 中运行,对吧?

TreeSet - 所有操作 O(lg(N))。 size() 操作需要 O(lg(n)),对吧?

HashSet - 如果应用适当的哈希函数,所有操作 O(1)。
HashMap - 所有操作 O(1),类似于 HashSet。

非常欢迎任何进一步的解释。提前谢谢你。

【问题讨论】:

  • 如果你有这么神奇的HashSet,为什么还需要ArrayList?
  • @Stas:因为 List 和 Set 不是一回事,也因为常数因素仍然可以有很大的不同......
  • @Stas:该命令仅让您了解操作的扩展方式。它不会告诉你因素,例如HashSet 可以比 ArrayList 慢很多倍,并且没有 get()/set() 方法。
  • @Peter Lawrey, @Jon Skeet 你是对的。这就是为什么我认为这种同情具有误导性。
  • @Stas:如果您不了解大 O 表示法,它们只会产生误导。我没有看到这里有人被误导或混淆的证据。

标签: java algorithm collections


【解决方案1】:

ArrayList.add() 摊销 O(1)。如果该操作不需要调整大小,则为 O(1)。如果它确实需要调整大小,则为 O(n),但随后会增加大小,以便在一段时间内不会发生下一次调整大小。

来自Javadoc:

加法运算在摊销常数时间内运行,即添加 n 个元素需要 O(n) 时间。所有其他操作都以线性时间运行(粗略地说)。与 LinkedList 实现相比,常数因子较低。

就性能分析而言,该文档通常非常适合 Java 集合。

散列算法的 O(1) 不仅仅是应用“正确”散列函数的问题 - 即使使用非常好的散列函数,您仍然可能碰巧遇到散列冲突。 通常复杂度是O(1),但如果所有哈希碰巧发生碰撞,它当然可以是O(n)。

(此外,将散列的成本计算为 O(1) - 实际上,例如,如果您正在对字符串进行散列,则每次调用 hashCode 的字符串长度可能为 O(k)。)

【讨论】:

  • +1:同样,LinkedList 是 O(1),只要它不触发 GC,它更有可能这样做。 ;)
  • @Suraj: GC = "垃圾收集" (?)
  • @Suraj,LinkedList.add() 总是创建一个对象,它比 ArrayList 消耗更多的内存。因此,虽然在纸面上 ArrayList 会有 LinkedList 没有的延迟,但它不太可能触发一些最长的延迟。
  • @peter,我不会说它本身会导致 GC,直到你真正在你的 jvm 中创建一个数据库,但你仍然有一个观点
  • 关于HashSet 和HashMap.add 的另一点:它们的复杂性也受散列函数的影响(可能是O(k),其中k 是字符串长度)。
【解决方案2】:

访问以下链接。它将帮助您消除疑虑。

【讨论】:

    猜你喜欢
    • 2012-08-14
    • 2017-06-04
    • 2013-09-12
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 2021-03-10
    相关资源
    最近更新 更多