【问题标题】:HashMap || How hashcode lookup is constant哈希图 ||哈希码查找如何保持不变
【发布时间】:2016-03-10 16:47:58
【问题描述】:

在哈希图中,哈希码如何查找常量O(1)

我们知道,hashmap 在内部会创建一个数组来保存给定键值的哈希码。 hashmap利用散列函数生成散列码。我们还知道,对于查找,hashmap 需要恒定的时间(假设没有冲突)。每当我们请求哈希映射来查找给定键的值时,它首先计算存储桶位置(即与给定键的哈希码映射的数组的索引)。然后它获取值。我知道第二部分将花费恒定的时间。但是第一部分呢?如何查找哈希码常量的数组索引?尤其是当哈希图有数百万个值时?

我的 StackOverflow 搜索在 hashmap 上发现了多个问题,但他们大多回答了我问题的第二部分,而不是第一部分。

我找到的链接很少:

  1. Why hashmap lookup is O(1) i.e. constant time?
  2. Can hash tables really be O(1)

我还发现了javarevisited.blogspot的用户发布的这个问题:

嗨,贾文, 需要澄清我最近的一个面试问题。 用于搜索和排序更喜欢的 Collection 数据结构:ArrayList 或 LinkedList。 我提到 ArrayList 将是检索操作的选择,因为它实现了随机访问,而链表将是插入/删除的更好选择,因为它保存了节点前后的指针。 我的后续问题,所以您的意思是说使用包含 100 万条记录的 Arraylist 进行检索更快?我说如果索引已知,我们可以使用 contains() 并获取值。但请在真实动态案例中澄清这 100 万个场景,即在不知道索引的情况下。 ArrayList 会更快吗?

【问题讨论】:

  • big-O 时间的全部意义在于描述算法如何在理想机器上针对n 的大值进行扩展。你能澄清一下你的问题是什么吗?
  • "即使它真正的价值更低" ???
  • 感谢彼得的回复。我的主要问题是哈希码查找(获取存储桶位置的第一部分)如何保持恒定时间。
  • @ Yves Daoust,假设哈希映射仅包含 10 个值,那么它可以。我想了解对于非常大的 hahmap,hashcode 值的查找是如何保持不变的。
  • 不,一点也不,我只是想弄清楚你还需要什么信息。对我来说,其他问题的答案似乎相当清楚。我不明白为什么您认为如果“使用”更多内存位置,内存查找需要更长的时间。你说“显然”,但实际上并非如此。

标签: java algorithm hash hashmap


【解决方案1】:

您似乎对数据结构有误解。创建数组时,该数组会在内存中保存一个空间。该空间的大小是数组中元素的数量乘以每个元素的大小

因此,一个包含八个 2 字节数字的数组将是 16 个字节。

假设我们想要第四个索引处的数字:我们可以查找这个数字无需迭代,因为我们对数据结构的性质有所了解:特别是它从哪里开始以及每个的大小元素。在这种情况下,我们知道如果我们将 2 个字节乘以 3(3 = 4 - 1:记住我们是从零开始索引的),我们得到 6,并且我们想要的元素的开头是数组开头之后的 6 个字节。

哈希图通常由这种性质的数组支持。所需数组元素开始位置的计算更为复杂,但它可以在无需迭代的情况下完成。因此它是O(1)。在数组位置中找到的值是检索到的 在内存中的实际位置。

  • 使用提供的键计算后备数组中的位置(存储值的内存位置)的函数是一个常数时间操作。
  • 读取第一步计算的内存位置是一个常数时间的操作。
  • 读取存储在第二步中读取的位置的内存位置是一个常数时间的操作。

因此,整个操作在恒定时间内发生。

【讨论】:

    【解决方案2】:

    当你找到哈希码时,你也可以找到常数时间的单元格数

    cellIndex = hash(X) % array.length
    

    所以你有 const 时间

    【讨论】:

      【解决方案3】:

      在给定索引处的数组查找是在恒定时间内完成的。实际上,它是一个简单的地址计算(base + index * stride),然后是间接的。

      【讨论】:

      • 所以基本上你想说hascode不过是一个内存地址?
      • 不,哈希码是一个索引。根据索引,您可以通过简单的线性变换计算地址。
      猜你喜欢
      • 2020-06-07
      • 2012-09-16
      • 1970-01-01
      • 2013-03-21
      • 1970-01-01
      • 2021-09-05
      • 1970-01-01
      • 2012-03-05
      • 2017-12-01
      相关资源
      最近更新 更多