python-哈希表

哈希表,哈希函数
哈希表是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做哈希函数,存放记录的数组叫做哈希表。
给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

Python 中的哈希码:
在python中计算哈希码的标准机制是一个内置签名hash(x)函数,该函数将返回一个整型值作为对象x的哈希码。然而在Python中,只有不可变的数据类型是可哈希的。这个限制是为了确保在一个对象的生命周期期间,其哈希码保持不变。这是对于对象在哈希表中作为键一个重要属性

压缩函数
通常,键k的哈希码不会直接适合使用一个桶数组,因为整数哈希码可能是负的或可能超过桶数组的容量。因此,当我们决定对于一个对象k的键使用整数哈希码时,还有一个问题就是需要把整数映射到[0,N-1]区间上。这称为压缩函数
划分方法
一个简单的压缩函数是划分方法,它将一个整数i映射到N:
i mod N(N是桶数组的大小,是一个固定的整数)
如果将n设置为一个小于等于表长的素数,那么这个压缩函数有助于传播哈希值的分布即减少冲突 但事实上选择N为素数并不总能充分地解决问题

MAD 方法
有一个更复杂的压缩函数可以帮助一组整数键消除重复模式
这个方法通过 [(ai+b)mod p]mod N 对i进行映射,这里N是桶数组的大小,p是比N大的素数,a和b是从区间[0,p-1]任意选择的整数,并且a>0 这个压缩函数可以使得任意两个不同键冲突的概率为1/N

冲突处理方案
冲突是指两个不一样的键经过哈希函数映射后得到的哈希码可能一样。

解决方案
1分离链表
处理冲突的一个简单并且有效的方式是使每个桶存储其自身的二级容器,容器中存储所有元组(k,v) 使f(k)=j j是哈希表的索引
在这里插入图片描述2开放寻址
开放寻址法把所有的元素都存放在散列表中,也就是每个表项包含动态集合的一个元素。在开放寻址法中,当要插入一个元素时,可以连续地检查散列表的个各项,直到找到一个空槽来放置这个元素为止。检查顺序可以是线性的,可以是二次的,也可以是再次散列的。

线性探测:使用线性探测方法时,如果我们想要将一个元组(k,v)插入到桶A[j]处,在这里j=h(k),但A[j]已经被占用,那么尝试将它插入A[(j+1)mod N];若A[(j+1)mod N]也被占用,则尝试插入A[(j+2)mod N],如此重复操作,直到找到一个可以接受新元组的空桶

二次探测: 使用二次探测方法时,将反复探测桶A[(h(k)+f(i))mod N],i=0,1,2,…其中f(i)=i^2,直至发现一个空桶

双哈希策略: 在这种方法中,我们选择一个二次哈希函数h’,如果函数h将一些键k映射到已经被占据的桶A[h(k)]中,则我们将迭代探测桶A[h(k)+f(i))mod N],i=0,1,2,…其中f(i)=i*h’(k).在这种情况下,不允许将二次哈希函数设为0.h’(k)=q-(k mod q) 是一个常用的函数,其中对于素数q满足q<N,且N也应该是素数

另一种避免聚集的开放寻址方法是迭代地探测桶A[h(k)+f(i)) mod N],这里f(i)是一个基于伪随机数产生器的函数,它提供一个基于原始哈希码位的可重复的但是随机的连续的地址探测序列。Python 的字典现在就是使用的这种方法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值