哈希表(Hash Table)与哈希算法

概述

  哈希表(Hash Table)也叫做散列表,根据关键码值(key value)可以快速存取访问的一种空间换时间的数据结构。它通过把关键码值通过映射函数计算到表中一个位置来访问记录,可以加快查找到速度。这个映射函数叫做散裂函数(Hash Function),存放记录的数组叫做哈希表(或散列表)。

  举个例子比如我们想想在14亿个身份证号码中找出其中一个身份证号,我们肯定不可能一个个去找,而我们可以将14亿条数据存放在哈希表中,然后根据哈希表结构就可以快速找到要找的数据。所以哈希表就是这种能够通过给定的关键字的值直接访问到具体对应的值的一个数据结构。也就是说把关键字映射到一个表中的位置来直接访问记录,以加快访问速度。

  我们把这个关键字称为 Key,把对应的记录称为 Value,它们是一一对应的。

 

 哈希表的应用

   1. 在编程语言中,如Golang中的字典(map),PHP里的数组(array),Java中的Map等它们底层都是使用哈希表来实现的。

   2. Redis中的字典及键值对存放。

   3. 缓存(Lru Cache)。

 

哈希表工作原理

  

 

   哈希表是根据哈希函数来决定你要存放的数据所在的位置。上图字符串lies传递给哈希函数,经过计算返回给的下标是9,那么就讲lies存放在9这个下标的位置,其它的存放都是这样的过程。

   这里面最重要的就是上面这个哈希函数,因为哈希函数决定数据应该被存放在什么地方。有很多种哈希函数,其中一种比较简单的:把要存储的数据每个字符的ASCII码相加,再去除余(mod)某个数,余数就是存储的位置。当然现实中的哈希函数比这个复杂多,而且哈希函数的性能比较好的话,可以让计算出来的值比较分散,而不会发生碰撞,比如有可能两个不同的数据,但是最后计算出来的位置相同,像上图lies字符串计算后得到9,那么其它的字符串计算后也有可能等于9,这种情况就称为“哈希碰撞”

 

哈希算法

  哈希表之所以这么高效,可以快速从海量数据中查到某一条数据,这其中就使用到了哈希算法。我们知道哈希表的工作机制是根据Key访问一个映射表来得到 Value 的地址,而这个映射表就叫作散列函数或者哈希函数,实现该函数的算法就是哈希算法。

 

常见哈希算法

  1. 直接寻址法(direct-address table):取关键字或关键字的某个线性函数值为散列地址。

  2. 数字分析法:通过对数据的分析,发现数据中冲突较少的部分,并构造散列地址。例如同学们的学号,通常同一届学生的学号,其中前面的部分差别不太大,所以用后面的部分来构造散列地址。

  3. 平方取中法 (midsquare method) :当无法确定关键字里哪几位的分布相对比较均匀时,可以先求出关键字的平方值,然后按需要取平方值的中间几位作为散列地址。这是因为:计算平方之后的中间几位和关键字中的每一位都相关,所以不同的关键字会以较高的概率产生不同的散列地址。

  4. 取随机数法:使用一个随机函数,取关键字的随机值作为散列地址,这种方式通常用于关键字长度不同的场合。

  5. 除留取余法:取关键字被某个不大于散列表的表长 n 的数 m 除后所得的余数 p 为散列地址。这种方式也可以在用过其他方法后再使用。该函数对 m 的选择很重要,一般取素数或者直接用 n。

 

 哈希表性能分析

   哈希表的性能是由其选择的哈希算法决定的,哈希表之所以查找中效率很高,是因为它的时间复杂度为O(1),但是也不是总是为O(1),因为在实际使用中,随着数据量的增大,数据冲突是不可避免的。

 

posted @ 2020-07-03 16:41  songguojun  阅读(1761)  评论(0编辑  收藏  举报