繁体   English   中英

C 中的哈希表单独链接

[英]Hashtable separate chaining in C

我正在 C 中构建一个哈希表,使用开放哈希(单独的链接)来存储单词。 我不关心使用相同 hash 键存储单词的顺序。

目前,我有一个指向带有哈希表( struct item * arr )的结构( struct dict * d )的指针。 更具体地说,这个表是一个包含一个单词( char * word )和一个指针( struct item * next )的项目数组( struct item )。

我不清楚两个方面:

1.碰撞后将单词链接在一起时(插入新项目),我应该将元素插入到链表的开头还是末尾?

我已经看到它以两种方式完成,但后者似乎更受欢迎。 然而,前者对我来说似乎更快,因为我只需要将我的第一个项目的指针设置为我的新项目,并将其指针设置为 null。 我不必进行任何指针追踪(即遍历我的链表,直到找到 null 指针)。

2.我的哈希表应该是一个指向项目(结构项目)的指针数组,还是只是一个项目数组(结构项目),就像我所做的那样?

换句话说,是否应该将特定 hash 密钥的第一个项目插入第一个单元格(一个空单元格),还是应该在该单元格中已经有一个指针,我们将指向这个新项目?

对于 1. 是否将 append 预先添加到列表中并不重要。 如果您保持较小的负载,则链很短,并且您不会看到访问性能有任何明显差异。 如果您保持表较小并且负载变高,您可能需要研究不同的策略。 访问模式可能很重要。 例如,如果您更有可能查找最近插入的值,则希望它们位于列表的前面,因此最好在前面添加。 但是对于 hash 表,如果可以的话,最好保持较小的负载,然后就没有关系了。

对于 2. 也可以。 如果你的表是一个指针数组,NULL 用于空链,一个简单的递归链表实现会很好地工作。 使您的列表函数将列表作为参数,并使插入和删除返回一个新列表。 参数或返回值都可以是 NULL。 然后执行类似tbl[bin] = insert(tbl[bin], val)tbl[bin] = delete(tbl[bin], val)的操作。 如果链很短,您不必太担心递归开销。 在任何情况下,如果它只是前置,则不需要递归来查找值或插入,所以它只是删除你无论如何都没有得到尾递归的地方。 拥有链接数组的好处是,您可以在列表的前面获得一个虚拟元素,这通过避免空列表的特殊情况来简化非递归列表实现,或者您避免跟随指针访问第一个查找 bin 后链中的元素。 但是,对于后者,您需要一种方法来区分空链和具有一个元素的链。 这几乎不值得,如果你想避免在链表上跳跃,开放寻址或其他一些冲突策略可能会更好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM