在之前的内容中讲述了许多关于查找的方法,比如说顺序表查找(挨个儿比较);有序表查找(二分法查找)。在这里将介绍一种用于查找的存储技术,即散列表(或称为哈希表)。
1. 相关概念
在哈希表中,记录的存储位置 = f (关键字),通过查找关键字的存储位置即可,不用进行比较。散列技术是在记录的存储位置和它的关键字之间建立一个明确的对应关系f 函数,使得每个关键字 key 对应一个存储位置 f(key) 且这个位置是唯一的。这里我们将这种对应关系 f 称为散列函数,又称为哈希(Hash)函数。采用散列技术将记录存储在一块连续的存储空间中,这块连续存储空间称为散列表或哈希表(Hash table)。
当存储记录时,通过散列函数计算出记录的散列地址;当查找记录时,我们通过同样的是散列函数计算记录的散列地址,并按此散列地址访问该记录。散列技术即使一种存储方法,也是一种查找方法;散列技术之间没有关系,只有关键字和函数之间有关系,所以散列技术是一种面向查找的存储技术
缺点是会存在关键字重复的问题,比如说男女为关键字的时候就不合适了。同样不适合查找范围的,比如说查找18-20岁之间的同学。散列表技术对于1对1的查找是适合的。
2. 构造散列函数
2.1 两个基本原则
“好的散列函数 = 计算简单 + 分布均匀”。其中计算简单指的是散列函数的计算时间不应该超过其他查找技术与关键字比较的时间,而分布均匀指的是散列地址分布均匀。
2.2 具体方法
2.2.1 直接定址法
即使用关键字本身作为函数值,即f(key) = key。假如有一个从1到100岁的人口数字统计表,其中,年龄作为关键字,哈希函数取关键字自身。
如,下图所示
又假果现在要统计的是1980年以后出生的人口数,那么我们对出生年份这个关键字可以变换为:用年份减去1980的值来作为地址。即:f(key) = key – 1980
所以直接定值法是取关键字的某个线性函数值为散列地址,即 f(key) = a*key + b。其优点是简单、均匀,不会产生冲突;但缺点是需要知道关键字的