散列的英文单词是Hash,Hash也译作哈希,是音译,本人以前误以为是人名。
定义
通过某种特定的函数/算法(称为散列函数/算法)将要检索的项(Key)与用来检索的索引(index/Hash Value)(称为散列,或者散列值)关联起来,生成一种便于搜索的数据结构(称为散列表)。散列算法也被用来加密存在数据库中的密码(password)字串,由于散列算法所计算出来的散列值(Hash Value)具有不可逆(无法逆向演算回原本的数值)的性质,因此可有效的保护密码。
有定义可知,散列主要用于两方面:信息检索和信息安全。另外,散列表实际上是普通数组的推广。
散列存储
设要存储的数据元素为n,设置一个长度为m(m>=n)的连续内存单元,分别以每个数据元素的关键字Ki(0<=i<=n-1)为自变量,通过哈希函数h(Ki),把Ki映射为内存单元的某个地址h(Ki),并把该数据元素存储在这个内存单元中。
第一步是要定义数据元素的关键字Ki。
哈希冲突
可能出现这种现象:Ki!=Kj(i != j),h(Ki) = h(Kj),这种现象叫做哈希冲突,即不同的关键字,映射的地址是相同的。解决哈希冲突的基本思想是:通过哈希冲突函数产生一个新的地址。
装填因子
设a = n/m,a就叫装填因子。a越大,哈希冲突的可能性就越高;a越小,哈希冲突的可能性就越低,但是也越浪费空间。
散列函数的构造方法
1.除留余数法
h(K)= K mod m,m为哈希表长,一般设为质数:4d + 3
2.直接定址法
3.数字分析法
4.折叠法
5.平方取中法
哈希冲突解决方法
1.闭散列法。发生冲突时,在哈希表内部寻找没有被占用的空间。
2.开散列法。发生冲突时,在哈希表外部寻找空间,也叫链表法。
哈希查找的时间复杂度
哈希查找与哈希存储是相对应的。查找给定的某一元素时,先通过哈希函数算出哈希值(索引),然后就可以直接得到需要的元素了。但并不总是一步就能得到需要的元素,因为有哈希冲突存在。这时候就需要用哈希冲突函数查找,直到查到需要的元素。因此,在最坏的情况下,哈希查找的时间复杂度为O(n),最理想的情况下为常量阶O(1),但实际情况往往会接近常量阶,因为冲突毕竟是少见的,而数组的查找时间复杂度为O(n),所以使用散列表能大大提高检索的效率,但需要更多的空间,散列算法是一种典型的以空间换取时间的算法。