Algorithm 具有开放寻址、非延迟删除(无逻辑删除)的哈希表

Algorithm 具有开放寻址、非延迟删除(无逻辑删除)的哈希表,algorithm,hashtable,Algorithm,Hashtable,除了线性探测(但仍然是开放寻址)之外,是否可以在开放寻址哈希表中使用冲突解决方案进行非延迟删除(无逻辑删除) 对于线性探测,有一个算法。我想知道,当我们使用二次探测/双散列时,是否有一种非延迟删除算法?对于任何具有任何值的非线性探测算法,都没有这种算法。它适用于线性探测,因为探测序列是可逆的。如果探测序列是可逆的,那么所有元素都遵循相同的探测序列(尽管它们将根据初始散列从序列的不同位置开始)。因此,二次散列不会阻止探测收敛,从而导致以线性探测为特征的已用节点的群集 换句话说,任何允许通过沿探测序

除了线性探测(但仍然是开放寻址)之外,是否可以在开放寻址哈希表中使用冲突解决方案进行非延迟删除(无逻辑删除)


对于线性探测,有一个算法。我想知道,当我们使用二次探测/双散列时,是否有一种非延迟删除算法?

对于任何具有任何值的非线性探测算法,都没有这种算法。它适用于线性探测,因为探测序列是可逆的。如果探测序列是可逆的,那么所有元素都遵循相同的探测序列(尽管它们将根据初始散列从序列的不同位置开始)。因此,二次散列不会阻止探测收敛,从而导致以线性探测为特征的已用节点的群集


换句话说,任何允许通过沿探测序列向后移动未删除元素来删除的探测算法,其对负载系数的敏感性与线性探测相同,没有线性探测提供的参考位置的优势。

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

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
函数删除(键):布尔值
i:=查找槽(键)
如果不是插槽[i],则使用
return false//表中没有键
j:=i
环
j:=(j+1)模数槽
如果表已满100%,则使用插槽[j]。或j=i//
断环
k:=散列(槽[j].key)模num\u槽
if(j
在您发布的链接中,它说“上面的O(1)remove方法只能在具有单槽步进的线性探测哈希表中使用。”@亚历克斯莱因:这对我来说很奇怪。这种方法是用于线性探测的,所以它当然只适用于线性探测。我试着想出一些办法,虽然这个问题很难解决,但它似乎不是不可能的。也许用二次探测是不可能的,但也许用其他探测方法也是可能的。