我们正在学习数据结构和算法类中的哈希表,而且我无法理解单独的链接。
我知道基本前提:每个存储桶都有一个指向包含键值对的节点的指针,每个节点都包含指向当前存储桶的迷你链接列表中下一个(潜在)节点的指针。这主要用于处理碰撞。
现在,为简单起见,假设哈希表有5个桶。假设在创建适当的哈希表实例后,我在main中编写了以下代码行。
myHashTable["rick"] = "Rick Sanchez";
myHashTable["morty"] = "Morty Smith";
让我们假设我们正在使用的任何哈希函数恰好为字符串键rick
和morty
生成相同的桶索引。假设桶索引是索引0,为简单起见。
因此,在我们的哈希表中的索引0处,我们有两个值为Rick Sanchez
和Morty Smith
的节点,无论我们决定将它们放入哪个顺序(第一个指向第二个)。 / p>
当我想显示rick
的相应值时,这里的代码为Rick Sanchez
,散列函数将生成桶索引为0。
如何确定需要返回哪个节点?我是否循环遍历节点,直到找到其密钥与rick
匹配的那个?
答案 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