哈希表概念

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

上面所提到的哈希函数是指:有一个对应关系 f ,使得每个关键字和结构中一个唯一的存储位置相对应,这样在查找时,我们不需要像传统的查找算法那样进行比较,而是根据这个对应关系 f 找到给定值K的像f(K)。

哈希函数与哈希表

  • 这个hash函数并没有什么统一标准,它的核心思想就是就是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。
  • 这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数,这个消息可能是字符、数组、字符串等等。
  • 再使用哈希表进行查询的时候,就是再次使用哈希函数将key转换为对应的数组下标,并定位到该空间获取value,如此一来,就可以充分利用到数组的定位性能进行数据定位。
  • 拥有这样的hash存储结构的数据结构称为散列表,或者叫哈希表。
  • 哈希表一般基于数组实现,特定情况下结合链表,但是数组是哈希表基础数据结构。

为什么要有哈希表呢? 数组的特点是:寻址容易,插入和删除困难;而链表的特点是:寻址困难,插入和删除容易。那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?答案是肯定的,这就是我们要提起的哈希表,哈希表有多种不同的实现方法,我接下来解释的是最常用的一种方法

哈希算法

构造哈希函数的方法有很多。首先需要明确什么是“好” 的哈希算法。若对于关键字集合中的任一个关键字,经哈希函数映像到地址集合中任何一个地址的概率是相等的,则称此类哈希函数是均匀的(Uniform)哈希函数。换句话说,就是使关键字经过哈希函数得到一个“随机的地址”,以便使一组关键字的哈希地址均匀分布在整个地址区间中,从而减少冲突。

一个hash函数需要满足

  1. 接受一个单一的参数,这个参数可以是任何类型,但是只能是一个。
  2. 返回一个整型值(一般情况下)。
  3. 输出的哈希地址均匀分布在整个地址区间中。
  4. 对于两个相同的输入,输出必须相同。
  5. 对于两个不同的输入,输出相同的概率需要做到非常小。
  6. hash的计算不能过于复杂,时间复杂度尽可能地低。

既然自己想不到比较好的hash算法,我们就来看看别人是怎么做的吧,下面是一些常用的hash算法:

  • 直接定址法 取key的线性函数值作为hash值,value = a * key + b,a,b为常数。这一类散列码的特点是:对输入为整型数据而言,不会产生下标冲突。不产生冲突当然是最完美的状态,但是这种方式要求输入的key遵循一定的线性规律。

例如:有一个01到07的部门人数统计表,其中,部门编号作为关键字,哈希函数取关键字自身。如下表所示:

地址01020304050607部门01020304050607人数23432465643346

这样若要询问01部门有多少人,则只要查表的第01项即可。由于直接定址所得的地址集合和关键字集合的大小相同。因此,对于不同的关键字不会发生冲突,但是实际中能使用这种哈希函数的情况很少。

  • 除留余数法 除留余数法:假设数组的长度为l,value = key % l,这一种散列码实现简单,运用比较多,但是如果输入的元素集合不具有一定的规律,比较容易产生冲突。数组的长度最好是质数,被除数为质数在一定程度上可以缓解数据堆积的问题。

除留余数法此方法为最常用的构造散列函数方法。对于散列表长为m的散列函数公式为: f( key ) = key mod p ( p ≤ m )

mod是取模(求余数)的意思。事实上,这方法不仅可以对关键字直接取模,也可在折叠、平方取中后再取模。

显然在这里选取p的值至为关键,那么选取p值多少为合适呢?下面我们来举个例子看看:有一个关键字,它有7个记录。如果采用除留余数法,那么可以先尝试将散列函数设计为f(key) = key mod 7的方法。比如12 mod 7= 5,所以它存储在下标为5的位置。

地址0123456关键字722917111248

不过这也是存在冲突的可能的,像7、14、21、28、35.....这些获得的下标都为零。

如何合理选取p值? 使用除留余数法的一个经验是,若散列表表长为m,通常p为小于或等于表长(最好接近m)的最小质数或不包含小于20质因子的合数。 举个例子: 某散列表的长度为100,散列函数H(k)=k%P,则P通常情况下最好选择哪个作为p呢?答案是97。

  • 数字分析法 数字分析法即对关键字进行分析,取关键字的若干位进行或者组合进行hash计算,这一类散列码的特点是比较灵活,通常是结合其他hash函数来计算,可根据实际情况来做出调整,具有想当的灵活性。

有学生的生日数据如下:

学生序号012345学生生日1975.10.031975.11.231975.03.021975.07.121975.04.211975.02.15

