HashMap方法的时间复杂度

时间:2011-01-02 10:29:43

标签: java methods hashmap time-complexity

由于我正在解决时间复杂问题,因此我一直在搜索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中存储的元素数量。

感谢。

6 个答案:

答案 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哈希表中存在的条目数乘以哈希表中存储桶的总数),以及哈希函数映射每个插入内容的效率如何。高效是指哈希函数可能将两个非常不同的对象映射到同一个存储桶(这称为冲突)。解决冲突的方法有很多种,称为冲突解决技术,例如

  • 使用更好的哈希函数
  • 打开地址
  • Chaining e.t.c

Java使用链接重新哈希处理来处理冲突。

束缚缺点:在最坏的情况下,删除和搜索将执行操作O(n)。可能会发生所有对象都映射到特定存储桶的情况,该存储桶最终会扩展到O(n)链。

重新计算缺点 Java使用(n/b)的有效负载因子0.75作为重新计算的限制(据我所知,知识链显然需要平均{{1 }}。如果使用O(1+(n/b)) <0.99(带有重新哈希处理),则为恒定时间)。当表很大时,重新哈希处理就变得不可用了,在这种情况下,如果我们将其用于实时应用程序,则响应时间可能会成问题。

那么,在最坏的情况下,Java HashMap花费n/b的时间来搜索,插入和删除。