数据结构之--哈哈哈哈哈希表

366 阅读5分钟

——写在前面

这是一个精简版的哈希表介绍,所列举的信息都是最常用的哈希表知识,个人认为知道这些再加上一个灵活变通的大脑,就可以轻松驾驭哈希表啦~✨

一、什么是Hash表

要想知道什么是哈希表,那得先了解 哈希函数

如果有一种函数,根据这个函数和查找关键字key,可以直接确定查找值所在位置,而不需要一个个比较。这种函数就叫做哈希(Hash)函数。

即:地址index=Hash(key),而哈希表是基于哈希函数建立的一种查找表。哈希表包括地址、关键值(和一些可有可无的关键值的小弟们)。 举例来讲就是这样的:

大家好😁,我是哈希表
地址1 我是键1 我是键1的小弟一号 我是键1的小弟二号 …… 我是键1的小弟n号
地址2 我是键2 我是键2的小弟一号 我是键2的小弟二号 …… 我是键2的小弟n号
地址n …… …… …… …… ……

二、哈希函数的构造方法

哈希函数的构造方法有很多种,如果可以,你自己也可以创造出适合你要存储的数据的专属哈希函数。具体方法有:直接定制法数字分析法平方取中法折叠法除留余数法等等。这里只讲使用最广泛的一种——除留余数法。如果想知道其他方法的,可以出门右转👉别人家的博客(本博客的参照博客)。

除留余数法:Hash(key)=key % p (p<=m;m为表长,%为取余)

此方法的精髓在于p的取值,为了避免哈希冲突(下方有介绍),比如我们存储3 6 9,那么p就不能取3因为 3 % 3 === 6 % 3 ===9 % 3===0,这样这三个数就都被存在了同一个地址 #0 里。所以,p应为不大于m的质数或是不含20以下的质因子的合数,这样可以减少地址的重复(冲突) 上栗子: 比如key = 7,39,18,24,33,21时取表长m为9 p为7 那么存储如下(Hash(key)=key%7)

index key 冲突的key
0 7 21(地址冲突)
1
2 33
3 24
4 39 18(地址冲突)
5
6
7
8

综上,hash函数设计要考虑的因素有:

  1. 计算散列地址所需要的时间(即hash函数本身不要太复杂)
  2. 关键字的长度
  3. 表长
  4. 关键字分布是否均匀,是否有规律可循
  5. 设计的hash函数在满足以上条件的情况下尽量减少冲突

三、哈希冲突

即不同key值产生相同的地址,Hash(key1)=Hash(key2) 比如我们上面说的存储3 6 9,p取3是 3 % 3 === 6 % 3 === 9 % 3 此时3 6 9都发生了hash冲突。

哈希冲突的解决方案

不管hash函数设计的如何巧妙,总会有特殊的key导致hash冲突,特别是对动态查找表来说。 hash函数解决冲突的方法有: 开放定制法、链地址法、公共溢出区法、再散列法

公共溢出区法

建立一个特殊存储空间,专门存放冲突的数据。此种方法适用于数据和冲突较少的情况。

再散列法

准备若干个hash函数,如果使用第一个hash函数发生了冲突,就使用第二个hash函数,第二个也冲突,使用第三个…… 重点了解一下开放定制法和链地址法

开放定制法(看不懂文字解释就看例子)

如果Hash(key)=Hash(keyi) 那么key2存储位置Hash(keyi)=(Hash(key)+di)%m (m为表长,di为增量)

di有三种取法
  1. 线性探测再散列——di=c∗i (c为你喜欢的常数)
  2. 平方探测再散列——di=1^2,−1^2,2^2,−2^2 (平方探测表长有限制:表长m必须为4j+3的质数)
  3. 随机探测在散列(双探测再散列)——di是一组伪随机数列(随机探测di有限制:随机探测时m和di没有公因子)
上栗子🌰:

有一组数据19 01 23 14 55 68 11 86 37要存储在表长11的数组中,其中H(key)=key MOD 11。

链地址法

产生hash冲突后在存储数据后面加一个指针,指向后面冲突的数据 上面的例子,用链地址法则是下面这样:

四、hash表的查找

查找过程和造表过程一致。

hash表的查找效率

S为平均查找长度, α=n/m(n表示实际装载数据长度,m为表长)

假设我现在有10个数据,想使用链地址法解决冲突,并要求平均查找长度<2

那么有 1+α/2 <2 👉 α<2 👉 即 n/m<2 (n=10) 👉 m>10/2 👉m>5

👉即:采用链地址法,使得平均查找长度< 2 那么m>5

五、hash表的删除

首先链地址法是可以直接删除元素的,但是开放定址法是不行的,拿前面的双探测再散列来说,假如我们删除了元素1,将其位置置空,那 23就永远找不到了。正确做法应该是删除之后置入一个原来不存在的数据,比如-1

六、参考博客:

CSDN博主「洌冰」的原创文章