如何创建哈希表

9
我想在继续之前提一下,我已经查看了这个网站以及其他网站上询问同样问题的其他问题。我希望能得到一个好的答案,因为我的目标有两个:
  1. 首先,我想学习如何创建哈希表。
  2. 其次,我发现Stack Overflow上的很多答案往往假设某种程度的知识,而这种知识对于新手来说常常是不存在的。话虽如此,我希望在自己弄清楚之后,编辑我的主要信息,包括更深入的过程解释。

进入正题:

据我目前的理解,哈希表是一个数组列表(或类似的数据结构),它希望尽可能地减少冲突,以保持其受人称赞的O(1)复杂度。以下是我的当前过程:

因此,我的第一步是创建一个指针数组:

Elem ** table;
table = new Elem*[size];//size is the desired size of the array

我的第二步是创建一个哈希函数(非常简单的函数)。

int hashed = 0;
hashed = ( atoi( name.c_str() ) + id ) % size;
//name is a std string, and id is a large integer. Size is the size of the array.

我的第三步是创建一个用于检测碰撞的东西,这是我目前所处的部分。

以下是一些伪代码:

while( table[hashedValue] != empty )
    hashedValue++

else
    put in the list at that index.

虽然有点不太雅致,但我仍处于“这是什么”的阶段。请包容我的困惑。

还有其他需要补充的吗?我有遗漏或者做错了什么吗?

谢谢。


1
看起来还可以,哈希值索引到一个固定数组中,每个数组元素是实际值的列表。 - Kerrek SB
3个回答

4
处理找不到空插槽和调整表格大小的问题。

1

你缺少一个 Elem 的定义。这并不是微不足道的,因为它取决于你想要一个 链式 哈希表还是探测哈希表。


哦,抱歉,我有一个定义,只是没有提供。它是一个链表。 - Joshua
@Joshua:假设您不想存储重复项,那么碰撞检测只是遍历该列表的问题。 - Fred Foo

0
哈希函数对于相同的数据会生成相同的值。然而,您的冲突检查会修改该值,这意味着哈希值不仅取决于输入,还取决于哈希映射中其他元素的存在。这很糟糕,因为您几乎永远无法通过名称实际访问您放置的元素,只能通过迭代地遍历映射来访问。
其次,您的冲突检查容易受到溢出/范围错误的影响,因为您只是增加了哈希值,而没有根据映射的大小进行检查(虽然如我之前所说,您甚至不应该这样做)。

我猜我没有提供足够的信息,抱歉。我要哈希的对象有一个私有名称和ID,因此它们在对象中始终存在。 - Joshua
@Joshua:那不是我想说的意思。在你的碰撞检查中,如果你计算得到的位置不为空(只要下一个位置也不为空),你就会改变哈希值。这意味着,在哈希图的负载情况下,对于相同的数组大小,如果之前插入的另一个元素产生了相同的哈希值(即发生冲突),该元素可能会被插入到不同的位置。这将无法让你通过插入它时的相同键来访问该元素。 - Xeo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接