数据结构与算法18——散列表(哈希表)

散列表(哈希表)查找

  • 我们要在a[ ]中查找key关键字的记录:
    —— 顺序表查找:挨个儿比较
    —— 有序表查找:二分法查找
    —— 散列表查找:?

在这里插入图片描述

散列表的查找步骤

  • 当存储记录时,通过散列函数计算出记录的散列地址
  • 当查找记录时,我们通过同样的是散列函数计算记录的散列地址,并按此散列地址访问该记录。

构造散列函数的两个基本原则

好的散列函数 = 计算简单+分布均匀

  1. 直接定址法
    —— 例1:有一个从1到100岁的人口数字统计表,其中,年龄作为关键字,哈希函数取关键字自身。
    即:f(key)= key
    数据结构与算法18——散列表(哈希表)_第1张图片
    —— 例2:如果现在要统计的是1980年以后出生的人口数,那么我们对出生年份这个关键字可以变换为:用年份减去1980的值来作为地址。
    即:f(key)= key - 1980
    数据结构与算法18——散列表(哈希表)_第2张图片

  2. 数字分析法
    数字分析法通常适合处理关键字位数比较大的情况,例如我们现在要存储某家公司员工登记表,如果用手机号码作为关键字,那么我们发现抽取后面的四位数字作为散列地址是不错的选择。
    数据结构与算法18——散列表(哈希表)_第3张图片

  3. 平方取中法
    平方取中法是将关键字平方之后取中间若干位数字作为散列地址。

  4. 折叠法
    折叠法是将关键字从左到右分割成位数相等的几部分,然后将这几部分叠加求和,并按散列表表长取后几位作为散列表地址。

  5. 除留余数法
    —— f(key)= key mod p (p<=m)
    我们对有12个记录的关键字构造散列表时,就可以用除留取余法:
    在这里插入图片描述
    p的选择是关键,如果对于下面这个表格的关键字,p还选择12的话,那得到的情况未免也太糟糕了:
    在这里插入图片描述
    p的选择很重要,如果我们把p改为11,那结果就另当别论了:
    在这里插入图片描述

  6. 随机数法
    选择一个随机数,取关键字的随机函数值为它的散列地址。
    即:f(key)= random(key)
    这里的random是随机函数,当关键字的长度不等时,采用这个方法构造散列函数是比较合适的。

处理散列冲突的方法

  1. 开放定址法
    所谓的开放定址法就是一旦发生冲突,就去寻找下一个空的散列表,只要散列表足够大,空的散列地址总能找到,并将记录存入。
    他的公式是:
    fi(key)= (f(key)+di)MOD m (di = 1,2,…m-1)
    数据结构与算法18——散列表(哈希表)_第4张图片

  2. 再散列函数法
    fi(key) = RHi(key)(i = 1,2,3,…k)

  3. 链地址法
    数据结构与算法18——散列表(哈希表)_第5张图片

  4. 公共溢出区法(常用方法)
    数据结构与算法18——散列表(哈希表)_第6张图片

散列表查找的代码实现

你可能感兴趣的:(数据结构)