哈希表(hash table)基础概念
哈希是什么
引入:我们在学习数组的时候,使用数组元素的下标值即可访问到该元素,所花费的时间是O(1),与数组元素的个数n没有关系,这就是哈希方法的核心思想。
哈希方法:以关键值K为自变量,通过一定的函数关系h(K)(哈希函数)计算出对应的函数值,把这个值解释为结点的存储地址,将结点的关键码(key)和属性数据(value)一起存入此存储单元中。检索时,用同样的函数计算出地址,找到对应的数据。
哈希表:按哈希存储方式构造的存储结构称为哈希表(hash table)
举例:已知线性表关键码值集合为S={and, begin, do, else, for,golang},假设哈希函数是关键码K的第一个字母在字母表中的序号,哪么可以建立如下的哈希表:

当然这个例子特别简单,细心的同学很快就发现了二个问题:
- 如果S中有类似于and,apple这样的关键码,哪么这个表还怎么存放,在1的位置存放and还是apple呢?(这种现象称为冲突)
- 分配的空间大小比实际所需的要大一点(一般情况下,哈希表的空间(H)比结点的集合(M)大,这样虽然浪费了空间,但是换来了检索效率,称α=M/H为哈希表的负载因子)
其实这就是接下来要谈到的哈希函数的选择和冲突解决策略。
哈希函数
哈希方法的核心就是哈希函数的选择,理想的哈希函数应该使得结点“分布均匀”,且冲突少
为了简单起见,以下的哈希函数我们假设关键值都是整数(如果不是整数,哪也有特定的方法可以把它转换为整数,毕竟在计算机世界里,任何东西都是01组成的串)
除余法:
关键值码k除以M(往往取哈希表的长度),并取余数作为哈希地址。
乘余取整法
先让关键码k乘上一个常数A(0<A<1),提取乘积的小数部分。然后,再用整数n乘以这个值,对结果向下取整,将其作为哈希的地址。
有许多种哈希函数可以选择,每种都有其适用的场景,但是作为软件开发工程师,我们只要理解它的思想就可以,至于什么场景选择什么哈希函数,哪大概率是数学家应该研究的问题。
优秀的哈希函数可以尽可能的避免产生冲突,但是冲突的产生是不可避免地,这就是接下来要谈到的冲突解决策略
冲突解决策略
冲突解决技术可以分为两类,拉链法和开地址法,这两种方法的不同之处在于,拉链法把发生冲突的关键码存储在哈希表主表之外,而开地址法把发生冲突的关键码存储在表中另一个槽内。
拉链法
拉链法的一种简单形式是把哈希表中的每一个槽定义为一个链表的表头,哈希到一个特定槽的所有记录都放到这个槽的链表中。
假设S={and, apple, begin, do, dog, else, for, go, golang},哈希函数还是关键码K的第一个字母在字母表中的序号。哪么可以建立如下的哈希表:

