哈希表又称散列表,其定义是根据一个哈希函数将集合S中的关键字映射到一个表中,这个表就称为哈希表,而这种方法就称为Hashing。从作用上来讲,构建哈希表的目的是把搜索的时间复杂度降低到O(1),考虑到一个长度为n的序列,如果依次去比较进行搜索的话,时间复杂度是θ(n),或者对其先进行排序然后再搜索会更快一些,但这两种方法都不是最快的方法。

一、直接寻址表

直接寻址表就是一个数组。每个数存在相应的下标内,当关键字的全域U比较小时,直接寻址是一种简单而有效的技术。比如,如果全域为U={0,1,…,m-1}。则可以使用长度为m的数组:

二、哈希表

直接寻址技术的缺点很明显:如果全域U很大,则存储大小为|U|的数组是不切实际的,而且如果实际存储的关键字集合K相对于全域U来说很小的时候,会造成巨大的浪费。此时采用散列表。

在直接寻址方式下,具有关键字k的元素存放在索引为k的位置中,在哈希表中,该元素存放在h(k)中。h()就是一个散列函数。它将关键字的全域U映射到散列表T[0..M-1]的槽位上:

这里会存在所谓“冲突”的问题:两个关键字可能被映射到同一个槽位中。由于全域|U|>M,所以冲突是无法避免的。一个好的哈希函数产生的键值应该尽可能的均匀,这样可以减少产生冲突的次数;但是无论是何种哈希函数也不可能完全解决冲突问题,所以还应该寻找解决冲突的方法。

哈希函数

除法散列法:散列函数为h(k) = k mod m。其中m为散列表的槽位数,使用除数散列法的时候,对于m的选择要慎重。比如m不应该是2的幂。否则如果m = ,则h(k)就是k的p个最低位数字(二进制)。除非已经知道关键字的最低p位数的排列是等可能的,否则在设计散列函数时,应该考虑关键字的所有位。一个不太接近2的整数幂的素数是m个一个比较好的选择。

乘法散列法:  假设所有的key都是整数,m=2^r ,计算机字长是w,那么构建h(k)=(A*k mod 2^w) rsh (w-r) 其中rsh是右移的意思,A的大小是2^(w-1)<A<2^w 这个哈希函数的好处是,最后的取得h(k)实际上和每一位上的k值都相关,而A和2^w这两个数是互质的,所以想象一个轮盘,周长是2幂,A肯定不是周长的倍数,k是转了多少圈,那么最后的h(k)就会有可能落到轮盘的任意位置。

实际工作中需要根据不同的情况采用不同的哈希函数。通常,考虑的因素有:

计算哈希函数所需的时间;

关键字的长度;

哈希表的大小;

关键字的分布情况;

记录的查找频率。

解决冲突的方法

1.链接法解决冲突。

解决冲突的比较简单的方法就是链接法。它是把散列到同一个槽位的所有元素都放在一个链表中,然后数组中存放指针指向这个链表,如下图:

在最坏的情况下,也就是所有的h(k)都指向了同一个槽,那么哈希表实际上就是一个链表,在链表中查询一个值的时间复杂度是θ(n),在最好的情况下,没有发生碰撞那么时间为θ(1)。给定一个具有m个槽位,存储了n个元素的哈希表T,定义α=n/m为哈希表T的装载因子(即每个链表平均长度),一次成功的搜索平均用时θ(1+α/2)1表示计算H的时间,α/2表示在链表中所用的平均时间,所以如果n=O(m)那么α就是常数,在这个哈希表中搜索的时间就为θ(1),同时,考虑平均情况下的最坏情况的搜索,时间为θ(1+α)。由于插入操作首先需要调用CHAINED-HASH-SEARCH确认元素x的关键值未曾出现在表中,然后用O(1)时间将x插入到链表T[h(key[x])]中,所以期望的时间是O(1)。相仿地,删除操作对双向拉链表平均情形时间也是O(1),所以所有的字典操作可以在O(1)的平均时间内得到支持。

2.开放寻址法

开放寻址法是另外一种处理冲突的方法。在该方法中,所有的元素都存放在哈希表中。当查找某个元素的时候,需要系统的检查所有的表项,直到找到所需的元素,或者最终查明该元素不在表中。因此,在开放寻址法中,哈希表有可能会被填满,因而装载因子α <=  1。

开放寻址法就是发生冲突时,采取某种探查方法,寻找下一个槽,如果下一个槽仍然有数,那么就继续探查,知道找到一个空的槽。常用的探查方法有:

1.线性探查。h(k,i) = (h’(k) + i) mod m, i = 0,1,…,m-1。给定一个关键字k,首先探查槽位h’(k),然后是h’(k) + 1,以此类推,直到最后的h’(k)-1。在线性探查中,初始探查位置决定了整个序列,所以有m种不同的探查序列。

线性探查有个缺点,就是一次群集。当表中i,i+1,i+2位置上都已经填满时,下一个哈希地址为i,i+1,i+2,i+3的关键字记录都将竞争i+3的位置。随着连续被占用的槽位不断增加,平均查找时间也不断增加。

2.二次探查。 h(k,i) = (h’(k) + i + ) mod m,      i = 0,1,…,m-1 。二次探查即每次以平方的形式向后查找,知道找到空的槽。这种探查的效果要比线性探查好。但是,如果两个关键字的初始探查位置相同,那它们的探查序列也是相同的,这一性质会导致二次群集。类似于线性探查,二次探查也仅有m个不同的探查序列。
3.双重哈希探查。
4.伪随机序列探查。 双重散列是开放寻址法中的最好方法之一,不像线性和二次探查,双重探查的的探查序列以两种不同的方式依赖于关键字k。为了能使探查序列查找到整个表,值必须与m互素。有两种方法:

