哈希表原理详解

文章目录

  • 概述
  • 1. 哈希表介绍
      • 哈希表由来
      • 1.1 哈希表定义
      • 哈希表造表过程
      • 哈希表查找过程
      • 总结
  • 应用场景

概述

介绍哈希表(散列表)相关原理。

1. 哈希表介绍

哈希表由来

在哈希表出现之前,已经存在了两种数据结构–数组和链表,但是各有优缺点,适用场景也不同:

类型 优缺点
数组 寻址容易,插入和删除困难
链表 寻址困难,插入和删除容易

那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?答案是肯定的,这就是我们要介绍的哈希表,哈希表有多种不同的实现方法。

这里的多种实现方法,是针对哈希函数以及碰撞解决方法而言的,这也是为什么我们前面要介绍它们的元婴。

具体来说,哈希函数会按key生成对应的哈希值,再转换成数组下标,这当中难免会产生相同的数组下标,这个时候就需要采用哈希冲突的解决方法,例如采用链地址法生成的HashTable:
哈希表原理详解_第1张图片
左边很明显是个数组,数组的每个成员包括一个指针,指向一个链表的头,当然这个链表可能为空,也可能元素很多。

1.1 哈希表定义

哈希表(也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

哈希表造表过程

哈希表hashtable(key,value) 就是把Key通过一个固定的算法函数既所谓的哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里。

在将value(也就是下图的元素)存储到

哈希表原理详解_第2张图片

哈希表查找过程

当使用哈希表进行查询的时候,就是再次使用哈希函数将key转换为对应的数组下标,并定位到该空间获取value,如此一来,就可以充分利用到数组的定位性能进行数据定位。

总结

总结一下,对于哈希表来说,先按指定的key生成的哈希值,而表中存储的value是你要存储的数据。具体来说,比如我要存储<“张三”,2016220202>到哈希表中,假设key是"张三",要存进去的是整个将那么实际上,采用的方法是,使用哈希函数 H(“张三”)生成 哈希值,进而生成数组下标(假设是25),这样需要存储的数据----<“张三”,2016220202>----就能存储在数组中了。

但是,难免出现同名的也叫"张三"的人,这个时候,则用特定的冲突解决方法来处理。(假设采用的是链地址法,那么就也会存储到数组下标为25的链地址空间中去。)

而在访问的时候,比如我们想要查找"张三",实际上,也是通过哈希函数和数组下标转换操作,从而得到存储"张三"的那个数组下标,这样就能访问到数组中存储的value–<“张三”,2016220202>。

如果不是采用这种方法,在最坏的情况下,我们需要遍历整个数组,并进行字符串比较,看看有没有叫"张三"的,而使用哈希表,只需要一点额外的计算哈希值以及数组下标的时间,就能直接定位到数据的存储地址了。

应用场景

场景
说明
关联数组 哈希表通常用于实现许多类型的内存表。
它们用于实现关联数组(索引是任意字符串或其他复杂对象的数组)。
数据库索引 哈希表也可以用作基于磁盘的数据结构和数据库索引(例如在dbm中)。
高速缓存 哈希表可用于实现高速缓存,即用于加速对数据的访问的辅助数据表,其主要存储在较慢的介质中。
对象表示 一些动态语言(如Perl,Python,JavaScript和Ruby)使用哈希表来实现对象。
提升速度 哈希函数用于各种算法,以使其计算更快。

你可能感兴趣的:(数据结构)