我正在尝试弄清楚Java基本集合操作的复杂度(使用大O符号)。类似于这个问题关于C++语言。
以下是我所知道的,根据常识:
列表
ArrayList
- 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)
- contains(E e) O(n)
- list concatenation (addAll) O(n)
LinkedList
- 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) 删除指定元素或位置的元素
- contains(E e) O(n) 判断是否包含指定元素
- list concatenation (addAll) O(1) 链表合并
集合
HashSet和LinkedHashSet
- add(E e) O(1)(常数时间复杂度)
- remove(E e) O(1)(常数时间复杂度)
- contains(E e) O(1)(常数时间复杂度)
- 使用迭代器查找/获取元素 O(n)(线性时间复杂度)
TreeSet
- add(E e) O(log n)(对数时间复杂度)
- remove(E e) O(log n)(对数时间复杂度)
- contains(E e) O(log n)(对数时间复杂度)
- addAll O(n log n)(n乘以对数时间复杂度)
- 使用迭代器查找元素 O(n)(线性时间复杂度),或者实现二分查找可达到 O(log n)(对数时间复杂度)
地图
HashMap和LinkedHashMap
- put(K key, V value) O(1)
- get(K key) O(1)
- remove(E e) O(1)
- containsKey(Object key) O(1)
- containsValue(Object value) O(n)
- putAll O(n)
- 使用迭代器查找/获取元素 O(n) 或者可能是 O(log n),与
TreeSet
相同
TreeMap
- put(K key, V value) O(log n)
- get(K key) O(log n)
- remove(E e) O(log n)
- containsKey(Object key) O(log n)
- containsValue(Object value) O(n)
- putAll O(n log n)
- 使用迭代器查找/获取元素 O(n)
问题: 这个说法正确吗?
ArrayList.Add(E e)
的摊销常数时间是恒定的。 - MAV