我正在编写只使用整数的双哈希表。
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和其他,我不是在谈论安全性,只是众所周知的算法)更快更好地分发,为什么我们需要双重哈希?
谢谢!
答案 0 :(得分:0)
测试散列函数时,可能会与某些病理输入发生高冲突(=破坏散列函数的那些)。这些输入可以通过反转哈希函数来发现,哈希函数可以导致某些attacks(这是real concern,因为互联网路由器的哈希表空间有限)。即使没有对手,在特定输入之后这样的哈希表的查找时间可以增长,甚至在最坏的情况下变为线性。
双重散列是一种解决哈希冲突的方法,以尝试来解决病理输入的线性增长问题。 Linear probing或open addressing是受欢迎的选择。但是,在这些情况下,输入的数量必须远远低于表的大小,除非您的哈希表可以动态增长。
回答你的第二个问题(现在你已经自己修复了代码),简而言之,双哈希更适合小哈希表,单哈希更适合大型哈希表。