经分析,第一位,第二位,第三位、第四位重复的可能性大,取这四位造成冲突的机会增加,所以尽量不取前四位,取后四位比较好。

  • 随机数法 选择一个随机函数,取关键字的随机函数值为它的哈希地址,即H(key)= random(key),其中random为随机函数。通常,当关键字长度不等时采用此法构造哈希函数较恰当。
  • 平方取中法 取关键字平方后中间几位作哈希地址。适于关键字长度不统一的情况,而且对于元素连续的输入,可以很好的将其散列均匀,而且相对于除法而言,乘法的执行速度更快,这个由硬件决定。
  • 折叠法 将关键字分割成位数相同的几部分(最后一部分的位数可以不同),然后取这几部分的叠加和(舍去进位)作为哈希地址,这方法称为折叠法。

例如:每一种西文图书都有一个国际标准图书编号,它是一个10位的十进制数字,若要以它作关键字建立一个哈希表,当馆藏书种类不到10,000时,可采用此法构造一个四位数的哈希函数。

处理哈希冲突的方法

基本原则: 从hash函数的要求可以看到,事实上我们只能定义对于两个不同的输入,输出相同的概率尽可能小。

  • 开放地址法

    • 开放地址法有一个公式:Hi=(H(key)+di) MOD m i=1,2,...,k(k<=m-1)其中,m为哈希表的表长。di是产生冲突的时候的增量序列。

(1)-di值可能为1,2,3,...m-1,称线性探测再散列。如果di取1,则每次冲突之后,向后移动1个位置. (2)-di取值可能为1,-1,4,-4,9,-9,16,-16,...kk,-kk(k<=m/2)称二次探测再散列。 (3)-di取值可能为伪随机数列。称伪随机探测再散列。

例如,在长度为7的哈希表中已填有关键字分别为9、16的记录(哈希函数 H(key) = key MOD 7),现有第2个记录,其关键字为16,由哈希函数得到哈希地址为2,产生冲突。若用线性探测再散列方法处理,得到下一个地址为3,仍冲突,继续算4,不冲突,填入哈希表。若用二次探测再散列,则应填入需要为1的位置。 线性探测再散列

地址0123456关键字91716

二次探测再散列

地址0123456关键字16917

  • 多哈希法 设计多种哈希函数,可以避免冲突,但是冲突几率还是有的,函数设计的越好或越多都可以将几率降到最低。
  • 拉链法 拉出一个动态链表代替静态顺序存储结构,可以避免哈希函数的冲突,不过缺点就是链表的设计过于麻烦,增加了编程复杂度。此法可以完全避免哈希函数的冲突。

左边很明显是个数组,数组的每个成员包括一个指针,指向一个链表的头,当然这个链表可能为空,也可能元素很多。我们根据元素的一些特征把元素分配到不同的链表中去,也是根据这些特征,找到正确的链表,再从链表中找出这个元素。

  • 建立一个公共溢出区 这也是处理冲突的一种方法、假设哈希函数的值域为[ 0, m - 1 ],则设向量HashTable[ 0..m - 1 ]为基本表,每个分量存放一个记录,另设向量OverTable[0..v]为溢出表。所有关键字和基本表中关键字为同义词的记录,不管它们由哈希函数得到的哈希地址是什么,一旦发生冲突,都填入溢出表。

总结

优点:

  • 不论哈希表中有多少数据,查找、插入、删除(有时包括删除)只需要接近常量的时间即0(1)的时间级。实际上,这只需要几条机器指令。
  • 哈希表运算得非常快,在计算机程序中,如果需要在一秒种内查找上千条记录通常使用哈希表(例如拼写检查器)哈希表的速度明显比树快,树的操作通常需要O(N)的时间级。哈希表不仅速度快,编程实现也相对容易。
  • 如果不需要有序遍历数据,并且可以提前预测数据量的大小。那么哈希表在速度和易用性方面是无与伦比的。

缺点:

  • 它是基于数组的,数组创建后难于扩展,某些哈希表被基本填满时,性能下降得非常严重,所以程序员必须要清楚表中将要存储多少数据(或者准备好定期地把数据转移到更大的哈希表中,这是个费时的过程)。

