问题:构建哈希表常见的解决冲突的方法:拉链法和线性探测法

影响哈希查找效率的一个重要因素是哈希函数本身。当两个不同的数据元素哈希值相同时,就会发生冲突。为减少发生冲突的可能性,哈希函数应该将数据尽可能分散地映射到哈希表的每一个表项中。解决冲突的方法有以下两种:

1、开放定址法:

所谓开放定址法,即由关键码得到的哈希地址一旦产生了冲突,也就是说,该地址已经存放了数据元素。我们需要寻找下一个空的哈希地址,只要哈希表足够大,空的哈希地址总能找到,并将数据元素存入。常用的找空哈希地址方法有下列三种。

  • ① 线性探测法
    Hi = ( Hash(key) + di ) % m
    其中,Hash(key)为哈希函数,m为哈希表长度, d为增量序列1,2,…,m-1,且 = i 。
    设关键码集为 {47,7,29,11,16,92,22,8,3},哈希表表长为11,Hash(key)=key % 11,用线性探测法处理冲突,构造哈希表如下表所示:
0 1 2 3 4 5 6 7 8 9 10
11 22 47 92 16 3 7 29 8

47,7,11,16,92均是由哈希函数得到的没有冲突的哈希地址,因而是直接存入的。Hash(29)=7,哈希地址上冲突,需寻找下一个空的哈希地址:
H1 = ( Hash(29) + 1 ) % 11 = 8,哈希地址8为空,所以将29存入。
另外,22,8同样在哈希地址上有冲突,也是由 找到空的哈希地址的;而Hash(3)=3,哈希地址上冲突,因为:
H1 = ( Hash(3) + 1 ) % 11 = 4,仍然冲突
H2 = ( Hash(3) + 2 ) % 11 = 5,仍然冲突
H3 = ( Hash(3) + 3 ) % 11 = 6,找到空的哈希地址,存入。
线性探测法可能使第i个哈希地址的同义词存入第i+1个哈希地址,这样本应存入第i+1个哈希地址的元素变成了第i+2个哈希地址的同义词……因此,可能出现很多元素在相邻的哈希地址上“堆积”起来,大大降低了查找效率。为此,可采用二次探测法,或再哈希函数探测法,以改善“堆积”问题。

  • ② 二次探测法
    Hi = ( Hash(key) + di ) % m
    其中,Hash(key)为哈希函数,m为哈希表长度, d为增量序列1^2-1^22^2-2^2,…,q^2-q^2q \leqslant \frac{m }{2 }
    仍对前面例子的关键码序列{47,7,29,11,16,92,22,8,3},用二次探测法处理冲突,构造哈希表如下表所示。
0 1 2 3 4 5 6 7 8 9 10
11 22 3 92 16 7 29 8

与关键码寻找空的哈希地址只有3这个关键码不同,Hash(3)=3,哈希地址上冲突,由[图片上传失败...(image-c7d04d-1609756554547)]
H1 = ( Hash(3) + 1^2 ) % 11 = 4,仍然冲突
H2 = ( Hash(3) - 1^2 ) % 11 = 2,找到空的哈希地址,存入。

  • ③ 再哈希法
    Hi = ( Hash(key) + i * ReHash(key) ) % m
    其中,Hash(key),ReHash(key)是两个哈希函数,m为哈希表长度。
    再哈希法,先用第一个函数Hash(key)对关键码计算哈希地址,一旦产生地址冲突,再用第二个函数ReHash(key)确定移动的步长因子,最后,通过步长因子序列由探测函数寻找空的哈希地址。
    比如,Hash(key)=a时产生地址冲突,就计算ReHash(key)=b,则探测的地址序列为:
    H1 = ( a + 1 *b ) % m,仍然冲突
    H2 = ( a + 2 *b ) % m,仍然冲突
    H3 = ( a + 3 *b ) % m,找到空的哈希地址,存入。

2、链地址法:

哈希值相同的数据元素存放在一个链表中,在查找哈希表的过程中,当查找到这个链表时,必须采用线性查找方法。这样的好处是,不怕冲突多;缺点是降低了散列结构的随机存储性能。本质是用单链表结构辅助散列结构的不足。
链地址法又称拉链法,设哈希函数得到的哈希地址域在区间[0,m-1]上,以每个哈希地址作为一个指针,指向一个链,即分配指针数组:
ElemType eptr[m];
建立m个空链表,由哈希函数对关键码转换后,映射到同一哈希地址i的同义词均加入
eptr[i]指向的链表中。
对关键码序列为 {47,7,29,11,16,92,22,8,3,50,37,89,94,10},哈希函数为Hash(key)=key % 11,用拉链法处理冲突,建表下所示。

链地址法

3、建立一个公共溢出区

设哈希函数产生的哈希地址集为[0,m-1],则分配两个表:
一个基本表ElemType base_tbl[m];每个单元只能存放一个元素。
一个溢出表ElemType over_tbl[k];只要关键码对应的哈希地址在基本表上产生冲突,则所有这样的元素一律存入该表中。
查找时,对给定值kx通过哈希函数计算出哈希地址i,先与基本表的base_tbl[i]单元比较,若相等,查找成功;否则,再到溢出表中进行查找。

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

推荐阅读更多精彩内容