散列表和单独链接:您如何知道从存储桶列表中返回哪个值?

时间:2017-09-22 16:53:56

标签: data-structures hashmap computer-science

我们正在学习数据结构和算法类中的哈希表,而且我无法理解单独的链接。

我知道基本前提:每个存储桶都有一个指向包含键值对的节点的指针,每个节点都包含指向当前存储桶的迷你链接列表中下一个(潜在)节点的指针。这主要用于处理碰撞。

现在,为简单起见,假设哈希表有5个桶。假设在创建适当的哈希表实例后,我在main中编写了以下代码行。

myHashTable["rick"] = "Rick Sanchez";
myHashTable["morty"] = "Morty Smith";

让我们假设我们正在使用的任何哈希函数恰好为字符串键rickmorty生成相同的桶索引。假设桶索引是索引0,为简单起见。

因此,在我们的哈希表中的索引0处,我们有两个值为Rick SanchezMorty Smith的节点,无论我们决定将它们放入哪个顺序(第一个指向第二个)。 / p>

当我想显示rick的相应值时,这里的代码为Rick Sanchez,散列函数将生成桶索引为0。

如何确定需要返回哪个节点?我是否循环遍历节点,直到找到其密钥与rick匹配的那个?

1 个答案:

答案 0 :(得分:1)

要解决哈希表冲突,就是这样,要将项目放入哈希表中哈希值与另一个冲突,你最终会减少到数据结构的映射。支持哈希表实现;这通常是一个链表。在发生冲突的情况下,这是哈希表结构的最坏情况,您将最终使用O(n)操作来获取链表中的正确项。就是这样,如你所说的循环,将使用匹配的密钥搜索项。但是,如果您有像搜索平衡树这样的数据结构,那么它可以是O(logN)时间,就像Java8实现一样。

正如JEP 180: Handle Frequent HashMap Collisions with Balanced Trees所说:

  

主要思想是一旦哈希桶中的项目数量   超过某个阈值,该桶将从使用a切换   链接到平衡树的条目列表。在高哈希的情况下   碰撞,这将改善O(n)到O(n)的最坏情况性能   O(log n)。

     

此技术已在最新版本中实施   java.util.concurrent.ConcurrentHashMap类,也是定型的   作为JEP 155的一部分包含在JDK 8中。该代码的部分将   被重用于在HashMap和LinkedHashMap中实现相同的想法   类。

我强烈建议您始终关注一些现有的实施方案。说一下,你可以看一下Java 7的实现。这将提高您的代码阅读技能,这几乎更重要,或者您比编写代码更经常。我知道这是更多的努力,但它会得到回报。

例如,看一下Java 7中的HashTable.get方法:

[Activity(Label = "@string/application_name")]

在这里,我们看到if((e.hash == hash)&& e.key.equals(key))试图找到带有匹配键的正确项目。

以下是完整的源代码:HashTable.java