正如@Dai 在 cmets 中指出的那样,这取决于您使用的是哪种哈希表。 (事实证明,有很多不同的方法来制作哈希表,没有一种数据结构是哈希表的“工作方式”!)
其中一个更常见的哈希表使用一种称为封闭寻址的策略。在封闭寻址中,每个项目都根据其哈希码映射到一个槽,并与所有其他也最终进入该槽的项目一起存储。然后通过查找要查找的存储桶来完成查找,然后检查该存储桶中的所有项目。在这种情况下,具有相同哈希码的任何两个项目将最终在同一个桶中。 (不过,它们不能真正占据那个桶中的同一个位置。)
另一种构建哈希表的策略是使用一种称为开放寻址的方法。这是一系列不同的方法,它们都基于以下思想。我们要求表中的每个槽最多存储一个元素。和以前一样,要进行插入,我们使用元素的哈希码来确定将其放入哪个插槽。如果插槽是空的,那就太好了!我们把元素放在那里。如果那个槽已满,我们就不能把物品放在那里。相反,使用一些可预测的策略,我们开始查看其他插槽,直到找到一个空闲的插槽,然后将项目放在那里。 (执行此操作的最简单方法,线性探测,通过在所需槽之后尝试下一个槽,然后是下一个,等等,如果需要,环绕。)在这个系统中,因为我们不能在同一个位置存储多个项目,不,具有相同哈希码的两个元素不必(事实上,不能!)占据同一个位置。
最近一种越来越流行的散列策略是 cuckoo 散列。 在 cuckoo 散列中,我们维护一些单独的散列表(通常是两个或三个),其中每个槽只能容纳一项。要插入一个元素,我们尝试将它放在第一个表中由其哈希码确定的位置。如果那个位置是免费的,那就太好了!我们把物品放在那里。如果没有,我们将那里的项目踢出并尝试将该项目放在下一个表中。这个过程一直重复,直到最终一切都停止了,或者我们陷入了一个循环。像开放寻址一样,该系统防止多个项目存储在同一个槽中,因此具有相同哈希码的两个元素可能会去不同的地方。 (cuckoo hashing 有多种变化,其中每个表槽可以存储固定但少量的项目,在这种情况下,您可以在同一个位置有两个具有相同哈希码的项目。但不能保证。)
还有一些其他的散列方案我没有在这里描述。 FKS 完美散列通过使用两层散列表来工作,遵循封闭寻址的思路,但会定期重建整个表以确保没有一个存储桶过度过载。 可扩展散列使用类似树的结构来增长溢出的桶,一旦它们变得太满。 Hopscotch hashing 是线性探测和链式散列之间的混合体,可以很好地处理并发性。但希望这能让您了解您使用的哈希表类型如何影响您的问题的答案!