【问题标题】:Worse case time complexity put/get HashMap更糟糕的时间复杂度 put/get HashMap
【发布时间】:2011-12-31 00:59:23
【问题描述】:

当其键的哈希码始终相等时,Hashmap 的最坏情况时间复杂度是多少。

在我的理解中:由于每个键都有相同的哈希码,它总是会去同一个桶并循环通过它来检查 equals 方法,所以对于 get 和 put 时间复杂度应该是 O(n),对吗?

我在看这个HashMap get/put complexity,但它没有回答我的问题。

同样在这里Wiki Hash Table 他们指出插入的最坏情况时间复杂度是 O(1) 而获取 O(n) 为什么会这样?

【问题讨论】:

    标签: java hashmap


    【解决方案1】:

    插入的时候,放在桶的什么地方都没有关系,所以你可以把它插入到任何地方,因此插入是O(1)

    查找时间为 O(n),因为您必须遍历每个对象并验证它是否是您要查找的对象(如您所说)。

    【讨论】:

    • 为什么是这个 O(n) ?我们在查看项目之前获取 HashMap 的桶索引,因此我们不需要查看整个桶,而是查看指定的桶及其元素(条目对象)。
    • 如果所有内容的哈希码为 1,那么“指定的存储桶及其元素”就是地图中的所有内容。
    • 您需要进行查找才能进行插入。 ergo O(n)
    【解决方案2】:

    是的,在最坏的情况下,您的哈希映射将退化为链表,并且您将遭受 O(N) 的查找以及插入和删除的惩罚,这两者都需要查找操作(感谢 cmets指出我之前回答中的错误)。

    有一些方法可以减轻最坏情况的行为,例如使用自平衡树而不是链表来解决桶溢出 - 这将最坏情况的行为减少到 O(logn) 而不是 O( n)。

    【讨论】:

    • 所以put不需要循环遍历桶来检查equals,如果它返回true然后replace否则只是添加?导致复杂度为 O(n)?
    • 此语句错误“如果将新对象添加到Bucket的头部,则可以实现O(1)插入”。原因是您必须遍历链表以确定该键是否已存在于 Map 中。假设我正在插入 1,3,4,3 。现在,当我在地图的索引 3 处插入元素时,它会与其他元素落入同一个桶中,现在我的地图已经包含 3(索引 1 处的元素)所以这 3 应该不再插入。为了检查 3 是否已经存在,我需要遍历列表。
    • 对于好的哈希函数,最坏的情况总是logn,请参阅stackoverflow.com/questions/4553624/hashmap-get-put-complexity/…我的回答
    【解决方案3】:

    在开放散列中,您将有一个链表来存储具有相同散列码的对象。所以: 例如,您有一个大小为 4 的散列表。 1) 假设您要存储哈希码 = 0 的对象。然后该对象将映射到索引 (0 mod 4 = ) 0。 2) 然后你又想放另一个 hashcode = 8 的对象。这个对象将被映射到索引 (8 mod 4 = ) 0,因为我们记得索引 0 已经被我们的第一个对象填充了,所以我们必须放第二个在第一个旁边。

    [0]=>linkedList{object1, object2}
    [1]=>null
    [2]=>null
    [3]=>null
    

    3) 搜索的步骤是什么? 1、你要对key对象进行hash,假设它的hashcode是8,所以你会被重定向到index (8 mod 4 = ) 0,那么由于同一个索引中存储的对象不止一个,我们必须搜索将列表中的所有对象逐一存储,直到找到匹配的对象或直到列表末尾。由于该示例有 2 个对象存储在同一个哈希表索引 0 中,并且搜索到的对象位于链表的末尾,因此您需要遍历所有存储的对象。这就是为什么最坏的情况是 O(n)。 当所有存储的对象都在哈希表的同一个索引中时,会发生最坏的情况。所以它们将存储在一个链表中,我们(可能)需要遍历所有这些链表才能找到我们搜索的对象。

    希望对您有所帮助。

    【讨论】:

      【解决方案4】:

      在 Java 8 的 HashMap 实现中(当键类型实现 Comparable 时):

      使用平衡树处理频繁的 HashMap 冲突:在高哈希冲突的情况下,这会将最坏情况下的性能从 O(n) 提高到 O(log n)。

      来自here

      【讨论】:

      • 正确,但仅当键类型实现 Comparable 时。
      【解决方案5】:

      HasMap 复杂度

      
                Best.  Avg.   Worst
        Search  O(1)   O(1)   O(n)
        Insert  O(1)   O(1)   O(n)
        Delete  O(1)   O(1)   O(n)
      

      希望这会有所帮助

      【讨论】:

        猜你喜欢
        • 2020-10-11
        • 2017-05-17
        • 1970-01-01
        • 1970-01-01
        • 2021-04-17
        • 2017-09-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多