由于我正在解决时间复杂问题,因此我一直在搜索oracle Java类库,以了解列表,地图和类中使用的一些标准方法的时间复杂性。 (更具体地说,ArrayList,HashSet和HashMap)
现在,在查看HashMap javadoc page时,他们只是真正谈论get()
和put()
方法。
我仍然需要知道的方法是:
remove(Object o)
size()
values()
我认为remove()
将与get()
,O(1)
具有相同的复杂性,假设我们没有具有相同hashCodes的巨型HashMap等等......
对于size()
,我还假设O(1)
,因为HashSet也没有订单,因此size()
方法的复杂度为O(1)
。
我不知道的是values()
- 我不确定这种方法是否会以某种方式“复制”HashMap,时间复杂度为O(1)
,或者它是否具有迭代HashMap,使复杂性等于HashMap中存储的元素数量。
感谢。
答案 0 :(得分:21)
来源通常很有用:http://kickjava.com/src/java/util/HashMap.java.htm
remove:
O(1)size:
O(1)values:
O(n)(通过迭代器遍历)答案 1 :(得分:5)
删除代码(如在HashMap的rt.jar中)是:
/**
* Removes and returns the entry associated with the specified key
* in the HashMap. Returns null if the HashMap contains no mapping
* for this key.
*/
final Entry<K,V> removeEntryForKey(Object key) {
int hash = (key == null) ? 0 : hash(key.hashCode());
int i = indexFor(hash, table.length);
Entry<K,V> prev = table[i];
Entry<K,V> e = prev;
while (e != null) {
Entry<K,V> next = e.next;
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k)))) {
modCount++;
size--;
if (prev == e)
table[i] = next;
else
prev.next = next;
e.recordRemoval(this);
return e;
}
prev = e;
e = next;
}
return e;
}
显然,最坏的情况是O(n)。
答案 2 :(得分:1)
您可以随时查看源代码并自行检查
无论如何...我曾经检查过源代码,我记得的是有一个名为size
的变量,它始终包含HashMap
中的项目数,因此size()
是{{1 }}
答案 3 :(得分:1)
搜索:O(1 + k / n)
插入:O(1)
删除:O(1 + k / n)
其中k是否。添加到同一LinkedList的碰撞元素(k个元素具有相同的hashCode)
插入是O(1)因为你在LinkedList的头部添加元素。
在给定良好的hashFunction的情况下,分摊时间复杂度接近于O(1)。如果您太关注查找时间,请尝试使用BinarySearchTree而不是Java的Default实现来解决冲突,即LinkedList
答案 4 :(得分:1)
只是想针对上面的评论添加一条评论,声称最坏的情况是 HashMap 在删除和搜索中可能会达到 O(n),这在我们谈论 Java HashMap 实现时永远不会发生。
对于有限的数量(低于 64 个条目),hashMap 是由数组备份的,所以在足够不幸的情况下,但仍然不太可能,它是线性的,但渐近地说,我们应该说在更坏的情况下,HahsMap O(logN)
答案 5 :(得分:0)
HashMap插入,删除的平均时间复杂度平均为O(1)
个恒定时间。
也就是说,在最坏的情况下,java需要O(n)
的时间进行搜索,插入和删除。
请记住,HashMap的时间复杂度显然取决于 loadfactor n/b
(哈希表中存在的条目数乘以哈希表中存储桶的总数),以及哈希函数映射每个插入内容的效率如何。高效是指哈希函数可能将两个非常不同的对象映射到同一个存储桶(这称为冲突)。解决冲突的方法有很多种,称为冲突解决技术,例如
Java使用链接和重新哈希处理来处理冲突。
束缚缺点:在最坏的情况下,删除和搜索将执行操作O(n)
。可能会发生所有对象都映射到特定存储桶的情况,该存储桶最终会扩展到O(n)
链。
重新计算缺点 Java使用(n/b)
的有效负载因子0.75
作为重新计算的限制(据我所知,知识链显然需要平均{{1 }}。如果使用O(1+(n/b))
<0.99(带有重新哈希处理),则为恒定时间)。当表很大时,重新哈希处理就变得不可用了,在这种情况下,如果我们将其用于实时应用程序,则响应时间可能会成问题。
那么,在最坏的情况下,Java HashMap花费n/b
的时间来搜索,插入和删除。