哈希冲突解决方法


解决哈希冲突两种常见的方法是:闭散列和开散列

一、闭散列

闭散列法又称开放地址法,当发生哈希冲突时,如果哈希表未满,说明其中必然还有空位置,可以把 key 存放到表中 “下一个” 空位置中去,那如何寻找 “下一个” 空位置?

1、线性探测

从发生冲突的位置开始,依次继续向后探测,直到找到空位置为止

int a[ ]  = {37, 25, 14, 36, 49, 68, 57, 11, 19};
int HashFunc(int key)
{
  return key % 19;
}

在这里插入图片描述

2、二次探测

Hi = (H0 ± i^2) % 哈希表长度,其中,H0 = HashFunc(key),i = 1, 2, …

int a[ ]  = {37, 25, 14, 36, 49, 68, 57, 11, 19};
int HashFunc(int key)
{
  return key % 19;
}

在这里插入图片描述

3、双重哈希

Hi = (H0 + i * H1) % 哈希表长度,其中,H0 = HashFunc1(key),H1 = HashFunc2(key),i = 1, 2, …

注意

删除操作

二、开散列

开散列法又称链地址法(开链法),将具有相同哈希地址的关键码使用链表等数据结构进行存储

int a[ ]  = {37, 25, 14, 36, 49, 68, 57, 11, 19};
int HashFunc(int key)
{
  return key % 17;
}

在这里插入图片描述
使用哈希函数计算出每个元素所在的桶号,同一个桶的链表中存放哈希冲突的元素,各链表的头结点存储在哈希表中

三、负载因子 α

α = 哈希表中元素个数 / 哈希表长度

注意

负载因子对闭散列尤为重要,应严格限制在 0.7 ~ 0.8 以下(超过 0.8,查找时 CPU 缓存不命中次数呈指数级上升),当然对于开散列,负载因子也不应过大,避免桶过深

// 使用素数表对齐做哈希表的容量,降低哈希冲突      
const int _PrimeSize = 28;      
static const unsigned long _PrimeList[_PrimeSize] =     
  {         
	53ul,         97ul,         193ul,       389ul,       769ul,         
	1543ul,       3079ul,       6151ul,      12289ul,     24593ul,         
	49157ul,      98317ul,      196613ul,    393241ul,    786433ul,         
	1572869ul,    3145739ul,    6291469ul,   12582917ul,  25165843ul,         
	50331653ul,   100663319ul,  201326611ul, 402653189ul, 805306457ul,         
	1610612741ul, 3221225473ul, 4294967291ul     
  }; 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值