散列查找--解决冲突的方法

常用的处理冲突的方法:开放定址法,分离链接法。

因为是期末复习(●ˇ∀ˇ●),浅浅地记个开放定址法的线性探测法和平方探测法;

例:

设关键字序列{47,7,29,11,9,84,54,20,30},散列表表长TableSize=13,散列函数为:h(key)=key mod 11。

萌新瞎补:

散列表表长:对于一串数,就看做一个整形数组来存这些数,TableSize就是数组的大小;

散列函数:咳咳,这是之前的知识啊!就是本来是这个数,通过一种关系变成了另外一个数,比如为了实现离散化操作。

ok,继续。

线性探测法:

见表:

关键字 47 7 29 11 9 84 54 20 30
散列地址 3 7 7 0 9 7 10 9 8
冲突次数 0 0 1 0 0 3 1 3 6

可见啊,有些关键字对应的散列地址有冲突!

线性 探测 上

所谓线性,就是对于原冲突散列地址+1再往散列函数搞搞,h(new)=(h(old)+1)%13,其实很显然就是往他右边看看,如果右边没有就在右边住下了,如果右边还有持续往右,但是注意,最右边的时候,本来式子就是取膜啊,所以就是往回看起,就是这么一步一步的探测,找空位子。

平均查找长度(ASL):就是一共找了几次然后除以关键字的个数。比如:上面的例子:ASL=(1+1+2+1+1+4+2+4+7)/9≈2.56;

平方探测法:

这个据说比线性好,我们能在线性探测法看到,如果连续一段都已经被占了,那么线性的话(也就是+1的话)有点慢啊。
这个时候,平方 探测  出场。
线性不是每次+1取膜么?平方就是如果“聚集”,我是加一个数k的平方,而且这个k会越来越大,而且线性只往右边(其实是往右的循环),平方是往两端,具体序列是:
+1^2,-1^2,+2^2,-2^2,+3^2,-3^2,...,+k^2,-k^2  这样的话找的更快啊!
有证据(略)表明:TableSize如果是4x+3(x是正整数)形式的素数,平方探测法就可以探查到整个散列表空间;
有一题譬如:PAT1078
题目是严格向右探测的:
贴一小段代码,当找不到的时候,注意+k^2 并取膜;
bool flag=false;
			int inc=1;
			while(inc<Size)
			{
				int tmp=(x+inc*inc)%Size;
				if(mp.find(tmp)==mp.end())
				{
					mp[tmp]=1;
					a[i]=tmp;
					flag=true;
					break;
				}
				inc++;
			}
			if(!flag) a[i]=-1;

OK,THAT'S ALL;



原文地址:https://www.cnblogs.com/keyboarder-zsq/p/6777480.html