前几节课讲散列表的时候,我们需要用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 开放定址,加密哈希的更多相关文章

  1. [MIT6.006] 1. Algorithmic Thinking, Peak Finding 算法思维,峰值寻找

    [MIT6.006] 系列笔记将记录我观看<MIT6.006 Introduction to Algorithms, Fall 2011>的课程内容和一些自己补充扩展的知识点.该课程主要介 ...

  2. Python与数据结构[4] -> 散列表[2] -> 开放定址法与再散列的 Python 实现

     开放定址散列法和再散列 目录 开放定址法 再散列 代码实现 1 开放定址散列法 前面利用分离链接法解决了散列表插入冲突的问题,而除了分离链接法外,还可以使用开放定址法来解决散列表的冲突问题. 开放定 ...

  3. C# Dictionary源码剖析---哈希处理冲突的方法有:开放定址法、再哈希法、链地址法、建立一个公共溢出区等

    C# Dictionary源码剖析 参考:https://blog.csdn.net/exiaojiu/article/details/51252515 http://www.cnblogs.com/ ...

  4. java 解决Hash(散列)冲突的四种方法--开放定址法(线性探测,二次探测,伪随机探测)、链地址法、再哈希、建立公共溢出区

    java 解决Hash(散列)冲突的四种方法--开放定址法(线性探测,二次探测,伪随机探测).链地址法.再哈希.建立公共溢出区 标签: hashmaphashmap冲突解决冲突的方法冲突 2016-0 ...

  5. 开放定址法——平方探测(Quadratic Probing)

    为了消除一次聚集,我们使用一种新的方法:平方探测法.顾名思义就是冲突函数F(i)是二次函数的探测方法.通常会选择f(i)=i2.和上次一样,把{89,18,49,58,69}插入到一个散列表中,这次用 ...

  6. 开放定址法——线性探测(Linear Probing)

    之前我们所采用的那种方法,也被称之为封闭定址法.每个桶单元里存的都是那些与这个桶地址比如K相冲突的词条.也就是说每个词条应该属于哪个桶所对应的列表,都是在事先已经注定的.经过一个确定的哈希函数,这些绿 ...

  7. [MIT6.006] 8. Hashing with Chaining 散列表

    一.字典 在之前课里,如果我们要实现插入,删除和查找,使用树结构,最好的时间复杂度是AVL下的Ο(log2n),使用线性结构,最好的复杂度为基数排序Ο(n).但如果使用字典数据类型去做,时间复杂度可为 ...

  8. [MIT6.006] 9. Table Doubling, Karp-Rabin 双散列表, Karp-Rabin

    在整理课程笔记前,先普及下课上没细讲的东西,就是下图,如果有个操作g(x),它最糟糕的时间复杂度为Ο(c2 * n),它最好时间复杂度是Ω(c1 * n),那么θ则为Θ(n).简单来说:如果O和Ω可以 ...

  9. [MIT6.006] 7. Counting Sort, Radix Sort, Lower Bounds for Sorting 基数排序,基数排序,排序下界

    在前6节课讲的排序方法(冒泡排序,归并排序,选择排序,插入排序,快速排序,堆排序,二分搜索树排序和AVL排序)都是属于对比模型(Comparison Model).对比模型的特点如下: 所有输入ite ...

随机推荐

  1. shell-的变量-全局变量

    shell变量基础及深入   1. 变量类型 变量可分为两类:环境变量(全局变量)和局部变量. 环境变量也可称为全局变量,可以在创建他们的shell及其派生出来的任意子进程shell中使用.局部变量只 ...

  2. linux块设备驱动---相关结构体(转)

    上回最后面介绍了相关数据结构,下面再详细介绍 块设备对象结构 block_device 内核用结构block_device实例代表一个块设备对象,如:整个硬盘或特定分区.如果该结构代表一个分区,则其成 ...

  3. SpringBoot整合Mybatis 编译失败:找不到符号 程序包不存在

    问题描述:jpa不好用,转用mybatis,配置多数据源  但是配置后无法编译mvn clean install  dao层这些报错,找不到entity的包     问题解决:罪魁祸首:热部署的部分 ...

  4. 在Linux命令行内的大小写转换

    在编辑文本时大小写常常是需要注意的地方,大小写的转换是很枯燥而繁琐的工作,所幸,Linux 提供了很多能让这份工作变得容易的命令.接下来让我们看看都有哪些完成大小写转换的命令. tr 命令 tr (t ...

  5. 多测师讲解自动化测试 _RF自定义关键字_高级讲师肖sir

    RF自定义关键字 在rf中叫关键字 在python中就叫做函数 或实例方法 我们自己可以写自定义关键字 自己创建一个库===库里面去创建模块===模块里面创建类和实例方法==>rf导入和引用 库 ...

  6. 基于python实现二叉树的遍历

    """ 二叉树实践: 用递归构建树的遍历 # 思路分析 -- 1.使用链式存储,一个Node表示一个数的节点 -- 2.节点考虑使用两个属性变量,分别表示左连接右连接 & ...

  7. docker查看ip

    docker查看容器的网络ip   docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' conta ...

  8. 查看centos 7.6 当前所有监听端口

    由于要开展服务器安全工作查看系统当前所监听端口 ss -lnt 缺点发现有重复端口也显示出来了! ss -lnt | awk '/*

  9. 远程Jenkins新增Mac电脑节点

    一,前言 上一篇博客Jenkins集成appium自动化测试(Windows篇)介绍了怎么使用远程Jenkins新建节点连接本地Windows电脑进行Appium自动化测试集成. 但是在做ios Ap ...

  10. node初学

    安装node.js 往往需要解析环境,但是现在直接安装时就已经配置好了, cmd打开 输入cd/ 在输入node -v   显示版本号 Node与php比较:https://www.techug.co ...