Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >哈希相关知识再学习

哈希相关知识再学习

作者头像
静默加载
发布于 2020-05-29 02:21:32
发布于 2020-05-29 02:21:32
7980
举报

在平时工作和源码学习的过程中经常遇到哈希相关的问题,每次都会上网找资料回忆哈希相关的知识点。趁这机会记录下来,防止以后又忘记了!!

哈希表

根据关键字(Key value)至二级访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表。

哈希冲突

对不通的关键字可能得到同意散列地址,即k1 != k2,而f(k1) = f(k2),这种现象称为碰撞,也叫哈希冲突。

为什么需要哈希

使用数组或者链表存储元素,一旦存储的内容数量特别多,需要占用很大的空间,而且在查找某一个元素是否存在的过程中,数据和链表都需要循环便利,而通过哈希计算,可以大大减少比较次数。

哈希使用

几种常见的哈希函数(散列函数)的构造方法

  • 直接定址法:取关键字或者关键字的某个线性函数值为散列地址。例如:H(key) = key,H(key) = a*key + b,其中a,b为常数。

直接定址法

  • 除留余数发:取关键字被某个不大于散列长度m的数p求余,得到的作为散列地址。例如:H(key)=key%p,p < m。

除留余数发

  • 数字分析法:当关键字的位数大于地址的位数,对关键字的各位分布进行分析,选出分布均匀的任意几位作为散列地址。仅仅用于适用所欲关键字都已知的情况下,根据实际应用确定要选取的部分,尽量避免发生冲突。

数字分析法

  • 平方取中法:先计算出关机子的平方值,然后取平方值中间几位作为散列地址。随机分布的关键字,得到散列地址也是随机分布的。

平方取中法

  • 折叠法(叠加法):将关键字分为位数相同的几部分,然后取这几部分的叠加和(舍去进位)作为散列地址。用于关键字位数比较多,并且关键字中每一位上数字分布大致均匀。

折叠法

  • 随机数法:选择一个随机函数,把关键字的随机函数值作为它的哈希值。通常关键字的长度不等时采用这种方法。

构造哈希函数的方法很多,实际工作中需要根据不同的情况选择合适的方法,总的原则是尽可能的减少产生的冲突。

通常考虑的因素有关键字的长度和分布情况、哈希值的范围等。

如:当关键字是整数类型时就可以用哦除留余数法;如果关键字是小数类型,选择随机书法会比较好。

哈希函数

链接法(拉链法)

拉链法解决冲突的做法是:将所有关键字为hash相同的结点链接在同一个单链表中。

若选定的散列表长度为吗,则可将散列表定义为一个由m个头指针组成的指针数组T[0...m-1].

凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。

T中各个分量的初值值均为空指针

在拉链法中,装填因子a可以大于1,但一般均取a<=1。

拉链法构造散列表

开放定址发(再散列法)

基本思想:当关键字key的哈希地址p=H(key)出现冲突时,以p为基础,产生另一个哈希地址p1,如果p1任然冲突,再以p为基础,产生另一个哈希地址p2,...,直到找出一个不冲突的哈希地址pi,将相应元素存入其中。

这种方法有一个通用的再散列函数形式:Hi = (H(key) + di) % m, i = 1,2,,4,...,n。其中H(key)为哈希函数,m为表长,di称为增量序列。增量序列的取值方式不同,相应的再散列方式也不同。

用开放定址法解决冲突的做法是:

当冲突发生时,使用某种探测技术在散列表中形成一个探测序列。沿此序列逐个单元地查找,知道找到给定的关键字,或者碰到一个开放地址(即该地址单元为空)为止(若要插入,在探测到开放的地址,则可将待插入的新结点存入该地址单元)。查找时探测到开放地址则表明无待查的关键字,即查找失败。

简单的说:当发生冲突时,使用某种探测(亦称探测)技术在散列表中寻找下一个空的散列地址,只要散列表足够大,空的散列表地址总能找到。

按照形成探查序列的方法不同,可将开放地址发区分为线性探查法、二次探查法、双重散列法等。

  • 线性探查法:hi=(h(key) + 1) % m, 0 <= i <= m-1。 基本思想是:探查时从地址d开始,首先探查T[d],然后依次探查T[d+1],...,直到T[m-1],此后又循环到T[0],T[1],...,直到有空余地址或者到T[d-1]位为止。 这种方法的特点是:冲突发生时,顺查看表中下一单元,知道找出一个空单元或者查遍全表。
  • 二次探测再散列法:hi=(h(key) + i*i)% m, 0 <= i <= m-1。 基本思想是:探查时从地址d开始,首先探查T[d],然后依次探查T[d+1^2],T[d+2^2],T[d+3^2],...等,直到探查到有空余地址或者到T[d-1]为止。 缺点是无法探测到整个散列空间。
  • 双重散列法:hi=(h(key) + i*h1(key))%m, 0 <= i <= m-1。 基本思想是:探查时从地址d开始,首先探查T[d],然后依次探查T[d+h1(d)],T[d+2*h1(d)],...,等。该方法使用了两个散列函数h(key)和h1(key),故也称为双散列函数探查法。 定义h1(key)的方法比较多,但无论采用什么方法定义,都必须使h1(key)和值和m互素,才能使发生冲突的同义词地址均匀分布在整个表中,负责可能造成同义词地址的循环计算。 该方法是开放定址法中最好的方法之一。

