散列表(又称:哈希表)
⽤拉链法(⼜称链接法、链地址法)处理“冲突”:把所有“同义词”存储在⼀个链表中
【拉链法】散列查找、查找效率分析
查找成功效率分析:
查找失败效率分析:
常⻅的散列函数
1. 除留余数法 —— H(key) = key % p
散列表表⻓为m,取⼀个不⼤于m,但最接近或等于m的质数p
质数⼜称素数。指除了1和此整数⾃身外,不能被其他⾃然数整除的数
例:散列表表⻓15,散列函数 H(key)=key%13
例:散列表表⻓150,散列函数 H(key)=key%149
Why?——用质数取模,分布更均匀,冲突更少
2. 直接定址法 —— H(key) = key 或 H(key) = a*key + b
其中,a和b是常数。这种⽅法计算最简单,且不会产⽣冲突。
它适合关键字的分布基本连续的情况,若关键字分布不连续,空位较多,则会造成存储空间的浪费。
把学号映射成从0开始
3. 数字分析法 —— 选取数码分布较为均匀的若⼲位,作为散列地址
设关键字是r进制数(如⼗进制数),⽽r个数码在各位上出现的频率不⼀定相同,可能在某些位上分布均匀⼀些,每种数码出现的机会均等;⽽在某些位上分布不均匀,只有某⼏种数码经常出现,此时可选取数码分布较为均匀的若⼲位作为散列地址。这种⽅法适合于已知的关键字集合,若更换了关键字,则需要重新构造新的散列函数
4. 平⽅取中法——取关键字的平⽅值的中间⼏位,作为散列地址。
具体取多少位要视实际情况⽽定。这种⽅法得到的散列地址与关键字的每位都有关系,因此使得散列地址分布⽐较均匀,适⽤于关键字的每位取值都不够均匀或均⼩于散列地址所需的位数。
处理冲突的⽅法——开放定址法
① 线性探测法: di = 0, 1, 2, 3, …, m-1;即发⽣冲突时,每次往后探测相邻的下⼀个单元是否为空
插入1
插入79
插入25
查找21
查找成功、失败效率分析:
②平⽅探测法。当di = 02, 12, -12, 22, -22, …, k2, -k2时
⼜称⼆次探测法,其中k≤m/2
⾮重点⼩坑:散列表⻓度m必须是⼀个可以表示成4j + 3的素数,才能探测到所有位置