访问/查找HashMap存储桶(存储桶中没有值)的时间复杂度是多少?

时间:2018-11-28 17:02:09

标签: java data-structures hashmap

假设我们有两个不同的hashMap,分别是map1和map2。

  • map1有1000个条目和1000个存储桶。
  • map2具有999999个条目和999999个存储桶。

假设我们有一个对象“ obj1”,其哈希码为“ 1234”,并将该对象作为键同时放在map1和map2(值“ xyz”)中。

在map2中查找“ obj1”值是否需要更多时间? 从map1和map2访问obj1的时间复杂度是否仍为O(1)?

2 个答案:

答案 0 :(得分:3)

resetAuth中查找存储桶总是O(1),与容量(存储桶数)无关。

假设您的HashMap的哈希码为obj11234567的核心不是要搜索正确的存储桶(如TreeMap那样),而是要计算其位置,并立即使用该数字访问存储桶。那就是哈希码进入游戏的地方。

计算为HashMap,结果数字给出了obj.hashCode() % capacity的索引。

  • 对于小型哈希图,其为bucketsArray = 1234567 % 1000,这意味着相关的存储段为567

  • 对于大个子来说,它是bucketsArray[567] = 1234567 % 999999,结果是234568

除法值的计算所需的时间是恒定的,与值无关。具有给定索引的数组的访问时间也是固定的,因此为O(1)。

我们只是在谈论寻找水桶。如果存储桶包含多个条目,则线性搜索将完成哈希映射访问,即O(K),其中K为存储桶中条目的(平均?最大?)个数。

答案 1 :(得分:3)

我想最好用代码和图表来回答。我们都知道它是什么(单向)哈希函数。基本上,它接受任意输入并返回数字(在Java中为int,但并非总是如此)。 Java中的int有32位。这意味着它可以在-2,147,483,648和2,147,483,647之间。存在的每个Java堆上的每个对象都可以计算其哈希值(使用java.util.Object类中的方法),并且它必须处于该间隔内。

现在让我们假设我们有3个对象。

21234 = obj1.hashCode();  
623424 = obj2.hashCode();
23124432 = obj3.hasCode();

,我们想将它们添加到具有200个存储桶的hashMap中。 (这不是我在这里输入的有效的Java代码)

public class MyHashMap {
    private final Buckets[] buckets = new Buckets[200];

    public boolean add(Object object){
        int resultModulo = object.hashCode() % 200;
        buckets[buckets].add(object);
    } 
}

现在争取最后的和平。对于我们的对象,resultModulo将为34(21234),24(623424),32(23124432)。计算的数量不会超过200。

数组被分配为连续的内存。只是指针数组(64位)而不是实际对象。所以bucktes []看起来像这样

0xB80000xB80020xB80670xC1101 ....
1      2      3      4       .... 200

所以当您的代码调用bucket [34],bucket [24],bucket [32]时,硬件的作用是这样的:

  mov eax, bucktes[ecx*19] 
  ; eax now contains the pointer to the
  ; 19 element in the array
  ; this is a one clock instruction

所以这就是为什么有多少个桶都没关系的原因。