散列作为常用 的数据结构,之前上课的时候书上没有太多的篇章有讲,因此专门复习一下
1、空间换时间
先看一个简单的问题:给出N个正整数,再给出M个正整数,求问这M个整数的每一个是否有在N中出现,其中N,M<10^5;
对于这类问题,最直观的就是对于每个M,遍历N,但是复杂度达到了O(N*M),显然复杂度过大
那么给出的解决方案就是以空间换取时间,即设定一个bool型数组boolTable[100010],其为真,表示N有x这个值;说明,boolTable需要提前初始化为false ,显然这样的复杂度为O(N+M),先通过N对boolTable更新值,再判断M是否出现,同样假如想判断出现多少次,只需要将bool数组更改为Int类型即可。
上面问题是直接将值作为数组的下标来对这个数的性质j进行统计。这是一个非常实用的空间换取时间的策略。
·
2、散列函数
但是对于大整数或者字符串来说,怎么将乱七八糟的元素转化成一个能够接受的范围?
那就是散列--【将元素通过一个函数转化为整数,使得该整数可以唯一的表示这个元素】,这个函数就是散列函数
在数据结构课程上,我学的是哈希函数,差不多咧
2.1 除留余数法
h(K)=K mod m
m是哈希表的长度,m最好是1.1n--1.5n的素数,n是存储数的个数,而不是数的范围
2.2 直接定址法
h(K)=K+C
2.3 数字分析法
3、冲突解决
对于不同的数key1、key2,有h(key1)==h(key2),那么我们说发生了冲突
3.1线性探测法
如果发生冲突,就找下一个位置+1
3.2 平方探测法
H(key)+1,H(key)-1,H(key)+4,H(key)-4,H(key)+9
3.3 链地址法
把所有h(key)相同的key用一个单链表连接,
4、字符串hash
上面都是学过的东西,对于key不是整数如何设计散列函数呢?
一个例子是二维坐标,假设一个P点(x,y),其中0<x,y<range,那么令H(p)=x*range+y
对于字符串来说,给出的解决方案是先将字符串转化为26/52(大小写)/62(加数字)进制,再转化为十进制作为散列值