散列函数及冲突处理方法

1 散列

将元素通过一个函数转换为整数,使得该整数可以尽量唯一地代表这个元素,其中这个转换函数称为散列函数H

2 散列函数

2.1 直接定址法

恒等变换H(key)=key,或是线性变换H(key)=a*key+b

2.2 平方取中法

取key的平方的中间若干位作为hash值(很少用)

2.3 除留余数法

把key除以一个数mod得到的余数作为hash值的方法,H(key)=key%mod。

通过这个方法可以把很大的数转换为不超过mod的整数,这样就可以把它作为可行的数组下标。

当mod是一个素数时,H(key)能尽可能覆盖[0,mod)范围内的每一个数

2.3.1 线性探查法

如果表中下标为H(key)的位置已经被某个其他元素使用了,那么就检查下一个位置H(key)+1是否被占,如果还是被占,就继续检查下一个位置(hash值不断加1).如果检查过程中超过了表长,那么就回到表的首位继续循环,直到找到一个可以使用的位置。

2.3.2 平方探查法

H(key)+1^2、H(key)-1^2、H(key)+2^2、H(key)-2^2、H(key)+3^2......

如果H(key)+k^2超过了表长TSize,那么就把H(key)+k^2对表长TSize取模

2.3.3 链地址法(拉链法)

把所有H(key)相同的key连接成一条单链表。

设定一个数组Link,范围是Link[0]-Link[mod],Link[h]存放H[key]=h的一条单链表。

一般不需要自己实现上面解决冲突的方法,可以使用map来直接使用hash的功能

example1 将大写字母字符串转换为二十六进制

int hashFunc1(char S[],int len){
	int id=0;
	for(int i=0;i

example2 将大小写字母字符串转换为二十六进制

int hashFunc2(char S[],int len){
	int id=0;
	for(int i=0;i='A'&&S[i]<='Z')
			id=id*52+S[i]-'A';
		else if(S[i]>='a'&&S[i]<='z')
			id=id*52+S[i]-'a'+26;
	}
	return id;
}

example3 字母+数字字符串

int hashFunc3(char S[],int len){
	int id=0;
	for(int i=0;i

example4 查找n中查询字符串m出现的次数

const int maxn=100;
char S[maxn][5],temp[5];
int hashTable[26*26*26+10]={0};

int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=0;i

 

你可能感兴趣的:(算法学习)