一、字典

在之前课里,如果我们要实现插入,删除和查找,使用树结构,最好的时间复杂度是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. devops-jenkins部署和基本使用

    1. jenkins部署和基本使用  1.1) 先关闭centos 7的自带防火墙和selinux [root@test-2 ~]# /bin/systemctl stop firewalld [ro ...

  2. springboot1.5和jpa利用HikariCP实现多数据源的使用

    背景 现在已有一个完整的项目,需要引入一个新的数据源,其实也就是分一些请求到从库上去 技术栈 springboot1.5 (哎,升不动啊) 思路 两个数据源,其中一个设置为主数据源 两个事物管理器,其 ...

  3. JavaScript常用对象介绍

    目录 对象(object) 对象的创建方式 点语法 括号表示法 内置对象 Array 数组创建方式 检测数组 转换方法 分割字符串 栈方法 队列方法 重排序方法 操作方法 位置方法 迭代方法 Stri ...

  4. golang不想http自动处理重定向的解决方案

    目录 前言 解决方案 结论 前言     有时候发送http请求不想让库自动帮忙处理重定向,库里面默认的是会把所有重定向都完成一遍,结果就是最后一个没有重定向的请求的结果.因此需要一种方案直接获取首次 ...

  5. 实验报告系列:实验一 HTML语言的简单网页制作

    实验一 HTML语言的简单网页制作 一.实验目的: 1.掌握常用的HTML语言标记: 2.利用文本编辑器建立HTML文档,制作简单网页. 3.学习将其它格式的文档转换成HTML格式的文档 二.实验内容 ...

  6. vim插件配置

    OS:kali linux tool:vim 上图: 0x00 需要用到的插件及其下载地址 左边的一栏显示文件目录结构的用到的插件为 NERDTree 下载地址:https://github.com/ ...

  7. ThreeJS学习6_几何体相关(BufferGeometry)

    ThreeJS学习6_几何体相关(BufferGeometry) 使用 BufferGeometry 可以有效减少向 GPU 传输几何体相关数据所需的开销 可以自定义顶点位置, 面片索引, 法向量, ...

  8. SpringBoot+Mybatis_Plus Generator

    AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity.Mapper.Mapper XML.Service.Control ...

  9. 【Aspose.Words for Java】 对word文档,增加页眉,页脚,插入内容区图像,

    一.环境准备 jar包:aspose-words-20.4.jar 或者去官方网站下载: 官方网站:https://www.aspose.com/ 下载地址:https://downloads.asp ...

  10. LuoguP1286 两数之和

    题面概括 将n个数两两相加得到n*(n-1)/2个和,给出这些和,求所有原数方案 n<=500 LuoguP1286 题解 此题原题是 n<10, 没啥可做的 先将 \(n*(n-1)/2 ...