[MIT6.006] 10. Open Addressing, Cryptographic Hashing 开放定址,加密哈希
前几节课讲散列表的时候,我们需要用Chaining,链接法需要用到指针pointer,但有一种方法可以不要Chaining和指针,还能在发生冲突时,为产生冲突的关键字寻找下一个“空”的Hash地址。这种方法叫:开放定址法(Open Addressing)如下图所示:
在开放定址法中,用到探测法(Probing),它是让Hash函数指定slot的顺序去进行关键字key的探索,从而进行插入/查找/删除操作。简单来说,上图的例子就能看懂probing的运作机制了。为了方便确认slot是否已有关键字占用,为每个slot定义个flag,如果无占用就是None。
下面我们看下在开放定址下,它是如何进行插入/查找/删除操作:
对上图翻译如下:
- 插入(k,v):一直探测,直到一个空的slot出现,然后插入进去。注:k为要插入的数,v为散列表尝试插入的次数。
- 查找(k):只要slot上的关键字不等于k,则不断探测下去,直到遇到key=k的情况(返回:成功),或者遇到空slot(返回:失败)。
- 删除:删除简单来说就先用上面查找方式找到待删除k的位置,然后删除即可。但是如果散列表第1个slot就是空slot,那么查找(k)会返回失败的结果,然后实际上并不一定是对的,上图列子可以说明这一点。比如我先删除了586,之后要删496,散列表第1个位置上slot为空,则返回失败,这是不对的,因为496在散列表第3个位置上。这个时候为了解决这个问题,就加入了DeleteMe flag,如果第一个位置上586被删除了,则设DeleteMe != None,当要删496时,碰到DeleteMe != None时,跳过该位置,继续向下探测。需要注意的是,对于插入来说 DeleteMe和None没什么区别,只要为空就可以插入。
探测方法有几种,本课就讲了两种:线性探测法(Linear Probing)和再散列法(Double Hashing Probing)。
首先,如下图,线性探测法的散列函数为:h(k, i) = (h'(k) + i) mod m (其中h'(k)为正常的散列函数)。但这种方法有个弊端:线性探测法可能使第i个散列地址的同义词存入第i+1个散列地址,这样原本应存入第i+1个散列地址的元素就争夺第i+2个散列地址,从而造成大量元素在相邻的散列地址上“聚集”起来,减低了查找效率。
为了解决线性探测的聚集问题,可以使用再散列法,它的公式为:h(k, i) = (h1(k) + i * h2(k)) mod m(其中h1(k)和h2(k)两种不同的普通散列函数)。
课程的最后提到Uniform Hashing Assumption,如下图所示,具体的cost of operation instert作者没有讲的太细,所以我这边也没太看明白。而最后作者提到了密码加密的机制,简单来说就是一个密码x123456,然后你用hash(k=x123456)后保存在数据库中,因此想要猜到哈希加密后的密码是很难的。
[MIT6.006] 10. Open Addressing, Cryptographic Hashing 开放定址,加密哈希的更多相关文章
- [MIT6.006] 1. Algorithmic Thinking, Peak Finding 算法思维,峰值寻找
[MIT6.006] 系列笔记将记录我观看<MIT6.006 Introduction to Algorithms, Fall 2011>的课程内容和一些自己补充扩展的知识点.该课程主要介 ...
- Python与数据结构[4] -> 散列表[2] -> 开放定址法与再散列的 Python 实现
开放定址散列法和再散列 目录 开放定址法 再散列 代码实现 1 开放定址散列法 前面利用分离链接法解决了散列表插入冲突的问题,而除了分离链接法外,还可以使用开放定址法来解决散列表的冲突问题. 开放定 ...
- C# Dictionary源码剖析---哈希处理冲突的方法有:开放定址法、再哈希法、链地址法、建立一个公共溢出区等
C# Dictionary源码剖析 参考:https://blog.csdn.net/exiaojiu/article/details/51252515 http://www.cnblogs.com/ ...
- java 解决Hash(散列)冲突的四种方法--开放定址法(线性探测,二次探测,伪随机探测)、链地址法、再哈希、建立公共溢出区
java 解决Hash(散列)冲突的四种方法--开放定址法(线性探测,二次探测,伪随机探测).链地址法.再哈希.建立公共溢出区 标签: hashmaphashmap冲突解决冲突的方法冲突 2016-0 ...
- 开放定址法——平方探测(Quadratic Probing)
为了消除一次聚集,我们使用一种新的方法:平方探测法.顾名思义就是冲突函数F(i)是二次函数的探测方法.通常会选择f(i)=i2.和上次一样,把{89,18,49,58,69}插入到一个散列表中,这次用 ...
- 开放定址法——线性探测(Linear Probing)
之前我们所采用的那种方法,也被称之为封闭定址法.每个桶单元里存的都是那些与这个桶地址比如K相冲突的词条.也就是说每个词条应该属于哪个桶所对应的列表,都是在事先已经注定的.经过一个确定的哈希函数,这些绿 ...
- [MIT6.006] 8. Hashing with Chaining 散列表
一.字典 在之前课里,如果我们要实现插入,删除和查找,使用树结构,最好的时间复杂度是AVL下的Ο(log2n),使用线性结构,最好的复杂度为基数排序Ο(n).但如果使用字典数据类型去做,时间复杂度可为 ...
- [MIT6.006] 9. Table Doubling, Karp-Rabin 双散列表, Karp-Rabin
在整理课程笔记前,先普及下课上没细讲的东西,就是下图,如果有个操作g(x),它最糟糕的时间复杂度为Ο(c2 * n),它最好时间复杂度是Ω(c1 * n),那么θ则为Θ(n).简单来说:如果O和Ω可以 ...
- [MIT6.006] 7. Counting Sort, Radix Sort, Lower Bounds for Sorting 基数排序,基数排序,排序下界
在前6节课讲的排序方法(冒泡排序,归并排序,选择排序,插入排序,快速排序,堆排序,二分搜索树排序和AVL排序)都是属于对比模型(Comparison Model).对比模型的特点如下: 所有输入ite ...
随机推荐
- 一键同步,紧跟潮流——CODING 现已支持导入 GitHub 仓库
为方便用户从 GitHub 快速迁移到 CODING 并开始使用,CODING 现已支持导入 GitHub 仓库.免去繁琐步骤,只需简单两步操作即可完成导入,让仓库静默同步,无缝衔接,平滑过渡:同时还 ...
- CSS的元素显示模式与转换
CSS的元素显示模式与转换 1. CSS的元素显示模式 1.1 块元素 <div>标签是最典型的块元素.另外常见的块元素有h1~h6.p.ul.ol.li等. 特点: 独占一行 高度.宽度 ...
- 多测师讲解python _函数中变量_高级讲师肖sir
定义的函数内部的变量名如果是第一次出现, 且在=符号前,那么就可以认为是 被定义为局部变量.在这种情况下,不论全局变量中是否用到该变量名,函数中 使用的都是局部变量.例如: num=100 #全局变量 ...
- BUUCTF-数据包中的线索 1
打开题目里面一个pcapng的文件,于是我们拖进wireshark流量分析一波 发现有http的流量,于是我们过滤http 让后追踪http,然后发现base64的编码, 于是我们看到了base64编 ...
- Python中列表、元组、字典、集合与字符串,相关函数,持续更新中……
本篇博客为博主第一次学 Python 所做的笔记(希望读者能够少点浮躁,认真阅读,平心静气学习!) 补充: 列表.元组和字符串共同属性: 属于有序序列,其中的元素有严格的先后顺序 都支持双向索引,索引 ...
- spring boot:基于profile的多环境配置(spring boot 2.3.4)
一,为什么要进行多环境配置? 1,没有人会在生产环境中进行开发和测试, 所以通常会有多个环境的划分: 工程师本地的开发环境 进行测试的测试环境 最终上线的生产环境 每个环境对应不同的数据库/缓存等数据 ...
- Activiti的流程实例【ProcessInstance】与执行实例【Execution】
最近,我在做流程引擎Activiti相关的东西,刚开始时的一个知识点困扰了我许久,那就是Activiti的ProcessInstance与Execution的区别,这是一个Activiti的难点,能够 ...
- mysql query cache 查询缓存
查看本博文,并进行验证(验证结果与博文一致): https://blog.csdn.net/carmazhao/article/details/7088530 mysql默认是开启查询缓存的. 设置查 ...
- springcloud中使用dubbo开发rpc服务及调用
spring cloud中基于springboot开发的微服务,是基于http的rest接口,也可以开发基于dubbo的rpc接口. 一,创建goodsService模块 1, 在创建的goodsSe ...
- Deployer 的使用
假设我们的项目在本地 /www/demo-project 下,那么我们切换到该目录: $ cd /www/demo-project 然后执行 Deployer 的初始化命令: $ dep init 它 ...