一、字典

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

字典本质上就是一个直接可接入的表,每个键内可存放一个数列的items。但因此也有坏处:

  1. 键不一定为非负整数
  2. 消耗大量内存空间

为了解决这两个问题,散列表被提出来了。

二、散列表

首先我们看下散列表是怎么解决字典第一个问题:键不一定为非负整数。

散列表使用prehash的方法将键变为非负整数,在Python里,hash(x)就是prehash,但需要注意的是有时候,x ≠ y,也有可能会有hash(x) = hash(y)。

关于字典第二问题:消耗大量内存空间,散列表通过hashing方法解决:

hashing方法可以将全部u个keys,减少为可接受的数量大小m。简单来说就是形成一个散列表,通过散列函数hash(x),将原来键空间内的键放入散列表中进行存放。因为散列函数本身会有冲突collision(即x ≠ y,但hash(x) = hash(y) ),所以散列表下某个键里可能有多个来自键空间内的items。而为了处理这种情况,拉链法Chaining出现了,它是将散列表每个槽内中的冲突元素进行链接,可视化如下:

如果该散列表是简单平均式散列(即每个键被平均(uniformally)地hash到表内的槽里,并且各键hashing是独立的(independently)),并假设有n个keys和m个槽,那么散列表里链长度为n / m = α = load factor。而运行时间为Ο(1 + |chain|) = Ο(1 + α), 其中1指计算hash的时间,|chain|是指形成chain的时间等于它的长度。

三、散列函数

该课只讲了三种散列函数:Divison Method,Multiplication Method和Universal Hashing。最后一种比前两种能更好地避免冲突。

(1)Divison Method

h(k) = k mod m    (mod为求余)

(2)Multiplication Method

h(k) = [(a * k) mod 2w] >> (w - r)    (k为w bits,m=2r, ‘>>’为shift right操作)

最后结果为阴影部分。

(3)Universal Hashing

h(k) = [(a * k + b) mod p] mod m    (a和b为从{0,...,p-1}中抽取的随机数,p为大于|u|的质数,质数是只能被1和自身整除的数,u为key space的大小)

对于最差情况k1 ≠ k2下, P{h(k1) = h(k2)} = 1 / m,其小于简单平均式散列下的n / m。

[MIT6.006] 8. Hashing with Chaining 散列表的更多相关文章

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

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

  2. [MIT6.006] 10. Open Addressing, Cryptographic Hashing 开放定址,加密哈希

    前几节课讲散列表的时候,我们需要用Chaining,链接法需要用到指针pointer,但有一种方法可以不要Chaining和指针,还能在发生冲突时,为产生冲突的关键字寻找下一个"空" ...

  3. PAT-1078 Hashing (散列表 二次探测法)

    1078. Hashing The task of this problem is simple: insert a sequence of distinct positive integers in ...

  4. 散列表 (Hash table,也叫哈希表)

    散列表是根据关键字(Key value)而直接访问在内存存储位置的数据结构.也就是说,它通过把键值通过一个函数的计算,映射到表中一个位置来访问记录,这加快了查找速度.这个映射函数称做散列函数,存放记录 ...

  5. Python数据结构——散列表

    散列表的实现常常叫做散列(hashing).散列仅支持INSERT,SEARCH和DELETE操作,都是在常数平均时间执行的.需要元素间任何排序信息的操作将不会得到有效的支持. 散列表是普通数组概念的 ...

  6. Java数据结构与算法解析(十二)——散列表

    散列表概述 散列表就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查找的值即key,即可查找到其对应的值. 散列表的思路很简单,如果所有的键都是整数,那么就可以使用一个简单 ...

  7. 散列表(hash table)——算法导论(13)

    1. 引言 许多应用都需要动态集合结构,它至少需要支持Insert,search和delete字典操作.散列表(hash table)是实现字典操作的一种有效的数据结构. 2. 直接寻址表 在介绍散列 ...

  8. [转载] 散列表(Hash Table)从理论到实用(上)

    转载自:白话算法(6) 散列表(Hash Table)从理论到实用(上) 处理实际问题的一般数学方法是,首先提炼出问题的本质元素,然后把它看作一个比现实无限宽广的可能性系统,这个系统中的实质关系可以通 ...

  9. [转载] 散列表(Hash Table)从理论到实用(中)

    转载自:白话算法(6) 散列表(Hash Table)从理论到实用(中) 不用链接法,还有别的方法能处理碰撞吗?扪心自问,我不敢问这个问题.链接法如此的自然.直接,以至于我不敢相信还有别的(甚至是更好 ...

随机推荐

  1. 2016-12-04---tiny412平台下的iconv库的移植问题

    一.解决问题    在arm开发板上使用framebuff,在汉字显示时,因为只有gb2312的16*16的汉字字库,而ubuntu16.04默认    的编码方式时utf-8,因此需要进行转码(ut ...

  2. MeteoInfoLab脚本示例:计算涡度、散度

    用U/V分量数据计算涡度和散度,计算涡度的函数是hcurl,计算散度的函数是hdivg,参数都是U, V.脚本程序: f = addfile('D:/Temp/GrADS/model.ctl') u ...

  3. Jenkins集成appium自动化测试(Windows篇)

    一,引入问题 自动化测试脚本绝大部分用于回归测试,这就需要制定执行策略,如每天.代码更新后.项目上线前定时执行,才能达到最好的效果,这时就需要进行Jenkins集成. 不像web UI自动化测试可以使 ...

  4. fedora30平台安装docker 19.03

    一,下载docker 1,说明:docker的打包对于fedora的支持很及时, 所以在fedora 30/31上都可以直接使用官方的rpm包 下载地址: https://download.docke ...

  5. lumen发送邮件配置

    composer.json 增加 "illuminate/mail":"5.6"composer update -vvvconfig 目录新建mail.php ...

  6. ffmpeg实现视频文件合并/截取预览视频/抽取音频/crop(裁剪)(ffmpeg4.2.2)

    一,ffmpeg的安装 请参见: https://www.cnblogs.com/architectforest/p/12807683.html 说明:刘宏缔的架构森林是一个专注架构的博客,地址:ht ...

  7. react渲染数据3种方式

    直接渲染,()类似于模板字符串,包裹一个dom元素 ReactDOM.render( (<div> <h2>现在时间:{new Date().toLocaleTimeStrin ...

  8. HTML <del> 标签

    HTML <del> 标签 什么是<del> 标签? 定义文档中已被删除的文本. 实例 a month  is <del>25</del> 30 day ...

  9. C# URL编码

    #region URL编码 /// <summary> /// URL编码 /// </summary> /// <param name="str"& ...

  10. Redis基础——剖析基础数据结构及其用法

    这是一个系列的文章,打算把Redis的基础数据结构.高级数据结构.持久化的方式以及高可用的方式都讲一遍,公众号会比其他的平台提前更新,感兴趣的可以提前关注,「SH的全栈笔记」,下面开始正文. 如果你是 ...