程序员常说的「哈希表」是个什么鬼?

「哈希表」主要做用在于高效查找。算法

  在编程实现中,经常面临着两个问题:存储和查找,存储和查找的效率每每决定了整个程序的效率。编程

脑补下,你在家里忘记了指甲刀放在哪里,一般要在你家全部抽屉中顺序寻找,直到找到,最差状况下,有N个抽屉,你就要打开N个抽屉。这种存储方式叫数组,查找方法称为「遍历」。数组

脑补下,你是一个整理控,全部物品必须分门别类放入整理箱,再将整理箱编号,好比1号放入针线,2号放入证件,3号放入细软。数据结构

  这种存储和查找方式称为「哈希」,若是这个时候要查找护照,你不准要再翻全部抽屉,直接可在2号整理箱中获取,一般只用一次查找便可,如何编号整理箱,称为哈希算法。函数

一样是查找,差距怎么那么大涅~,假设咱们有100亿条数据记录,那差距就变得明显,遍历须要查找最多100亿次,最少1次,哈希只需1次。设计

让咱们正式介绍哈希和哈希算法,哈希也称散列,哈希表是一种与数组、链表等不一样的数据结构,与他们须要不断的遍历比较来查找的办法,哈希表设计了一个映射关系f(key)= address,根据key来计算存储地址address,这样能够1次查找,f既是存储数据过程当中用来指引数据存储到什么位置的函数,也是未来查找这个位置的算法,叫作哈希算法。hash

  让咱们举个例子,好比下面这几我的物,按数组存储: 余罪(133123111243)=>傅老大(13888888888)=>沈嘉文(13452342349)=>大胸姐(13890380934) 这样我要找到大胸姐的电话号码,须要顺序查找对比整个数组,第一个余罪,不是,第二个不是,第三个不是,直到第四个找到大胸姐。效率

  若是以hash存储呢?首先让咱们来看看如何设计哈希算法,哈希算法能够随意设计,教科书上通常会说如下几种方法:直接定址发,平方取中法,除数取余法,哈希算法的本质上是计算一个数字,若是用这几种方法讲解会稍显晦涩,咱们假设咱们的哈希算法是取姓名的首字母。因此f(余罪) = y, f(傅老大) = f,f(沈嘉文) = s,f(大胸姐) = d。 构建的hash表以下: a b c y .133123111243 d .13890380934 g z 位置7 f .13888888888 s .13452342349 咱们看到他们分别以姓名首字母的位置插入到这一张表格中,这样咱们构建了这样一个Key-Value表格,此表就是哈希表,也称为Hash Table。将来,当咱们要查找余罪的时候,经过计算,余罪在y位置,能够经过1次查找,找到这条记录,也即手机号。遍历

这个时候有客官问了,那以首字母为哈希函数的话,应该有不少好比以y的姓名啊,这个时候就不是一次查找了吧,其实有不少条记录都映射到一个位置上,称为哈希冲突。程序

哈希冲突是跟哈希函数的设计正相关的,你的随机性越大,那么产生哈希冲突的可能性越小,在小几率下,若是还有冲突怎么办,这个时候要作些有损的设计,好比若是有两个首字母为y的姓名,那么能够接到余罪的后面,当查找的时候,须要先查找到y,而后再顺序查找,以下所示: a b c y .133123111243 1332232323于谦 d .13890380934 g z 位置7 f .13888888888 s .13452342349 还有一些解决哈希冲突的办法叫「哈希再哈希」,也就是针对第一次哈希的结果再进行一次hash来减少冲突的几率。

   这就是Hash表,首先Ta是一种数据结构,是一种效率极高的查找方式,哈希表的核心在于哈希函数的设计,哈希冲突了没关系,咱们要增长随机性以及对冲突进行适当的有损化的处理。

相关文章
相关标签/搜索