(MIT6.006) lecture09 hash表02

UTF8gbsn

介绍

本节课程的主要内容在于hash的增长以及缩减。还介绍了一个查找子串的方法。

增长

假设我们的key现在有n个。而hash的抽屉的个数为m。那么有两种增长的策略。

  1. 如果 n ⩾ m n\geqslant m nm,那么我们将hash表的抽屉数量m加1.然后对前面已经插入的所有元素进行一次重新hash。那么这个算法的时间复杂度为 Θ ( n 2 ) \Theta(n^2) Θ(n2)。因为你插入n个元素需要进行重新hash次数为
    Θ ( 1 + 2 + ⋯ + n ) = Θ ( n 2 ) \Theta(1+2+\cdots+n)=\Theta(n^2) Θ(1+2++n)=Θ(n2)

  2. n ⩾ m n\geqslant m nm的时候我们将m增加到2m.这种策略的时间复杂度为 Θ ( n ) \Theta(n) Θ(n) .比如你要插入n个元素.那么需要重新hash的次数为
    Θ ( 1 + 2 + 4 + ⋯ + n ) = Θ ( n ) \Theta(1+2+4+\cdots+n)=\Theta(n) Θ(1+2+4++n)=Θ(n)

缩减

如果你的hash表进行了删除,那么为防止过分的资源浪费我们需要释放掉一部分的资源.那么策略是什么呢?
这里主要采用的策略是如果你的 n ⩽ 1 4 m n\leqslant \frac{1}{4}m n41m,
那么 m m m就进行减半,编程 m / 2 m/2 m/2.
为什么不在 n ⩽ 1 2 m n\leqslant \frac{1}{2}m n21m的地方进行减半呢?主要是为防止在临界点频繁增删,这样会导致数据结构频繁释放资源和分配资源.

example

python 中的list就是按照上面的方式进行的增减操作.

Karp-Rabin Algorithm

这个算法是一个查找子串的算法,首先假设目标串为s,我们希望在t串中找寻s串.这个算法利用hash的方法来做.

  • 将s进行hash.

  • 然后按照s的长度在t上进行滑动,每滑动一次可以得到一个子串.

  • 如果得到的子串的hash值和s的hash值相同.我们在进行真正的比较.

这个算法的期望时间复杂度为 O ( ∣ s ∣ + ∣ t ∣ c o s t ( h ) ) O(|s|+|t|cost(h)) O(s+tcost(h)),这与传统的子串比较复杂度 O ( ∣ s ∣ ⋅ ∣ t ∣ ) O(|s|\cdot|t|) O(st)比起来,有明显的优势.另外应该注意的是,我们还有一个算法KMP算法.它的最坏时间复杂度为 O ( n ) O(n) O(n)

Rolling Hash ADT

这个算法可以用来加速 Karp-Rabin Algorithm.它的定义如下

  1. r(), 在x上进行hash的函数

  2. r.append©,将c附加到x的后面.

  3. r.skip(),将最前面的字符删除.

这个算法省去了求中间重部分hash的过程,可以进一步提高算法的速度.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值