微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

哈希表链表中项目的删除时间

如何解决哈希表链表中项目的删除时间

我目前正在阅读 Clrs 的书,并研究如何在那里定义哈希表,当谈到开放哈希和使用链来解决冲突时,有一段文字写道:

If the hash table supports deletion,then its linked lists should be doubly linked
so that we can delete an item quickly. If the lists were only singly linked,then to
delete element x,we would first have to find x in the list T[h(x.key)] so that we
Could update the next attribute of x’s predecessor. With singly linked lists,both
deletion and searching would have the same asymptotic running times.)

我不明白为什么会这样(或更具体地说是如何),这不是一个关于为什么当你知道元素是双倍时从链表中删除的问题链表,我想我应该说清楚...

这与如何实际知道位置有关,因此双向链表可以产生这种差异,因为查看散列删除代码(如下),密钥用于生成导致正确位置的散列可以找到链接列表的位置的数组索引,但如何将其准确地转换为项目的链接列表中的实际位置?

CHAINED-HASH-DELETE(T,x)
1 delete x from the list T[h(x.key)]

在我看来,只对指向链表的键进行哈希处理,因此在任何一种情况下,仍然需要搜索列表以找到当前被删除的实际值?

我确定有一个简单的答案,但我不清楚!

解决方法

在我看来,只对指向链表的键进行哈希处理,因此在任何一种情况下,仍然需要搜索列表以找到当前被删除的实际值?

没错,当有人要求 erase(key) 时,双向链表没有任何好处,因为即使遍历单链表也很容易擦除。

不过,像(伪代码)这样​​的代码还是很常见的……

if (iterator i = hash_table.find(key)) {
    do_something_with(*i);
    if (should_erase(*i))
        erase(i);
}

这里,迭代器 i 可以是指向双向链表中某个节点的指针,因此每个解引用操作 *i 访问与该节点关联的元素/值不必重复哈希表桶查找或双向链表搜索的任何部分。

如果它随后决定 erase(i),则迭代器无需再次搜索即可识别要擦除的节点。

如果你只使用了一个单向链表,那么对于erase(iterator),为了避免重新搜索,它需要存储一个指向前一个元素的下一个指针的指针(这实际上是GCC的C++哈希表容器所做的) )。如果它只存储它(以保持迭代器更小),那么要访问迭代器逻辑寻址的元素,它必须首先查找前一个元素的下一个指针,然后再查找逻辑寻址的节点:这不是非常有效。如果它存储逻辑寻址元素的地址和前一个元素(或者更具体地说是它的下一个指针),那么迭代器就会变成更大的对象,同时也具有潜在的内存使用和性能影响。尽管如此,您还是为列表中的每个链接保存了一个“前一个”指针,而且元素数量多于迭代器的可能性更大。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。