【问题标题】:Double Hashing vs Linear Hashing双散列与线性散列
【发布时间】:2015-06-20 18:07:09
【问题描述】:

我正在编写只需要整数的双哈希表。

unsigned int DoubleHashTable::HashFunction1(unsigned int const data)
{
   return (data % GetTableSize());
}

unsigned int DoubleHashTable::HashFunction2(unsigned int const data, unsigned int count)
{
   return ((HashFunction1(data) + count * (5 - (data % 5)) % GetTableSize()));
}

并尝试使用 SetData() 将数据插入表中

void DoubleHashTable::SetData(unsigned int const data)
{
   unsigned int probe = HashFunction1(data);

   if (m_table[probe].GetStatus())
   {
      unsigned int count = 1;
      while (m_table[probe].GetStatus() && count <= GetTableSize())
      {
         probe = HashFunction2(data, count);
         count++;
      }
   }

   m_table[probe].Insert(data);
}

将 100 个整数项放入大小为 100 的表中后,表显示一些索引留为空白。我知道,这将需要 O(N) ,这是最坏的情况。我的问题是,即使需要最坏的搜索时间,项目也应该插入没有空白空间的表中,对吗?我找不到我的功能的问题。

附加问题。有众所周知的哈希算法,双重哈希的目的是尽可能减少冲突,H2(T)是H1(T)的备份。但是,如果众所周知的散列算法(如 MD5、SHA 等,我不是在谈论安全性,只是众所周知的算法)更快且分布良好,为什么我们需要双重散列?

谢谢!

【问题讨论】:

  • 双重散列有时很有用,因为没有完美的散列函数。我们能做的最好的就是尽量减少碰撞。另外,你在散列什么整数?
  • 只使用 rand() 函数生成无符号整数类型的随机数。我的表大小是 101(质数),并且将 101 个项目放入表中。
  • 我建议插入大量随机数,比如 1000 * tableSize,看看每个槽的填充情况。分布应该差不多。
  • 我尝试插入总是大于 10000 的随机数,rand() % 10000 + 10000。结果剩下 5 个空格。 (表的大小是 101)实际上,我无法遵循您的评论,大数字有什么区别?在我的脑海里,如果没有问题,桌子总是要满的。
  • 我发现了问题,HashFunction2() 返回的索引号错误,大于表的大小...(当表的大小为 11 时,它返回 13)我理解双散列的概念和线性散列与非常好的计算之间的区别。 H2(T) 有规则吗?我现在用的H2(T)是从网上找的,刚看了某大学CS课的ppt文件...

标签: hash hashtable linear-probing double-hashing


【解决方案1】:

在测试哈希函数时,可能会与某些病态输入(=破坏哈希函数的输入)发生高度冲突。这些输入可以通过反转哈希函数来发现,这可能导致某些attacks(这是real concern,因为互联网路由器的哈希表空间有限)。即使没有对手,这种哈希表在某些输入之后的查找时间也会增加,甚至在最坏的情况下变成线性。

双散列是一种解决散列冲突的方法,以try解决病态输入的线性增长问题。 Linear probingopen addressing 是受欢迎的选择。但是,在这些情况下,输入的数量必须远低于表大小,除非您的哈希表可以动态增长。

回答您的第二个问题(现在您已经自行修复了代码),简而言之,双哈希更适合小型哈希表,而单哈希更适合大型哈希表。

【讨论】:

  • 谢谢德雷克斯!现在我可以理解双重哈希和线性哈希的原因了。我知道我的第二个哈希函数返回的表索引不正确,并且当我放置与表大小相同的项目时会产生空格。如何设计双重散列的散列函数,使其比线性散列更好地工作? (我已经为线性和链接的开放寻址做过,我只是使用(表的数据百分比大小)来查找索引,但我需要一个用于双重哈希的第二个哈希函数。)我仍在寻找用于双重哈希的好的哈希函数,但很难找到。
  • 我从你的回答中了解到,如果给定输入的数量(几乎)与表的大小相同但在接近负载因子时表没有扩展的情况下没有完美的哈希函数到 70%,哈希表开始失败?如果我的理解是正确的,那么当表的使用量超过其标准百分比时,各种哈希表(除非需要链接)总是会增大其大小? (如 70% ~ 75%)
  • 这里有一些带有动画的更多探测和双重哈希函数的例子。走过去很有趣。 algoviz.org/OpenDSA/Books/OpenDSA/html/HashCImproved.html
  • 此外,即使有一个巨大的哈希链表,如果哈希函数是已知的,那么总是有一种计算冲突的方法会减慢查找速度。我最喜欢的例子是路由器hash table attack (PDF)
猜你喜欢
  • 1970-01-01
  • 2011-12-25
  • 1970-01-01
  • 1970-01-01
  • 2015-01-28
  • 1970-01-01
  • 2020-03-17
  • 1970-01-01
  • 2012-11-10
相关资源
最近更新 更多