【问题标题】:Hashtable separate chaining in CC中的哈希表单独链接
【发布时间】:2022-01-10 07:29:30
【问题描述】:

我正在用 C 语言构建一个散列表,使用开放散列(分离链)来存储单词。我不关心存储具有相同哈希键的单词的顺序。

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

我不清楚两个方面:

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

我看到它是双向的,但后者似乎更受欢迎。但是,前者对我来说似乎更快,因为我只需要将第一个项目的指针设置为我的新项目,并将其指针设置为 null。我不必进行任何指针追踪(即遍历我的链表,直到找到空指针)。

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

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

【问题讨论】:

    标签: c hash hashtable


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-01-14
      • 2020-08-24
      • 1970-01-01
      • 2018-10-29
      • 1970-01-01
      • 2012-05-06
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      相关资源
      最近更新 更多