什么是哈希hash

哈希Hash

什么是Hash

通过一些计算,把关键码值映射到数组中的位置来访问记录,这个过程称为散列(hash)。

重要组成:

  • hash函数:把关键码值映射到位置的函数称为散列函数。用h表示。
  • hash表:存放记录的数组称为散列表。用HT表示。
  • 槽(slot):散列表中的一个位置称为一个槽。

设计hash表的目标是:使得对于任何关键码值K和某个散列函数h,i=h(K)是表中满足0<=h(K)<M(M为HT中槽的数目)的一个槽,并且记录在HT[i]存储的关键码值与K相等。

冲突解决

在实际情况中,我们根据散列方法组织的数据库必须把存储的记录存放在不大的散列表中,以避免浪费过多的空间。这样的话,有可能有多个关键码值计算出来的h(K)是一样的,但又不能同时放在同一个槽中,此时就要使用冲突解决策略。

冲突解决策略

冲突解决策略一般分为两类:

  • 开散列方法(open hashing;也称为单链方法)
  • 闭散列方法(closed hashing;也称为开地址方法)
开散列方法

开散列方法的最简单形式把散列表中的每个槽定义为一个链表的表头,散列到一个槽的所有记录都放在这个槽的链表内。
在这里插入图片描述

闭散列方法

闭散列方法把所有记录直接存储到散列表中。每条关键码值标记为kR,记录R有一个基槽,就是h(kR),即由散列函数计算出来的槽。如果要插入一条记录R,而另一条记录已经占据了R的基槽,那么就把R存储在表的其他槽内。

桶式散列
  • 一种实现闭散列的方法是把散列表中的槽分成多个桶(bucket)。把散列表中的M个槽分成B个桶,每个桶中包含M/B个槽。
  • 散列函数把每一条记录分配到某个桶的第一个槽中。
  • 如果这个槽已经被占用,那么就顺序地沿着桶查找,直到找到一个空槽。
  • 如果一个桶全部被占满了,那么就把这条记录存储在表后具有无限容量的溢出桶(overflow bucket)中。

在这里插入图片描述

线性探查

最常用的散列方法。当发生冲突时,从当前基槽开始往后查找,有空位则将记录放进去。例如,2037原本应放在7的槽中,但是7已经被占用,所以往后查找空位,8是空的,于是将2037放进去。

在这里插入图片描述

但是这种方法会导致基本聚集。例如在上例中,下一条记录放到第2个槽的概率就是6/10了,因为取模后值为7,8,9,0,1,2都会放到第2个槽中。在理想情况下,表中的每个空槽都应该有相同的机会接受到下一个要插入的记录。

改进的冲突解决方法

如何避免基本聚集呢?

一种可能的改进方式是仍然使用线性探查,但是跳过一些槽,而且每次跳过常数c个而不是1个槽。这会生成探查函数:P(K,i)=ci

例如,如果常数c是2的话:如果基槽被占用的话,第一次会找基槽+2的位置,看是否被占用,如果被占用了,第二次会找基槽+4的位置,如果还是被占用,则找基槽+6的位置,以此类推。即从基槽开始的偏移量将会为2,4,6。

另一种方法是使用二次探查函数(对于某些常数c1,c2,c3):p(K,i)=c1i<sup>2</sup>+c2i+c3。一个最简单的变体就是p(K,i)=i<sup>2</sup>

例如,对于一个长度M=101的散列表,假定对于关键码k1和k2,h(k1)=30,h(k2)=29。k1的探查序列为30,31,34,39;k2的探查序列为29,30,33,38。这样,尽管k2会在第二步探查k1的基槽,这两个关键码的探查序列此后就立即分开了。

双散列方法

即由两个散列函数,一个散列函数用于计算基槽,另一个散列函数用于确定线性探查中的常数。即线性探查此时的形式为:p(K,i)=i*h2(K)

例如,假定散列表的长度是M=101,有3个关键码k1,k2,k3,h(k1)=30,h(k2)=28,h(k3)=30,h2(k1)=2,h2(k2)=5,h2(k3)=5。那么k1的探查序列为:30,32,34,36等;k2的探查序列为:28,33,38,43等;k3的探查序列为:30,35,40,45等。这样关键码之间就不会共享同一段探查序列了。

### 哈希的定义 哈希是一种通过特定算法将任意长度的数据映射为固定长度值的技术[^1]。这个过程通常由哈希函数完成,其核心目标是以高效的方式生成唯一的数值表示形式。哈希值也被称为散列值或消息摘要。 #### 哈希表的基本原理 哈希表是一种基于键值对存储数据的数据结构,利用哈希函数将键转换为数组索引位置来实现高效的插入、查找和删除操作[^1]。它的基本工作流程如下: - 键通过哈希函数计算得出一个哈希码。 - 使用该哈希码定位到具体的存储地址。 - 如果发生冲突(多个键对应同一个地址),则采用链地址法或其他策略解决。 ### 哈希在计算机科学中的应用 #### 数据完整性验证 哈希广泛应用于文件校验中,比如MD5算法可以用来检测文件传输过程中是否发生了篡改或损坏[^2]。通过对原始文件和接收后的文件分别计算它们的MD5哈希值并对比两者的一致性即可判断是否有误。 ```python import hashlib def file_hash(file_path): md5 = hashlib.md5() with open(file_path, 'rb') as f: while chunk := f.read(8192): # Read the file in chunks to handle large files. md5.update(chunk) return md5.hexdigest() print(f"The MD5 hash of your file is {file_hash('example.txt')}") ``` 此代码片段展示了如何使用Python标准库`hashlib`模块中的md5方法来获取某个本地文件的内容摘要[^3]。 #### 密码安全保护 为了防止密码明文泄露,在现代信息系统设计里普遍会先对用户的登录口令执行单向加密运算后再保存至数据库内;当用户再次尝试登陆时只需重复相同的变换逻辑重新生成密钥并与记录相匹配即可确认身份合法性而不必暴露真实字符序列本身。 #### 查找去重 在一个大型分布式环境中寻找重复项或者统计唯一项目数量的时候也可以借助于布隆过滤器这样的概率型数据结构配合简单的哈希机制达成目的——既节省空间又能满足一定精度需求下的高速检索要求。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值