###哈希
哈希算法理解为一种将很大的数据块经过哈希计算,用一个很小的字符串来标识这个很大的数据块
对应的<key,value>
模型
key表示计算的哈希值,value表示存放的数值
对应可以实现 key = func(value) 的函数称为哈希函数
一般情况都是采用value % length
计算哈希值
很明显的一般的数据结构不会太大,这样计算的哈希值的方法就不能保证每一个value
对应的key
都是不重复的,就出现的哈希冲突的问题。
####1.哈希冲突
出现多个不同的数据(value) 计算得到的哈希值(key)相同的情况,称为哈希冲突
####2.如何解决哈希冲突
**(a)开放定址法 (闭散列) **
生成一个Hash序列 H1 ,H2, H3, H4…
第一个冲突了,就继续下一个
H0 = value % length
Hi = (H0 + di) % lenght
- 线性探测再散列
di = 1,2,3,4,…(也是用到最多的方法)
线性探测容易产生“聚集”现象。当表中的第i、i+1、i+2的位置上已经存储某些关键字,则下一次哈希地址为i、i+1、i+2、i+3的关键字都将企图填入到i+3的位置上,这种多个哈希地址不同的关键字争夺同一个后继哈希地址的现象称为“聚集”。聚集对查找效率有很大影响。 - 平方探测再散列
di = 1^2 , 2^2, 3^2…
二次探测能有效避免“聚集”现象,但是不能够探测到哈希表上所有的存储单元,但是至少能够探测到一半。 - 随机探测再散列
di =伪随机数产生的 di
散列因子
用来描述哈希表的密集程度
a = 元素个数 / 哈希表长度
a 越大,产生冲突的概率就越大,a越小,空间浪费就大,散列因子一般控制在0.7~0.8左右
(b)链地址法 (开散列、哈希桶)
将存在哈希冲突的元素组织成链表,哈希表中存放该链表的链首地址
(c)再哈希
采用多个哈希函数的方法,如果使用第一个哈希函数计算的key值冲突了,就采用第二个哈希函数进行,依次类推。这样就要计算多次,查找的时候同样
(d)建立公共溢出区
另外开辟一块空间,将哈希表分为基本表和溢出表两部分,存在哈希冲突的数据存放再溢出表部分,这种方法若是哈希冲突严重,则效率很低。
###位图
用每一个比特位的 0/1 来表示是否存在,一般用来判断数字是否存于一堆数字中
###波隆过滤器
用来判断字符串是否存在于一长串字符串中。因为冲突率比较大,一般用再哈希的方法解决冲突