开地址法
开地址法把所有记录直接存储在哈希表中。每个记录关键码K有一个由哈希函数计算出来的基位置,即h(k)。如果要插入一个关键码k,而另一个记录的关键码已经占据了k的基位置(发生冲突)则把k存储在表中的其他地址内,至于其他地址怎么选择,有多种算法,我们以顺序探测法为例。
已知一组关键码为{26,36,41,38,44,15,68,12,06,51,25},哈希表长度L=15,用线性探查法解决冲突构造的哈希表的过程如下:
利用除余数作为哈希函数,假设选择M=13,则散列函数为:h(k)=k%13,按顺序插入各个结点:
h(26)=0, h(36)=10,h(41)=2, h(38)=12, h(44)=5,
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 26 | 25 | 41 | 44 | 36 | 38 |
h(15)=0,发生碰撞,因此需要进行探查,按照顺序探测法,显然3为开放的空闲地址,因此可以将其放在3单元。
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 26 | 25 | 41 | 15 | 44 | 36 | 38 |
68和12也类似,最后的哈希表如下所示:
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 26 | 25 | 41 | 15 | 68 | 44 | 6 | 36 | 38 | 12 | 51 |
小结
本文简述了哈希表的基本概念和思想,作为软件工程师,掌握这些知识足够我们从事工程开发了,至于一些偏数学方面的知识,比如散列方法的效率分析,以及相关的一些优化,本文就不再讲述。
参考资料:《数据结构与算法》张铭 编著
哈希表(hash table)基础概念的更多相关文章
- 算法与数据结构基础 - 哈希表(Hash Table)
Hash Table基础 哈希表(Hash Table)是常用的数据结构,其运用哈希函数(hash function)实现映射,内部使用开放定址.拉链法等方式解决哈希冲突,使得读写时间复杂度平均为O( ...
- PHP关联数组和哈希表(hash table) 未指定
PHP有数据的一个非常重要的一类,就是关联数组.又称为哈希表(hash table),是一种很好用的数据结构. 在程序中.我们可能会遇到须要消重的问题,举一个最简单的模型: 有一份username列表 ...
- 什么叫哈希表(Hash Table)
散列表(也叫哈希表),是根据关键码值直接进行访问的数据结构,也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. - 数据结构 ...
- 词典(二) 哈希表(Hash table)
散列表(hashtable)是一种高效的词典结构,可以在期望的常数时间内实现对词典的所有接口的操作.散列完全摒弃了关键码有序的条件,所以可以突破CBA式算法的复杂度界限. 散列表 逻辑上,有一系列可以 ...
- 数据结构 哈希表(Hash Table)_哈希概述
哈希表支持一种最有效的检索方法:散列. 从根来上说,一个哈希表包含一个数组,通过特殊的索引值(键)来访问数组中的元素. 哈希表的主要思想是通过一个哈希函数,在所有可能的键与槽位之间建立一张映射表.哈希 ...
- 哈希表(Hash table)
- Redis原理再学习04:数据结构-哈希表hash表(dict字典)
哈希函数简介 哈希函数(hash function),又叫散列函数,哈希算法.散列函数把数据"压缩"成摘要,有的也叫"指纹",它使数据量变小且数据格式大小也固定 ...
- Hash表 hash table 又名散列表
直接进去主题好了. 什么是哈希表? 哈希表(Hash table,也叫散列表),是根据key而直接进行访问的数据结构.也就是说,它通过把key映射到表中一个位置来访问记录,以加快查找的速度.这个映射函 ...
- 哈希表(Hash)的应用
$hs=@() #定义数组 $hs=@{} #定义Hash表,使用哈希表的键可以直接访问对应的值,如 $hs["王五"] 或者 $hs.王五 的值为 75 $hs=@''@ #定义 ...
- (四)Redis哈希表Hash操作
Hash全部命令如下: hset key field value # 将哈希表key中的字段field的值设为value hget key field # 返回哈希表key中的字段field的值val ...
随机推荐
- js中this关键字用法详解
1.全局环境中的this 在全局环境中,this 指向全局对象Global,即 window 对象 如: alert(this); // 显示 [object Window] alert(this = ...
- cookie和session,sessionStorage、localStorage和cookie的区别
1.cookie 含义: 存储在访问者的计算机中的变量,即存储在客户端 创建一个cookie /* getCookie方法判断document.cookie对象中是否存有cookie,若有则判断该co ...
- jdk8的环境配置
下载jdk,选择安装路径进行安装.https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.htm ...
- c#模拟鼠标左键单击
[System.Runtime.InteropServices.DllImport("user32.dll")] private static extern int mouse_e ...
- storm连接http需要的jar包
将httpclient-4.5.6.jar httpcore-4.4.10.jar这两个jar包拷贝到storm安装目录下的lib目录下 如果是集群的话,需要拷贝到集群中的每台机器上
- Image Processing and Analysis_21_Scale Space:Scale-space theory A basic tool for analysing structures at different scales——1994
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
- springbatch
springbatch job的创建使用 job:作业,是批处理中的核心概念,是batch操作的基础单元,每个job由多个step组成 step:步骤,任务完成的节点 每个job是由JobBuildF ...
- BCB 编写服务程序的一个注意事项
BCB编写服务,install报错的一个问题 今天编写了一个服务,最后INSTALL 的时候报错,如图: 经过近1小时的比较(俺过去写例子),居然无意中设置了一个属性 ...
- 创建conda虚拟环境以及python的virtualenv虚拟环境
我觉得我,嗯...可能脑袋里面有水 首先说一个,就是我电脑安装了conda2和conda3,原来怎么查看conda版本都是2,所以就没有创建虚拟环境 系统变量里面的path要改,总共有3个: D:\A ...
- mysql基础篇--库的管理
库的创建 create database [if not exists] 库名; 库的修改 alter database 库名 character set 字符集; #更改库的字符集 库的删除 dro ...