源自<<数据结构与算法分析c++>>
几种散列算法
int hash(const string &key, int tableSize)
{
int hashValue = 0;
for (int =0; i<key.length(); i++)
hashValue += key[i];
return hashValue % tableSize;
}
int hash(const string &key, int tableSize)
{
return ( key[0] + 27*key[1] + 27^2*key[2]) % tableSize;
}
int hash(const string &key, int tableSize)
{
int hashValue = 0;
for (int =0; i<key.length(); i++)
hashValue += 37*hashValue + key[i];
hashValue %= tableSize;
if( hashValue < 0)
hashValue += tableSize;
return hashValue ;
}
解决冲突
1.分离链接法: 把具有相同映射的元素保存到一个链表中。
应用:
HashObj通过hash函数得到vector下标号(链表号),再再对应链表作insert/search/remove操作。
(类似的,我们还可以使用二叉树、甚至另外一个散列表。但我们期望的是如果散列表大而且散列函数好,那么所有链表都应该很短。因此不值得去进行任何复杂的尝试。)
2. 探测法
线性探测:发生冲突时,从下一个单元开始逐个查找空位
平方探测:发生冲突时,从下一个n^2单元开始查找空位 (第一次冲突1^2,第二次冲突2^2,第三次冲突3^2)
双散列:发生冲突时,用第二个散列函数查找空位
3. 再散列
当表的元素填的太满,发生冲突的概率很大,那么意味着操作的运行时间消耗过长,甚至插入操作可能失败。此时解决的方法是再建立一个大约两倍大的表。将原始散列表中的元素通过新的散列函数映射到新表中。