哈希是什么

引入:我们在学习数组的时候,使用数组元素的下标值即可访问到该元素,所花费的时间是O(1),与数组元素的个数n没有关系,这就是哈希方法的核心思想。

哈希方法:以关键值K为自变量,通过一定的函数关系h(K)(哈希函数)计算出对应的函数值,把这个值解释为结点的存储地址,将结点的关键码(key)和属性数据(value)一起存入此存储单元中。检索时,用同样的函数计算出地址,找到对应的数据。

哈希表:按哈希存储方式构造的存储结构称为哈希表(hash table)

举例:已知线性表关键码值集合为S={and, begin, do, else, for,golang},假设哈希函数是关键码K的第一个字母在字母表中的序号,哪么可以建立如下的哈希表:

当然这个例子特别简单,细心的同学很快就发现了二个问题:

  1. 如果S中有类似于and,apple这样的关键码,哪么这个表还怎么存放,在1的位置存放and还是apple呢?(这种现象称为冲突
  2. 分配的空间大小比实际所需的要大一点(一般情况下,哈希表的空间(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)基础概念的更多相关文章

  1. 算法与数据结构基础 - 哈希表(Hash Table)

    Hash Table基础 哈希表(Hash Table)是常用的数据结构,其运用哈希函数(hash function)实现映射,内部使用开放定址.拉链法等方式解决哈希冲突,使得读写时间复杂度平均为O( ...

  2. PHP关联数组和哈希表(hash table) 未指定

    PHP有数据的一个非常重要的一类,就是关联数组.又称为哈希表(hash table),是一种很好用的数据结构. 在程序中.我们可能会遇到须要消重的问题,举一个最简单的模型: 有一份username列表 ...

  3. 什么叫哈希表(Hash Table)

    散列表(也叫哈希表),是根据关键码值直接进行访问的数据结构,也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. - 数据结构 ...

  4. 词典(二) 哈希表(Hash table)

    散列表(hashtable)是一种高效的词典结构,可以在期望的常数时间内实现对词典的所有接口的操作.散列完全摒弃了关键码有序的条件,所以可以突破CBA式算法的复杂度界限. 散列表 逻辑上,有一系列可以 ...

  5. 数据结构 哈希表(Hash Table)_哈希概述

    哈希表支持一种最有效的检索方法:散列. 从根来上说,一个哈希表包含一个数组,通过特殊的索引值(键)来访问数组中的元素. 哈希表的主要思想是通过一个哈希函数,在所有可能的键与槽位之间建立一张映射表.哈希 ...

  6. 哈希表(Hash table)

  7. Redis原理再学习04:数据结构-哈希表hash表(dict字典)

    哈希函数简介 哈希函数(hash function),又叫散列函数,哈希算法.散列函数把数据"压缩"成摘要,有的也叫"指纹",它使数据量变小且数据格式大小也固定 ...

  8. Hash表 hash table 又名散列表

    直接进去主题好了. 什么是哈希表? 哈希表(Hash table,也叫散列表),是根据key而直接进行访问的数据结构.也就是说,它通过把key映射到表中一个位置来访问记录,以加快查找的速度.这个映射函 ...

  9. 哈希表(Hash)的应用

    $hs=@() #定义数组 $hs=@{} #定义Hash表,使用哈希表的键可以直接访问对应的值,如 $hs["王五"] 或者 $hs.王五 的值为 75 $hs=@''@ #定义 ...

  10. (四)Redis哈希表Hash操作

    Hash全部命令如下: hset key field value # 将哈希表key中的字段field的值设为value hget key field # 返回哈希表key中的字段field的值val ...

随机推荐

  1. WebApi 全局异常与局部异常

    全局异常过滤器 public class ApiExceptionFilter:ExceptionFilterAttribute { private IHostingEnvironment _env; ...

  2. MyEclipse j2ee工程 WEB-INF 目录内容显示

    公司项目,使用的ant打包技术,,,蛋疼刚开始以为每次改个java代码都要ant 构建编译一把3-4分钟,很没有效率,, 然后实际使用中发下,可以用 auto building 和tomcat 的re ...

  3. Tomcat服务器的数字证书 HTTPS 连接!

    SUN公司提供了制作证书的工具keytool, 在JDK 1.4以后的版本中都包含了这一工具,它的位置为\bin\keytool.exe 注意要使用一下 cmd命令,请确认jdk环境变量可以使用,可以 ...

  4. 使用百度echarts仿雪球分时图(一)

    第一次写技术博客,有不足的地方希望大家指证出来,我再加以改正,谢谢大家. 之前一直没有找到一个合适的分时图项目,所以决定自己动手撸一个.接触的图表框架不多,在网上看到不少人推荐使用echarts,看了 ...

  5. gitlab自动化部署CI案例

    参考: https://blog.csdn.net/hxpjava1/article/details/78514999   (简单操作) https://blog.csdn.net/wh211212/ ...

  6. SpringMVC返回void的三大方法

    版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons) 在是springMVC的void的返回值中,有三大方法可以运行,个人觉得 ...

  7. flash多进程写操作

    1 应用场景介绍   硬件条件:使用stm32 MCU   软件条件:协议栈应用   协议栈简单介绍如下:   类似于OSI七层模型,所涉及的协议栈包括应用层,网络层,链路层,物理层,如下图:   在 ...

  8. js之head请求,闪电般实现交互

    平时我们用到的请求一般为post和get,今天介绍一种新的请求方式,head请求,顾名思义,head请求就是请求头部信息的,也只能请求头部信息,所以相应速度非常快,可以快速的实现前后端的交互 $.aj ...

  9. PAT Basic 1088 三人行 (20 分)

    子曰:“三人行,必有我师焉.择其善者而从之,其不善者而改之.” 本题给定甲.乙.丙三个人的能力值关系为:甲的能力值确定是 2 位正整数:把甲的能力值的 2 个数字调换位置就是乙的能力值:甲乙两人能力差 ...

  10. web开发原生开发混合开发的区别优势

    最近有人在讨论是原生开发好还是,混合开发好,以下是引用了数据来说: 最近原生应用.Web应用.混合应用的名字让我们听得比较熟悉了,现在我们就通过评析各种应用的优缺点来更进一步看看这三者的区别. 一.原 ...