【散列】散列表HashTable线性探测法类模板的实现

这篇博客探讨了散列表的冲突解决策略,包括线性探测法和平方探测法。线性探测法在装填因子低于0.5时有效,而平方探测法利用二次函数避免聚集。当表满一半时,再散列成为必要,通过创建新表并重新插入元素。代码示例展示了如何实现这些方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线性探测法

一般说来,对于不使用分离链接的散列表来说,其装填因子应该低于 λ=0.5,这样的表叫作探测散列表(probing hash table)。

如上图所示,当插入关键字68时,h(68)=68%11=2,与23冲突,于是被放入到下一个空闲位置4;插入11时,h(11)=0,与55冲突,向后寻找并存入空闲位置5。。。。只要表足够大,总能找到一个空闲位置,但花费的时间是相当多的。

可以看出,插入和不成功查找需要相同次数的探测,且成功查找应该比不成功查找平均花费较少的时间。

平方探测法

平方探测法是消除线性探测中一次聚集问题的冲突解决办法 – 冲突函数为二次的探测方法,流行的选择是f(i)=i2

如果使用平方探测,且表的大小是素数,那么当表至少有一半是空的时候,总能够插入一个新的元素。

再散列

对于使用平方探测的开放定址散列法(open addressing hashing),若散列表装的太满,则操作的运行时间将消耗过长,且插入操作可能失败,这可能发生在有太多的删除和插入混杂的场合。
此时,一种解决办法是建立另外一个大约两倍大的表(而且使用一个相关的新散列函数),扫描整个原始散列表,计算每个(未删除的)元素的新散列值并将其插入到新表中。

再散列可以用平方探测以多种方法实现:

(1)只要表满到一半就再散列
(2)只有当插入失败时才再散列
(3)途中策略:当散列表到达某一特定的装填因子时进行再散列。

代码实现

#include<vector>
#include<string>
int nextPrime(int n);

//使用函数对象,让散列函数只用对象作为参数并返回适当的整形量
template<typename T>
class _hash
{
   
public:
	size_t operator()(const T& key) {
   
		size_t hashVal = 0;

		T tmp = key;
		while (tmp > 0) {
   
			hashVal = 37 * hashVal + tmp % 10;
			tmp /= 10;
		}
		return hashVal;
	}
};

template<>
class _hash<std::string>
{
   
public:
	size_t operator()(const std::string & key) {
   
		size_t hashVal = 0;

		for (char ch : key) 
			hashVal = 37 * hashVal + ch;

		return hashVal;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhugenmi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值