认识算法之数据结构(六)哈希表

1,839 阅读3分钟

哈希表(Hash tables)

什么是哈希表

在介绍哈希表的时候,先回顾一下前几章的内容,再来比较下数组和链表的优缺点。

数组:寻址容易,但插入和删除元素比较麻烦; 链表:插入和删除元素容易,但寻址比较麻烦。

那么有没有一种数据结构是既能结合这两种的优点同时也能避免这两种数据结构所带来的缺点呢?答案是有的,那就是现在所讲的哈希表。
哈希表又称为散列表,是根据关键码值(Key,value)而直接进行访问的数据结构。  
它提供了快速的插入操作和查找操作,无论哈希表总中有多少条数据,  
插入和查找的时间复杂度都是为O(1)
以上是哈希表的定义,其结构示意图如下所示:

从上述结构中我 最左边的为key,通过中间的哈希运算(hash function)从而形成一个有意义的数字下标数组,从而与右边的value/buckets即元素内容形成了一个确定的对应关系。
似乎很难懂这三者(Keys,hash function,buckets)之间的关系,那么就举个例子🌰吧:👇👇👇

怎么正确建立学号(Key)与Value之间的映射关系呢? 我们可以通过这样的哈希运算 学号(key) - 201735020330 所得出的结果即作为存放Value的数组中,比如这个池早香,她的学号是201735020336,通过我们的哈希运算得数组下标值为6,那么我们就可以将其姓名和电话号码放进这个下标值为6的数组中。这样一个简单的哈希表就完成了。

❓ 哈希运算(hash funchion)有特定的运算方式吗?

没有,但为了构造一个好的哈希函数:我们希望hash函数作用在不同的key时,所得到的value能够均匀的分布在hash表中,即能尽可能少的减少地址冲突。比较常见的hash函数的构造方法有:
1)直接定址法 2)数字分析法3)平方取中 4)折叠法5)除留余数法

❓ 刚刚提到了地址冲突,什么是地址冲突?

当你用hash函数作用在两个互不相同的key上,得到的value值相等。这就好比“下面有请王先生上台演讲”,但底下那么多姓王的,不知道叫的是哪个王先生,只好一起上台了。因此正如上面所说,好的哈希运算需要慎重考虑其运算方法,避免出现地址冲突。但万一真的发生怎么办呢?通常有两个办法解决:
  1. 链地址法:
如图所示,采用链表的办法,将冲突的地址内容通过线性表的方式串联起来,然后在这个地址里通过顺序检索查找出我们想要的值。
  1. 开放地址法:
其方法就是找到一个未被占用地址的数组,并将元素存储进去,寻找空地址的方法有很多,而上图的方法就是较为简单线性查找法,从冲突的地址开始,往下搜索空地址。

为什么要用哈希表

1)索引速度快。2)方便数据的增删改查

相比于于数组和链表,如果我们以链表的方式依次查找,面对企业级的上千万的数据是非常耗时耗内存的。而如果我们使用数组的结构进行业务操作也会因删除和插入而浪费很多时间。

哈希表简单的实现