数据结构笔记-散列表

散列表(hashing)

常见查找

  • 顺序查找,O(N)
  • 二分查找 静态查找
  • 散列

查找方法:快速搜索到需要的关键词或关键词不方便比较怎么办

散列查找的两个基本工作

  • 计算位置
  • 解决冲突(collision) 多个关键词同一位置

时间复杂度几乎是常量,查找与问题规模无关,以空间换时间

填装因子(loading factor):设散列表空间大小为m,填入表中元素个数为n,则称 α = n / m \alpha =n/m α=n/m为散列表的填装因子

散列函数构造

好的散列函数

  1. 计算简单
  2. 关键字对应的地址空间分布均匀,尽量减少冲突

关键字是数字

  1. 直接取值
  2. 取余 ,一般取数组长度,或质数
  3. 数字组成有一定的规律,如身份证号,取随机的那部分做地址
  4. 折叠法 ,对较长对数字,截成等长对部分,求和
  5. 平方取中法,对数字平方后,取中间几位

关键字是字符

  1. ascII码求和,范围较小
  2. 利用ascII码,求出数字后,视为较大进制的数(如使用27进制,一共有26个字母),再转回十进制,取余。
  • 可以使用32进制,等价与左移5位。每读一位,左移,再加下一位
char key[];
int i,count=0;
while(*key !='\0'){
   count  = count <<5 +*key;
   key++;
   }

处理冲突

开放地址法 open adress(换一个地址)

发生冲突,按某种规则再找地址。
发生了第i次冲突后,试探下一个地址
h i ( k e y ) = ( h ( k e y ) + d i ) m o d T a b l e S i z e h_i(key)=(h(key)+d_i)mod TableSize hi(key)=(h(key)+di)modTableSize
常见的方法( d i d_i di不同)

  1. 线性探测 d i = i d_i=i di=i,易聚集
  2. 平方探测 d i = + ‾ i 2 d_i ={ \underline+ }i^2 di=+i2
    2.1.若散列长度为4k+3形式的质数(k为正整数),平方探测可以探测整个散列空间
    2.2 若 d i = + ‾ i 2 d_i ={ \underline+ }i^2 di=+i2找不到空位,则 d i = i 2 d_i =i^2 di=i2也找不到空位
  3. 双散列 d i = i ∗ h 2 ( k e y ) d_i=i*h_2(key) di=ih2(key)
    3.1 对任意key h 2 ( k e y ) ! = 0 h_2(key)!=0 h2(key)!=0
    3.2 应该保证所有散列单元都能被探测到,可以选择 h 2 ( k e y ) = p − ( k e y m o d p ) h_2(key)=p-(key mod p) h2(key)=p(keymodp)

懒惰删除:开放地址删除时,不能删除,只能标记,否则回断链,使部分元素找不到

再散列 Rehashing

当元素太多时,散列当效率回下降
一般 0.5 ≤ α ≤ 0.85 0.5 \leq \alpha \leq 0.85 0.5α0.85
当装载因子太大时,需要扩容,这个过程叫再散列

链地址法 (不改变地址)

将所有冲突的元素放在同一个链表上
装填因子 α \alpha α:所有地址链表的平均长度定义称装填因子

散列表性能分析

关键指标

  1. 成功平均查找长度(ASLs),冲突次数加一
  2. 不成功平均查找长度(ASLu) ,将不再散列表中的元素分类(如按h(key)的值分类)

影响产生冲突的因素:

  1. 散列是否均匀
  2. 处理冲突的方法
  3. 装填因子$\alpha $

应用:统计文本单词

reference

浙大 数据结构 mooc https://www.icourse163.org/course/ZJU-93001

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值