Hash
一、什么是hash
这里有个问题:
有20000个数,20000次询问。每个数的范围为 0~20000,可以怎么做?
桶标记
把这个问题改一下:
有20000个数,20000次询问。每个数的范围为 0~109,可以怎么做?
也还可以排序+二分
再改一下:
有20000个数,20000次询问。每个数的范围为 0~109,存在插入和删除操作,可以怎么做?
桶标记
排序+二分
于是便有了 ——hash。
hash的定义:通过一个函数F( ),将原本较大的数、字符串、甚至结构体计算为一个较小的数。得到的数叫做哈希值。
哈希值组成的数组叫hash表。
hash的本质其实是映射。将空间大的映射为空间小的。
二、hash怎么用
hash的关键是 构造哈希函数。
举个例子:
例1
给定n个数,范围-1000~1000,查询某个数。
hash函数:
F(key)=key+1000
例2
给定n个数,范围-109~109,查询某个数。
hash函数:
F(key)=(key+109) % mod
mod一般为哈希表大小以内的最大的质数。
为了理解这句话,我们得了解什么是哈希冲突。
当我们%一个数时,我们会发现,会有一些数的哈希值是相同的,这就叫哈希冲突。(当然,冲突是要处理的,这在下一章讲)
所以mod要尽可能大。
为什么mod要为质数?
证明:如果mod为非素数,有很多约数,数据中存在q满足gcd(mod,q)=d,
即存在mod=a*d,q=b*d,则q%mod=q-mod*(q/mod)=q-mod*(b/a),
其中b/a的范围为[0,b]的整数,而m