一、字典

在之前课里,如果我们要实现插入,删除和查找,使用树结构,最好的时间复杂度是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. SpringBoot使用activiti自定义流程demo解析

    环境搭建[这里直接讲解自定义流程] 集成 Activiti Modeler 下载源码 我这里选用的是 Activiti 5.23.0 版本的页面,下载 zip,解压 Activiti 5.23.0 源 ...

  2. Java 集合看这一篇就够了

    大家好,这里是<齐姐聊数据结构>系列之大集合. 话不多说,直接上图: Java 集合,也称作容器,主要是由两大接口 (Interface) 派生出来的: Collection 和 Map ...

  3. linux centos 04

    1.python的虚拟环境 1.将当前机器上的解释器作为一个 本地,复制出的很多歌 虚拟解释器 物理机上的 本体解释器 ,什么事也不做 分身1:  解释器1:虚拟环境1     运行django  1 ...

  4. 【UR #13】Yist

    UOJ小清新题表 题目摘要 UOJ链接 给出一个排列 \(A\) 以及它的一个非空子序列 \(B\),给出一个 \(x\) 并进行若干次操作,每一次操作需要在 \(A\) 中选择一个长度恰好为 \(x ...

  5. linux(centos8):用uniq去除文本中重复的行(去重)

    一,uniq命令的用途 1, 作用: 从输入文件或标准输入中找到相邻的匹配行, 并写入到输出文件或标准输出 2, 使用时通常会搭配sort使用 说明:刘宏缔的架构森林是一个专注架构的博客,地址:htt ...

  6. 【Flutter 混合开发】与原生通信-MethodChannel

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  7. Java进阶--Java动态代理

    JDK version: 1.8 动态代理中所说的"动态", 是针对使用Java代码实际编写了代理类的"静态"代理而言的, 它的优势不在于省去了编写代理类那一点 ...

  8. 腾讯云函数免费搭建onedrive网盘

    目录 腾讯云函数 介绍 真免费? 搭建教程 准备条件 创建云函数 创建触发器 配置SecretId和SecretKey 添加onedriver盘 自定义域名 访问路径处理 总结 搭建期间遇到的问题 想 ...

  9. tp5伪静态--宝塔

    location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s=$1 last; break; } }

  10. Phoenix的一些问题

    date: 2020-09-10 13:50:00 updated: 2020-09-14 16:30:00 1. Phoenix索引 全局索引:适合读多写少的场景.写数据时因为索引表分布在不同数据节 ...