哈希相关知识再学习

个人博客地址 http://dandanlove.com/

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

哈希表

根据关键字(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),,,,直到冲突不再产生。这种方法不易产生聚焦,但增加了计算时间。

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

文章到这里就全部讲述完啦,若有其他需要交流的可以留言哦

想阅读作者的更多文章,可以查看我 个人博客 和公共号:

振兴书城

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容