[知识点] 7.2 哈希表
Posted jinkun113
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[知识点] 7.2 哈希表相关的知识,希望对你有一定的参考价值。
前言
很久很久以前经常听到哈希这个词,后来多多少少有所接触,但并未系统地了解过哈希到底是怎么回事。
子目录列表
1、哈希表与数组
哈希表(hash table),又称为散列表,是根据关键码值(key)直接进行访问的一种数据结构,也就是说,给定一个 key,则可以通过哈希表的映射关系快速找到其对应的值(value)。这听起来似乎和数组是一个意思 —— 对于数组 a = {2, 5, 8},其元素 a[1] = 2, a[2] = 5, a[3] = 8,没错,数组本身就是一种 key-value 的对应关系,每个元素的编号为 key,值为 value —— 而哈希表在数组的基础上有什么改进?
2、哈希函数
给定一个哈希表,存在函数 f(key),对任意给定的 key 值,通过代入这个函数就能得到包含该 key 的记录在表中的地址,则这个函数叫做哈希函数。哈希的目的是让本来复杂的数据以简单的方式体现或访问,举个例子:给定 10 个同年同月同日同地出生的人的身份证号码,并为这些号码编一个号以便以后使用,比如:
a[320115********0105] = 1 a[320115********8577] = 2 ... a[320115********5201] = 10
显然,开一个 18 位数大小的数组是不现实的,我们决定将这些数进行哈希——由于这些号码前 14 位都是相同的,我们将这 18 位的 key 值取后 4 位来替换原 key 值进行各类操作,一下就变得现实起来了:
a[105] = 1 a[8577] = 2 ... a[5201] = 10
而后我们需要输出或其他情况时,把前 14 位还原即可。
所以,在生活中,我们常说的手机尾号便是手机号的哈希值,假设尾号为 4 位,其哈希函数为 f(key) = key % 10 ^ 4;小明在学校的学号为 1810141728,而在班上提交作业时使用的学号为 28,本质是完整学号的哈希值,哈希函数为 f(key) = key % 100。
而对于普通的数组,可以理解成哈希函数为 f(key) = key。
那么,如何构造一个哈希函数?有什么要求?
3、哈希冲突
上面举的几个例子中,10 个身份证号码的后 4 位理论上是不会有重复的;小明在班上交作业,班上也不会有和他一样尾号为 28 的;但对于手机尾号,假设张三的手机号为 155****1666,李四的手机号为 189****1666,那么他们在讨论手机号时,肯定不会用后 4 位尾号,因为并不能分清到底是谁的手机号,对于这种两个不同的原值通过哈希函数得到的哈希值相同的情况,我们称之为哈希冲突。
对于所有情况,哈希函数如何定义并无规定,但显然,我们要保证不出现哈希冲突的情况,或者尽可能少到忽略不计,即保证其哈希结果的正确性。而正确性与空间占用往往是成反比的,其正确性越高,哈希值范围越大, 所占用的空间也就越大,所以我们需要在其中找到平衡点,下面介绍几种常见的构造哈希函数的方法。
4、构造哈希函数
① 直接寻址法
取 key 或 key 的某个线性函数值作为哈希值,即 f(key) = a * key + b。
构造方便,但适用范围不广。
举例:
小明统计这次高数考试成绩,每 10 分为一个分段。分数为 key,分数段人数为 value,则哈希函数可以设定为 f(key) = 0.1 * key,通过哈希使 key 范围缩小至 1 / 10。
② 数学分析法
通过对 key 值的分析,找到最不可能出现冲突的构造方式,上述的手机尾号、学号等直接 key 值取模便是属于这种。
③ 平方取中法
求出 key 值的平方,取该平方值的中间几位作为哈希值。听起来也是个比较玄学的构造方法,当然取最中间的数也是不无道理的 —— 它们和 key 的每一位都会相关,出现冲突的概率较低。由于存在平方操作,key 值不能过大。
举例:
key = 77777,key ^ 2 = 6049261729,f(key) 可以取 9261。?
④ 折叠法
将 key 值按照数位平均切割为若干部分,求出每一部分各个数位之和,最后将这些和首尾相连,得到 f(key)。
举例:
key = 123456789,可以拆分成 123, 456, 789,分别求和为 6, 15, 24,再合并成 61524,即 f(key)。
⑤ 随机数法
选择一个随机函数,取随机值作为哈希值,即 f(key) = random(key)。
随机大法好。
⑥ 除留余数法
取 key 被某个
5、字符串 hash
上述所有哈希方法都是整数与整数之间的映射,但哈希的适用范围绝不局限于此。
以上是关于[知识点] 7.2 哈希表的主要内容,如果未能解决你的问题,请参考以下文章