建立公共溢出区

这种方法的基本思想是:将hash表分为基本表和溢出表两部分,凡是基本表发生冲突的元素,一律填入溢出表。

再哈希法

这种方法是同时构造多个不同的哈希函数:

Hi=RH1(key) i=1,2,3,,,,k

当哈希地址Hi=RH1(key)发生冲突时,再计算Hi=RH2(key),,,,直到冲突不再产生。这种方法不易产生聚焦,但增加了计算时间。

参考文章: 重温数据结构:哈希 哈希函数 哈希表

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
解决哈希冲突的常用方法分析
哈希算法:根据设定的哈希函数H(key)和处理冲突方法将一组关键字映象到一个有限的地址区间上的算法。也称为散列算法、杂凑算法。 哈希表:数据经过哈希算法之后得到的集合。这样关键字和数据在集合中的位置存在一定的关系,可以根据这种关系快速查询。 非哈希表:与哈希表相对应,集合中的 数据和其存放位置没任何关联关系的集合。
冬天里的懒猫
2020/08/03
15.2K0
数据结构基础详解:哈希表【理论计算篇】开放地址法_线性探测法_拉链法详解
散列表,又称哈希表。是一种数据结构,特点是:数据元素的关键字与其存储地址直接相关。
小徐在进步
2024/10/08
7650
数据结构基础详解:哈希表【理论计算篇】开放地址法_线性探测法_拉链法详解
HASH碰撞问题一直没真正搞懂?这下不用慌了
哈希表就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查找的值即key,即可查找到其对应的值。
架构精进之路
2021/01/20
6.7K1
HASH碰撞问题一直没真正搞懂?这下不用慌了
重温数据结构:哈希 哈希函数 哈希表
该文介绍了计算机科学中的哈希表(Hash Table)及其在编程中的应用。哈希表是一种数据结构,可以高效地完成查找、插入、删除等操作。文章还介绍了哈希函数、哈希冲突、拉链法等概念。
张拭心 shixinzhang
2018/01/05
2.7K1
重温数据结构:哈希 哈希函数 哈希表
哈希查找
这是一种简单/最常用的方法,嘉定哈希表表长为m,取一个不大于m但最接近或等于m的质数p,利用一下公式把关键字转化成哈希地址:
Autooooooo
2020/11/09
4870
哈希查找
哈希表基本概念介绍及哈希冲突的处理方法(附源码)
  哈希表(散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做哈希(散列)函数,存放记录的数组叫做哈希(散列)表。
嵌入式与Linux那些事
2021/05/20
9550
哈希表基本概念介绍及哈希冲突的处理方法(附源码)
hash哈希游戏系统开发技术原理丨hash哈希游戏系统开发流程
哈希表中元素是由哈希函数确定的。将数据元素的关键字K作为自变量,通过一定的函数关系(称为哈希函数),计算出的值,即为该元素的存储地址。表示为:
开发VC_Whi366
2022/06/28
3890
散列表
http://blog.csdn.net/yyxaf/article/details/7527878 搜索关键词:散列函数、散列表、哈希函数、哈希表、Hash函数、Hash表 散列方法不同于顺序查找、二分查找、二叉排序树及B-树上的查找。它不以关键字的比较为基本操作,采用直接寻址技术。在理想情况下,无须任何比较就可以找到待查关键字,查找的期望时间为O(1)。 散列表的概念 1、散列表 设所有可能出现的关键字集合记为U(简称全集)。实际发生(即实际存储)的关键字集合记为K(|K|比|U|小得多)。 散列方
用户1624346
2018/04/17
1.1K0
java解决hash算法冲突
看了ConcurrentHashMap的实现, 使用的是拉链法. 虽然我们不希望发生冲突,但实际上发生冲突的可能性仍是存在的。当关键字值域远大于哈希表的长度,而且事先并不知道关键字的具体取值时。冲突就难免会发 生。另外,当关键字的实际取值大于哈希表的长度时,而且表中已装满了记录,如果插入一个新记录,不仅发生冲突,而且还会发生溢出。因此,处理冲突和溢出是 哈希技术中的两个重要问题。 1、开放定址法      用开放定址法解决冲突的做法是:当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查
xiangzhihong
2018/02/01
9710
java解决hash算法冲突
【C++】哈希表的实现
哈希(hash)⼜称散列,是⼀种组织数据的⽅式。从译名来看,有散乱排列的意思。本质就是通过哈希 函数把关键字Key跟存储位置建⽴⼀个映射关系,查找时通过这个哈希函数计算出Key存储的位置,进 ⾏快速查找。
用户11375356
2024/12/24
2080
【C++】哈希表的实现
【408&数据结构】散列 (哈希)知识点集合复习&考点题目
散列查找是一种高效的查找方法,它通过散列函数将关键字映射到数组的一个位置,从而实现快速查找。这种方法的时间复杂度平均为(O(1)),但最坏情况下可能会退化到(O(n))。
苏泽
2024/09/09
3550
【408&数据结构】散列 (哈希)知识点集合复习&考点题目
哈希表的实现--C++
哈希(hash)又称散列,是一种组织数据的方式。从译名来看,有散乱排列的意思。本质就是通过哈希函数把关键字Key跟存储位置建立一个映射关系,查找时通过这个哈希函数计算出Key存储的位置,进行快速查找。
小志biubiu
2025/02/27
2270
哈希表的实现--C++
数据结构与算法之哈希表
哈希表也叫散列表。 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。 给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。
袁新栋-jeff.yuan
2020/08/26
7740
【数据结构】哈希表
顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码的多次比较。顺序查找时间复杂度为 $O(N)$ ,平衡树中为树的高度,即 $O(logN)$ ,搜索的效率取决于搜索过程中元素的比较次数。
椰椰椰耶
2024/09/20
1490
【数据结构】哈希表
程序员必读:教你摸清哈希表的脾气
在哈希表中,记录的存储位置 = f (关键字),通过查找关键字的存储位置即可,不用进行比较。散列技术是在记录的存储位置和它的关键字之间建立一个明确的对应关系f 函数,使得每个关键字 key 对应一个存储位置 f(key) 且这个位置是唯一的。这里我们将这种对应关系 f 称为散列函数,又称为哈希(Hash)函数。采用散列技术将记录存储在一块连续的存储空间中,这块连续存储空间称为散列表或哈希表(Hash table)。
谭庆波
2018/08/10
4060
程序员必读:教你摸清哈希表的脾气
散列表
总结:这上面三种方法都是在同一个数组中进行处理,没有超过数组的范畴,改变的都是d的取值方式
大忽悠爱学习
2021/11/15
6660
【数据结构】什么是哈希表(散列表)?
在正式开始深入了解哈希表之前呢, 我想带大家先回忆一下生活中咱们的这个"老朋友"。可能你会感到诧异, 我怎么会和它是"老朋友"呢? 别急, 其实你的生活中常常会出现哈希的身影,只是你没有细心观察罢了,不信你看下面几个场景对你来说是不是非常熟悉呢:
修修修也
2024/10/06
2980
【数据结构】什么是哈希表(散列表)?
[算法] 开放寻址法解决哈希冲突方式
开放寻址法:又称开放定址法,当哈希冲突发生时,从发生冲突的那个单元起,按照一定的次序,从哈希表中寻找一个空闲的单元,然后把发生冲突的元素存入到该单元。这个空闲单元又称为开放单元或者空白单元。开放寻址法需要的表长度要大于等于所需要存放的元素数量,非常适用于装载因子较小(小于0.5)的散列表。
唯一Chat
2020/12/31
4.1K0
海量数据处理
  针对海量数据的处理,可以使用的方法非常多,常见的方法有hash法、Bit-map法、Bloom filter法、数据库优化法、倒排索引法、外排序法、Trie树、堆、双层桶法以及MapReduce法。 1、hash法 hash法也成为散列法,它是一种映射关系,即给定一个元素,关键字是key,按照一个确定的散列函数计算出hash(key),把hash(key)作为关键字key对应的元素的存储地址,再进行数据元素的插入和检索操作。   散列表是具有固定大小的数组,表长应该是质数,散列函数是用于关键字和存储
Mister24
2018/05/14
2.3K0
为什么要重写 hashCode 和 equals 方法?
心里想着我没事重写哪玩意干啥,能不写就不写。嘴上当然没敢这么说,只能略表遗憾的说抱歉,我没写过。
周三不加班
2019/06/04
5580
为什么要重写 hashCode 和 equals 方法?
相关推荐
解决哈希冲突的常用方法分析
更多 >
LV.2
这个人很懒,什么都没有留下~
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档