数据结构之hash表
哈希函数
- hash函数就是根据key计算出存储地址的映射,而哈希表是基于哈希函数将key存储在一块连续存储空间的一种查找表。(长度为m)
- 地址index = H(key)
哈希函数的构造
- 直接定址法 f ( k e y ) = a ∗ k e y + b f(key) = a*key+b f(key)=a∗key+b
- 数字分析法 123 ∗ ∗ ∗ ∗ [ ∗ ∗ ∗ ∗ ] 123****[****] 123∗∗∗∗[∗∗∗∗]
- 平方取中法 123 4 2 = 15 [ 227 ] 56 1234^2 = 15[227]56 12342=15[227]56
- 折叠法 897 + 654 + 321 + 000 = 1 [ 962 ] 897 + 654 +321 + 000 = 1[962] 897+654+321+000=1[962]
- 除留余数 f ( k e y ) = k e y m o d p p < = m f(key) = key\;\;mod\;\;p\;\;\;p<=m f(key)=keymodpp<=m
- 随机数法 f ( k e y ) = r a n d o m ( k e y ) f(key) = random(key) f(key)=random(key)
hash函数设计因素
- 计算散列地址所需要的时间
- 关键字的长度
- 散列表的大小
- 关键字分布是否均匀,是否有规律可循
- 设计的hash函数在满足以上条件的情况下尽量减少冲突
哈希冲突
- 即不同key值产生相同的地址, H ( k e y 1 ) = H ( k e y 2 ) H(key_1)=H(key_2) H(key1)=H(key2)
哈希冲突的解决方案
-
开放地址法 H i ( k e y ) = ( H ( k e y ) + d i ) m o d m H_i(key)=(H(key)+d_i)\;mod\;m Hi(key)=(H(key)+di)modm
1)线性探测 d i = 1 , 2 , 3 , 4 , . . . , m − 1 d_i= 1,2,3,4, ..., m-1 di=1,2,3,4,...,m−12)平方探测 d i = 1 2 , − 1 2 , 2 2 , − 2 2 , . . . , − ( m / 2 ) 2 di=1^2,−1^2, 2^2,−2^2, ..., -(m/2)^2 di=12,−12,22,−22,...,−(m/2)2
3)随机探测
-
再散列法
准备若干个hash函数,如果使用第一个hash函数发生了冲突,就使用第二个hash函数,第二个也冲突,使用第三个…… -
链地址法
哈希表由存储数据和后面一个指针组成,指针指向冲突的数据 -
公共溢出区法
建立一个溢出表存储空间,专门存放冲突的数据。此种方法适用于数据和冲突较少的情况。
hash表查找的ASL因素
- 选用的hash函数
- 选用的处理冲突的方法
- hash表的饱和度,装载因子 α=n/m (n表示实际装载数据长度 m为表长)