【问题标题】:Hash table with open addressing, non-lazy delete (without tombstones)具有开放寻址、非延迟删除(无墓碑)的哈希表
【发布时间】:2019-03-31 17:20:47
【问题描述】:

是否可以在具有冲突解决而不是线性探测(但仍然是开放寻址)的开放寻址哈希表中进行非延迟删除(没有墓碑)?

使用线性探测,有一个算法here。我想知道,当我们进行二次探测/双重哈希时,是否有非延迟删除的算法?

【问题讨论】:

  • 在您发布的链接中,它说“上述 O(1) 删除方法仅适用于单槽步进的线性探测哈希表。”
  • @AlexReinking:这对我来说很奇怪。该方法适用于线性探测,因此当然只能用于线性探测。而且我试图想出一些东西,虽然这个问题很难,但似乎并非不可能。也许二次探测是不可能的,但也许用其他探测方法是可能的。

标签: algorithm hashtable


【解决方案1】:

对于任何具有任何价值的非线性探测算法,都没有这样的算法。它适用于线性探测,因为探针序列是可逆的。如果探测序列是可逆的,则所有元素都遵循相同的探测序列(尽管根据初始哈希,它们将在序列中的不同位置开始)。所以二级散列并没有阻止探测收敛,导致使用节点的聚类,这是线性探测的特征。

换句话说,任何允许通过沿探针序列向后移动未删除元素来删除的探测算法将具有与线性探测相同的负载因子敏感度,而没有线性探测提供的参考局部性优势。

【讨论】:

    【解决方案2】:

    纯删除删除的问题是空槽可能会导致以后的搜索在找到真正在表中的项目之前终止。如果您维护一个计数器,给出在任何插入之前进行的最大探测次数,并且仅在此探测次数之后终止每个失败的搜索,那么您可以通过简单地从其插槽中删除项目来删除 - 但当然失败的搜索会更昂贵。

    【讨论】:

      【解决方案3】:

      wiki 页面上的算法令人困惑且不完整:这里有一个更好的版本,优化了检查 k 是否超出范围 [i, j),认为 j 可能被环绕:

      function remove(key): boolean
          i := find_slot(key)
          if not slot[i].used
              return false // key is not in the table
          j := i
          loop
              j := (j + 1) modulo num_slots
              if not slot[j].used or j = i // if table was 100% full
                  breakloop
              k := hash(slot[j].key) modulo num_slots
              if (j < i) xor (k <= i) xor (k > j)
                  slot[i] := slot[j]
                  i := j
          endloop
          slot[i].used := false
          num_slots := num_slots - 1
          return true
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-15
        • 1970-01-01
        • 2011-02-03
        • 2011-11-17
        • 2023-04-08
        • 1970-01-01
        • 2015-06-04
        • 2012-02-25
        相关资源
        最近更新 更多