算法4B-----散列
-
散而列之
-
建立快速查询的索引
-
BC[j,‘x’],j相当于身份证号,
call-by-value
-
需要查电话簿才能拨打电话
-
建立一个表格,直接输索引,就可以打出响应的值
java:hashMap+hashTable
- 可以把key-value存储到容器中
- 通过key直接获取value
perl:%hash type
python:dictionary class
ruby:hash table
hashing:table+function
-
昨天的例子
- BC表,字符集中有多少个字符就有多少项
- 中间的每一项都记了一个shift
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rjpaqaHj-1601905457488)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005195132162.png)]
- 但是unicode这么大集合的字符串就不可能一下子开这么大的数组
-
清华大学的电话簿
- 新建一个数组
- 00000000~99999999
- 首先开不了这么大的数组,其次利用率太低
- 好处查询O(1),坏处没有这么大的空间
-
解决思路
-
建一个虚拟的表,假想开那么大的空间
-
分成两步
-
-
1.经过一次函数计算才映射到散列表上
2.从散列表上再去快速查询,这个散列表是10的(4~5)次方级别<<10^8,几万的数量
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lZL7ofwo-1601905457497)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005195829518.png)]
-
取一个素数90001,数组容量是90000,通过取模运算%90001
-
最饶头的地方:
- collison:碰撞、冲突
- 不同的电话映射到一个entry中
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LIoxGdGi-1601905457502)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005200127999.png)]
-
Hashing:hash function
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-86zBtfSB-1601905457514)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005200642108.png)]
- 取余,不动点0,局部的相关性(邻居)
- (a*key+b)%M,让0点偏移b
- 选择数位法
- 平方,取中间位上的数字
polynomial(移位法)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DuIBQJta-1601905457521)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005200827821.png)]
- 把前五位变成后五位,把后27位变成前27位
- 这种hash方式被验证在英文字符中产生的哈希碰撞是最少的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5eg1ZmnU-1601905457527)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005201346838.png)]
- 将一个英文字符串的每一个字母的ASCII码相加获得的和作为hash算法映射的值
hashing:open hashing + closed addressing
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QnFbXBPV-1601905457531)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005202052086.png)]
- 碰撞的同义词都放在一个哈希桶内
- 定址:任何一个桶内存的都是它的同义词,是封闭的散列
- 大量的浪费:链表内的每一个链接,都会占4个字节,最后的利用率也不会超过50%
- 还有一个缺点:缓存,链表的跳跃可能的物理内存离的非常远
hashing:closing hash + open addressing
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MlW6Av5X-1601905457533)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005202819681.png)]
- 第一行图:把非同义词放在一个桶内,依次找下去,
- 貌似比上一种拉链的方法麻烦
- 每次总是要找隔壁,这么下去,实际还有很多空的位置
- 第二行图:碰撞后跳离的步长是逐渐增大的,而不是恒定为1
- 叫做平方试探
- 注意不是二次散列,有很严重的歧义
应用 bucketsort : basic
-
排序
-
把某些元素塞到指定的key下面
-
把散列表中非0的元素取出来
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w6SJA6R4-1601905457536)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005203951124.png)]
-
n >> m时才适用
bucketsort:stability+deduplicate()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zCZjun0D-1601905457539)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005204038626.png)]
- 重复元素都会在指定位置继续接下去
- 算法的稳定性
- 分
- 集
bucketsort:max-gap
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aim5v62b-1601905457541)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005204546749.png)]
-
无限长数轴
-
期望的方法复杂度是O(n)的
-
从lo到hi分n-1个桶,再加一个桶,一共n个桶,左闭右开
-
绿的是没有点落在里面,红的是有点落进去
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xMY8VSfb-1601905457545)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005205020610.png)]
-
每一个红色段只关心最左和最右的值,绿色段全忽略,一个gap的最右边值和下一个gap最左边的值构成一个gap,找到那个最大的,所有的gap不会小于平均宽度((hi-lo)/ (n-1)),红色内部的gap是肯定小的
-
O(c*n)就是O(n)
radixsort:lexicographic order
- 字典序
- 依次比较字母,如果相同就往后比较,如果不相同大的就是更大者
- 实现这种基数排序
correctness = stability
stability of bucketsort
- 准备一个桶
- 一个四位数,先从个位比较,通过bucket sort
- 逐渐往大位继续滚动排序下去
- 正确性是因为前一次排序已经确定了,比较千位相同,就去比较百位,但是百位已经比较过了,所以能找到答案
- O(d X n) 数位是d,所以又是O(n)
bitmap:structure
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yZ5RyL88-1601905457548)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005210436141.png)]
- 存整数
- 开一个0到n的数组
- 得到一个数据结构
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jAn7a2BZ-1601905457551)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005210815123.png)]
- set:把对应的0翻转成1
- clear:减除掉那个元素
- test:判断这个k是否属于这个集合
实现
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jljKvacO-1601905457556)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005210905805.png)]
- 找到对应的比特
- test方法
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3H1E7kfJ-1601905457561)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005211525495.png)]
- set方法
- 把那一位强置为1
- clear方法
- 把那一位强置为0
bitmap: eratosthenes idea
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6aNagfD7-1601905457565)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005211940698.png)]
-
最早估算地球直径的人
-
羊皮纸算素数
-
素数筛法
-
把0和1排除
-
从某一个数的倍数依次找下去,插破,置为蓝色
-
实际上就是bitmap
-
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-weIoREO7-1601905457569)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005212141673.png)]
- 新建一个bitmap
- 排除0和1
- 从2开始,判断它是否是素数,如果不是素数,从它的2倍、3倍下去,在它未超过自己的计算范围之内,去把它在位图上扎破,
bitmap initialization O(1)
-
J. hopcroft cornell tuning
-
初始化时间只花O(1),但是并不是所有情况都需要这么做,有些时间简单用一个for循环遍历初始化是更好的
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qPKHvGsh-1601905457573)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005213141790.png)]
-
校验环
-
f[14] = 4 t[4] =14 符合
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MxkHKu8W-1601905457576)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005213343238.png)]
-
f[19] = 6 t[6] = 19 top=6 6的左侧 所以不符合
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QLu7zN66-1601905457580)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005213517347.png)]
-
f[24] = 2 t[2] = 21 f[21] = 2
-
-
比如在11的位置插入一个元素
- f[11] 要变成6 t[6]要变成11 top[6] 等于7
-
clear操作,去掉校验环,
-
最简单的操作,将top–,top实际就是一个栈,如果不是删除栈顶元素,怎么操作?
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tj4jV1JS-1601905457583)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20201005214124340.png)]
-
方法2:删除掉的窟窿,为了保持整体的完整性,用栈顶元素来充填,与原先栈顶配对的f也会变成新的t的位置
-