ds哈希查找—二次探测再散列_大白话之哈希表和哈希算法相关推荐

  1. 二次探测再散列_杭州二次元影像测量仪

    二次元影像g2fe1a测量仪杭州 三次元是指三坐标测量机,它是指在一个六面体的空间范围内,能够表现几何形状.长度及圆周分度等测量能力的仪器,又称为三坐标测量仪或三坐标量床.三坐标测量仪可定义为&quo ...

  2. Hash(散列)冲突解决之线性探测再散列和二次探测再散列

    线性探测再散列 H(key) = key %13,key 为关键字,采用开放地址法中的线性探测再散列解决冲突,依次输入11 个关键字,16,74,60,43,54,90,46,31,29,88,77, ...

  3. Hash(散列)冲突解决 线性探测再散列和二次探测再散列

    线性探测再散列 例如  哈希函数为: H(key) =  key %13,key 为关键字,采用开放地址法中的线性探测再散列解决冲突,依次输入 11 个关键字,16,74,60,43,54,90,46 ...

  4. 【哈希冲突解决】线性探测再散列和二次探测再散列

    定义 散列(Hashing)是计算机科学中一种对资料的处理方法,通过某种特定的函数/算法(称为散列函数/算法)将要检索的项与用来检索的索引(称为散列,或者散列值)关联起来,生成一种便于搜索的数据结构( ...

  5. 二次探测再散列举例_二次探测散列法

    展开全部 二次再散e68a84e8a2ad3231313335323631343130323136353331333431366365列法是指第一次散列产生哈希地址冲突,为了解决冲突,采用另外的散列函 ...

  6. 【哈希表】线性探测再散列的相关知识与计算

    注意概念: 装填因子 等概率下查找成功的平均查找长度 等概率下查找不成功的平均查找长度 线性探测再散列时以 存储空间的长度来取余 查找时比较次数,如在 {12}中查找12,12跟12也要进行一次比较. ...

  7. 哈希查找解决地址冲突的两种最常见方法(线性探测再散列,链地址法)C++实现

    哈希查找解决地址冲突的两种最常见方法(线性探测再散列,链地址法)C++实现 参考文章: (1)哈希查找解决地址冲突的两种最常见方法(线性探测再散列,链地址法)C++实现 (2)https://www. ...

  8. 散列表相关题目(线性探测再散列法)

    散列表相关题目(线性探测再散列法) 一.题目 将关键字序列(7.8.30.11.18.9.14)散列存储到散列表中.散列表的存储空间是一个下标从0开始的一维数组,散列函数为H(key)=(key×3) ...

  9. 线性探测再散列法计算asl

    再散列和平方散列不同,再散列是遇到冲突时前进一位. 计算查找失败的平均查找长度,要特别注意防止思维定式,在查找失败的情况下,既不是根据表中的元素个数,也不是根据表长来计算平均查找长度.查找失败时,在等 ...

最新文章

  1. 【Flutter】StatefulWidget 组件 ( PageView 组件 )
  2. JavaWeb基础之JdbcUtils工具类2.0
  3. idea启动多个tomcat失败
  4. php上传文件自动删除,jsp-解决文件上传后重启Tomcat时文件自动删除问题
  5. matlab 连通分支,(完整版)图的连通性判断matlab实验报告
  6. 托福试卷真题_干货解答考生疑惑,自考真题考过了还会在出吗?
  7. 使用docker搭建wordpress网站
  8. centos7源码安装mysql8.0_CentOS7下源码安装MySQL 8.x
  9. 【redis】redis应用场景,缓存的各种问题
  10. Spring Boot 使用模板引擎
  11. 为什么电脑能随便重装系统,而手机刷机可能刷成砖?
  12. 频率学派还是贝叶斯学派?聊一聊机器学习中的MLE和MAP
  13. 《计算机小常识》一不小心把windows资源管理器给结束任务了,电脑黑屏了怎么办?
  14. kafka创建Topic的一道面试题
  15. HashSet源码阅读
  16. 《武义九州》隐私政策
  17. 升压电路的原理-原文地址:http://www.52solution.com/basic/1218
  18. 迎接天翻地覆的重大演变:微软加速器区块链论坛成功举办
  19. 【RCV】接收单号丢失处理
  20. PaddleNLP_基于seq2seq的对联生成

热门文章

  1. 【渝粤题库】陕西师范大学200401 初等代数研究 作业(专升本)
  2. 【渝粤题库】广东开放大学 实用文写作 形成性考核
  3. 【渝粤题库】国家开放大学2021春2717家畜解剖基础题目
  4. 基于无线通信技术的智能公交系统设计
  5. php微信小程序获取用户信息,微信小程序获取openid及用户信息的方法
  6. LaTeX的编译速度优化方案
  7. oracle impdp导入时卡住,Oracle:impdp导入等待statement suspended, wait error to be cleared
  8. 阴阳师服务器维护稍后,《阴阳师》手游3月20日维护更新公告
  9. mysql与sim900a_sim900a的应用,基于SIM900A-GPRS模块的远程文件传输实例
  10. SLAM+语音机器人DIY系列:(二)ROS入门——2.ROS系统整体架构