【发布时间】: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 中复制粘贴来回答(事实证明是这样的),这使得它成为一个研究得很差的问题。