哈希表、哈希函数、哈希冲突与解决

目录

    • 哈希函数的构建:

哈希表:通过关键码来映射到值的一个数据结构;
哈希函数:键与值映射的一个映射关系;

哈希函数的构建:

常用方法
1、直接寻址法:f(x) = kx+b (k、b都是常数) ,一旦确定了哈希函数,那么添加、获取元素都需要通过这个哈希函数;
2、除留余数法:f(x) = x%k (k是常数,k <= m (m为存储位置长度)) ;

其他几种方法:

方法名 说明 适合情况
直接寻址法 f(key) = key 或者 f(key) = a*key + b 事先知道关键字的分布情况,查找表较小且连续
数字分析法 根据实际问题自己创造一个能将关键字散列表的各位置的散列函数 事先知道关键字的分布情况且关键字的若干位分布较均匀
平方取中法 先把关键字平方,然后取得到的结果的中间几位当哈希值 不知道关键字的分布,而位数又不是很大的情况
折叠法 把关键字分成较小的几组数据,求和,取得到结果的后几位当哈希值 不知道关键字的分布,且关键字位数较多情况
除留余数法 f(key) = key%n ( n≤m )m为表长(容量),n 为不大于 m 的素数,或是不含 20 以下的质因子 一般都可以,所以是最常用的方法
随机数法 f(key) = random(key) 关键字长度不等的时候

哈希冲突:由于哈希函数构造不当,通过同一个哈希函数把两个不同的数哈希到了同一个位置;m != n ---->f(m) = f(n);哈希冲突无法避免,但可以减少(改变合适的哈希函数还是有可能发生哈希冲突,但冲突的数据会大大减少)。

解决哈希冲突:
常用方法
1、链地址法:数组+链表(散列表)
2、探测法:① 线性探测:p(i) = i+c ②非线性探测:p(i) = i+random();

其他几种方法:

方法名 说明 注解
开放地址法 一旦发生了冲突,就去寻找下一个地址,只要散列表足够大,空的地址总能够找到,找到则记录存入 找地址的方法有:线性探测法、二次探测法、随机探测法
再散列函数法 发生散列地址冲突时,换一个散列地址计算,相信总会有一个函数是可以解决冲突的 这种方法可以使关键字不产生聚集,但增加了计算时间
链地址法 数组+链表 这种方法绝不会出现找不到地址的情况,但是查找时要遍历链表
公共溢出区法 就是把冲突的关键字放在一个新表中 这个方法的查找性还是比较高的

你可能感兴趣的:(java基础,数据结构)