【问题标题】:What is asymptotic complexity for CRUD operations on basic Java containers什么是基本 Java 容器上的 CRUD 操作的渐近复杂度
【发布时间】:2013-08-19 23:32:18
【问题描述】:

我试图弄清楚对 Java 基本集合的操作有哪些复杂性(使用大 O 符号)。与 C++ 语言的 question 类似。

这是我所拥有的,使用常识:

列表

数组列表

  • add(E e) O(1)
  • add(int index, E e) O(n)
  • set(int index, E element O(1)
  • get(int index) O(1)
  • remove(E e) remove(int index) O(n)
  • 包含(E e) O(n)
  • 列表连接(addAll)O(n)

链表

  • add(E e) O(1)
  • add(int index, E e) O(n)
  • set(int index, E element O(n)
  • get(int index) O(n)
  • remove(E e) remove(int index) O(n)
  • 包含(E e) O(n)
  • 列表连接(addAll)O(1)

套装

HashSet 和 LinkedHashSet

  • add(E e) O(1)
  • 删除(E e) O(1)
  • 包含(E e) O(1)
  • 使用迭代器O(n)查找/获取元素

树集

  • add(E e) O(log n)
  • 删除(E e) O(log n)
  • 包含(E e) O(log n)
  • addAll O(n log n)
  • 在实现二分查找时使用迭代器 O(n)O(log n) 查找元素

地图

HashMap 和 LinkedHashMap

  • put(K键,V值)O(1)
  • get(K 键) O(1)
  • 删除(E e) O(1)
  • containsKey(对象键) O(1)
  • 包含值(对象值)O(n)
  • putAll O(n)
  • 使用迭代器 O(n)O(log n) 查找/获取元素,与 TreeSet 相同

树状图

  • put(K key, V value) O(log n)
  • get(K 键) O(log n)
  • 删除(E e) O(log n)
  • containsKey(对象键) O(log n)
  • 包含值(对象值)O(n)
  • putAll O(n log n)
  • 使用迭代器O(n)查找/获取元素

注意:基于散列的集合假定设计良好的散列函数在 O(1) 中,否则在 O(n)

问题: 这是正确的吗?

【问题讨论】:

  • ArrayList.Add(E e) 有一个摊销常数时间。
  • @MAV 很多adds 不是这样吗? (我的意思是,上面提到的更多,不仅仅是ArrayList)
  • 很难说这些都是正确的或没有一个是正确的,尤其是考虑到像remove() 这样的函数将取决于它们的实现方式。我认为这个问题的范围很广。
  • @Kᴇʏsᴇʀ 很有可能。我还没有阅读所有提到的集合的文档。
  • -1 这个问题困扰着我,因为它基本上相当于“我懒得阅读文档,有人可以阅读我的版本并告诉我我是否碰巧是对的吗?”我想了一会儿关于这个否决票,但最后完全缺乏任何研究把我推倒了。如果问题是关于一个特定的集合,引用文档并且不确定它的某个方面,那将是一回事;但是这个问题可以通过从 javadocs 中复制粘贴来回答(事实证明是这样的),这使得它成为一个研究得很差的问题。

标签: java big-o


【解决方案1】:

有关这方面的最佳知识来源是文档。以下是我可以通过一两次快速搜索找到的内容。

列表

ArrayList

sizeisEmptygetsetiteratorlistIterator 操作在恒定时间内运行。 add 操作在摊销常数时间内运行,即添加 n 个元素需要 O(n) 时间。所有其他操作都以线性时间运行(粗略地说)。

LinkedList

所有操作都按照双向链表的预期执行。索引到列表中的操作将从开头或结尾遍历列表,以更接近指定索引的为准。

根据我对双向链表的记忆,我会说您的“常识​​假设”是正确的。

套装

HashSet

假设散列函数将元素正确地分散在桶中,此类为基本操作(添加、删除、包含和大小)提供恒定的时间性能。迭代这个集合需要的时间与 HashSet 实例的大小(元素的数量)加上支持 HashMap 实例的“容量”(桶的数量)之和成正比。

LinkedHashSet

与 HashSet 一样,它为基本操作(添加、包含和删除)提供恒定时间性能,假设哈希函数在桶中正确地分散元素。由于维护链表的额外费用,性能可能略低于 HashSet,但有一个例外:迭代 LinkedHashSet 所需的时间与集合的大小成正比,而不管其容量如何。 HashSet 的迭代可能会更昂贵,需要的时间与其容量成正比。

TreeSet

此实现为基本操作(添加、删除和包含)提供有保证的 log(n) 时间成本。

地图

HashMap

此实现为基本操作(get 和 put)提供恒定时间性能,假设哈希函数将元素正确地分散在桶中。对集合视图的迭代需要的时间与 HashMap 实例的“容量”(桶的数量)加上其大小(键值映射的数量)成正比。

LinkedHashMap

与 HashMap 一样,它为基本操作(添加、包含和删除)提供恒定时间性能,假设哈希函数在桶中正确地分散元素。性能可能只是略低于 HashMap,...

TreeMap

此实现为 containsKeygetputremove 操作提供有保证的 log(n) 时间成本。

如果某些方法没有提到,请尝试查找该特定方法。如果文档中没有提到运行时间,则可能取决于实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    相关资源
    最近更新 更多