m为2的幂,而 总产生奇数;

取m为素数, 则总是产生比m小的正整数。

双重探查法用到了 种探查序列。

在开放寻址哈希中,对于装载因子α,并假设是均匀散列,至多需要做1/(1-α)次探查。

参考:

《算法导论》

http://blog.csdn.net/gqtcgq/article/details/45289419

http://blog.csdn.net/persever/article/details/45773663

MIT算法导论公开课第七讲哈希表相关推荐

  1. 麻省理工公开课《算法导论》学习笔记:第一讲

    主题:简介课程,渐近概念的大局观,插入排序和归并排序,递归式函数时间分析(递归树方法) 教材:<算法导论> 收获:很感动地看到算法分析那个log(n)是为什么出现了,更深层还要听第二讲,若 ...

  2. 肖臻公开课(七)——比特币中的挖矿难度

    本笔记对应北京大学肖臻老师<区块链技术与应用>公开课第七课. 0.前言 在本节中,肖老师介绍了比特币的挖矿难度的调整算法. 1.定义 在比特币的挖矿算法中,需要找出一个"恰当&q ...

  3. “悟道”公开课第四讲丨悟道开发案例:​悟空策论——议论文写作平台

    图片出处:https://bmk.sh/2020/05/29/GPT-3-A-Brief-Summary/ 如果你错过了上一波深度学习引发的NLP范式转换,不要再错过这一波超大预训练模型的崛起. 现在 ...

  4. 【阿里云 CDP 公开课】 第二讲:CDH/HDP 何去何从

    简介:Hadoop社区版CDH/HDP已经不再更新,也将终止服务.后续的平台路线图怎么规划?Cloudera CDP整合了CDH和HDP,有哪些性能提升和功能增强?如何平滑的进行迁移?本文结合CDH/ ...

  5. MIT 算法导论 (二)Math Notation

    MIT 算法导论 (二)Math Notation O: f(n) = O(g(n)) ,  means that there are some suitable constants,such tha ...

  6. 《计算机科学导论》百度云,【麻省理工学院】Python编程和计算机科学导论公开课(中英字幕)...

    声明&链接 『[麻省理工学院]Python编程和计算机科学导论公开课(中英字幕)』资源内容来源于 52搜盘. 请认真阅读以下说明,您只有在了解并同意该说明后,才可继续访问本站. 1. 请认准罗 ...

  7. MIT算法导论03-分治法

    MIT算法导论03-分治法(Divide and Conquer) 课程名:Introduction to Algorithms 课程编号:6.046J/18.410J 授课教师:Prof.Erik ...

  8. [052] 微信公众平台开发视频公开课第2讲-自定义菜单开发讲解

    微信公众平台开发视频公开课第2讲将为大家讲解自定义菜单的相关知识,时间是2014年5月24日20:00-22:00.本次课程的大纲如下: 1.自定义菜单简介 1)如何获得菜单权限 2)菜单按钮分类(c ...

  9. PE格式第七讲,重定位表

    PE格式第七讲,重定位表 作者:IBinary 出处:http://www.cnblogs.com/iBinary/ 版权所有,欢迎保留原文链接进行转载:) 一丶何为重定位(注意,不是重定位表格) 首 ...

最新文章

  1. python根目录_Pycharm使用嵌入式Python
  2. 使用elementui实现表单上传功能_使用ElementUI中的upload组件上传Excel文件
  3. 人工智能是如何应用于智能交通领域
  4. 12小时紧急策划 复盘一篇10W+的诞生全历程
  5. python中变量不需要事先声明_第二章 Python 变量
  6. java内核_测量时间:从Java到内核再到
  7. 134. 加油站 golang
  8. Goalng小demo一:家庭收支记账软件项目
  9. 百度网盘就“用户激励计划”道歉;沈义人卸任 OPPO 全球营销总裁;Python 2.7.18 发布| 极客头条...
  10. mysql显示行号,通过表名模糊查找,通过列名模糊查找,常用sql
  11. jQuery操作DOM元素
  12. 全球五百强IT名企智力题精选
  13. devops之 --- git可视化工具sourcetree
  14. Android 电子书及阅读器Demo
  15. HTML5创意设计简历,35张设计师的创意个人简历信息图
  16. 世界超长经典名车荟萃
  17. 三大特征 六大原则结合实践运用
  18. 【092】韦达定理在一元n次方程中的推广
  19. html 链接到 appstore,如何在微信浏览器内打开App Store链接
  20. JavaScript自写逻辑思维导图(非常详细)

热门文章

  1. falagard cegui
  2. 《楚汉传奇》对韩信的一点看法
  3. 切比雪夫逼近法设计FIR滤波器
  4. pip永久设置清华镜像源一键下载requirements.txt
  5. java文件恢复软件,文件恢复软件 免费-文件恢复软件 免费版
  6. 第三人称的英语作文我和我的计算机,英语作文:我的同学My Classmate
  7. 计算机休眠策略,桌面从睡眠或休眠中意外唤醒
  8. ListView item错位 由于Item复用时高度不一致导致ListView 显示错误
  9. Ajax面试题 | 前端
  10. MySQL数据库层优化基本概念