为啥哈希表在存储桶的数组上使用链表?
Posted
技术标签:
【中文标题】为啥哈希表在存储桶的数组上使用链表?【英文标题】:Why do hashtables use a linked list over an array for the bucket?为什么哈希表在存储桶的数组上使用链表? 【发布时间】:2012-11-15 18:07:00 【问题描述】:当一个值被哈希到相同的值时,它被添加到哈希值引用的链表中。为什么哈希表的实现使用链表而不是数组作为存储桶?
是不是因为一个数组在初始化时有一个预先确定的大小,所以当桶中添加太多元素时需要调整大小?
【问题讨论】:
【参考方案1】:是的:通常,这是因为数组具有预先确定的大小。桶不需要使用链表或数组;一些狡猾的实现使用另一个哈希表,然后使用链表或数组作为它的桶!
如果您使用数组,则哈希表对每个数组元素都有一个预先确定的大小。每个可能的存储桶都已分配,您的哈希表可能非常大。如果你有很多内存,或者你期望一个非常完整的哈希表,那可能没问题。您可以通过持有指向数组的指针并根据需要分配它来缓解这种情况。
一个数组可以被索引,所以你可以保持数组的排序。然后,如果它变大了,你可以进行二分搜索来找到你想要的键。
如果使用链表,则必须遍历链表以线性查找所需的匹配项。这不是太高效,但可以最大限度地减少内存使用量。
与所有数据结构问题一样,您必须考虑您将拥有哪些访问模式以及如何使用和填充结构;你想赢得哪些权衡,哪些是你不太在意的?
【讨论】:
【参考方案2】:他们没有。
声称“哈希表的实现”使用链表是一种过度概括。 Java 可以。许多其他语言没有。例如,Python 使用开放散列,请参阅此问题的答案,How are Python's Built In Dictionaries Implemented
一般来说,通用 API 的设计者面临着一个非常艰难的选择,因为他们不了解用户的用例。有不同的实现选择具有不同的权衡,例如,如果您只添加元素但从不删除,则适用的选择与经常变异的 hashmap 不同。等等。
【讨论】:
以上是关于为啥哈希表在存储桶的数组上使用链表?的主要内容,如果未能解决你的问题,请参考以下文章