一、字典

在之前课里,如果我们要实现插入,删除和查找,使用树结构,最好的时间复杂度是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. 网页添加 Live2D 看板娘

        我是先参考别人的[点击跳转]博客来做的.不过我发现网上很多人都没有把一些细节写出来,用了别人那里下载的文件后里面的一些跳转链接就跳到他们的页面了.所以我这里写一写如何修改这些跳转链接吧. 1. ...

  2. python 利用jieba库词频统计

    1 #统计<三国志>里人物的出现次数 2 3 import jieba 4 text = open('threekingdoms.txt','r',encoding='utf-8').re ...

  3. JS获取指定月份的天数几种方法

    最近看到一个有意思的试题,正好在需求中也碰到类似的问题,即计算某个月的天数问题.碰到类似问题也许大部分会想是不是还要判断闰年.平年,如果这样想的话就复杂了,下面给出具体的计算方法. 获取月份天数方法一 ...

  4. 【原创】有利于提高xenomai 实时性的一些配置建议

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有错误,欢迎指正. @ 目录 一.影响因素 1.硬件 2.BISO(X86平台) 3.软件 4. 缓存使用策略与GPU 二.优化措施 1. BIO ...

  5. lumen 添加配置

    app同级目录新建config目录 添加配置文件 bootstrap/app.php里面加载 $app->configure('options');使用 $router->get('/', ...

  6. phpstorm10.0.3 下载与激活

    phpstorm10.0.3 百度网盘下载   提取码: kqvc 激活服务器: http://jetbrains.tencent.click/ (2016-09-19 可用) http://owo. ...

  7. centos 7.8 添加磁盘后查看、分区、格式化、挂载

    基础环境 公有云 由于磁盘空间快用完了,现在决定多加一个40G磁盘 第一步 分区 fdisk -l #查看当前磁盘信息 fdisk /dev/vdb #对指定磁盘进行操作 如上图一般磁盘的第一个分区都 ...

  8. 【Azure微服务 Service Fabric 】在SF节点中开启Performance Monitor及设置抓取进程的方式

    前提条件 当我们观察到SF中某一个节点出现CPU不正常的情况,但是由于不能肉眼长期观察,所以可以通过开启Performance Monitor的方式来获取每一个进程的%Processer Time的方 ...

  9. 纯JS自定义网页滚动条

    前言 由于最近在公司很忙,没什么时间更新,忙中抽时间做了一个JS滚动条,因为火狐浏览器与谷歌浏览器的滚动条自定义样式过于麻烦,所以我打算自己写个方便改样式的滚动条 CSS <style> ...

  10. pyqt设置窗口图标

    import sys from PyQt5.QtWidgets import QMainWindow,QApplication from PyQt5.QtGui import QIcon ''' 窗口 ...