我理解的Hash函数

最近出现了好几篇围绕着hash而发出来的文章。我尝试去学一下什么是hash。貌似围绕着这个有很多概念。

1. 概念

 Hash,一般翻译做“散列”,也有直接音译为“哈希”的。

2. Hash table 哈希表

它是基于高速存取的角度设计的,也是一种典型的“空间换时间”的做法。

这种数据结构能提供快速插入操作和查找操作。 时间复杂度是O(1). 树的复杂度是O(N)。缺点是基于数组,难于扩展。

其中重要的概念是如何把关键字转换成数组的下标,这个转换过程就要利用到Hash 函数。

这里有个常用的操作就是取余,例如:把一个199(largeNumber)的数据压缩到一个10(smallRange)的大小,那就除以10取余。

表达式为: smallNumber = largeNumber % smallRange.

压缩率是  largeNumber/smallRange.

解决数组下标冲突的方法,通常有 开放地址法链地址法

附上一个开放地址法中的查找函数,从这里就可以看到开放地址法的存储方案:

哈希表的大小的选择更合适的是素数。填充量不超过整个hash标的一半,最多到三分之二。

这是我想之后的素数研究的重要性,以前在学各种专业数学课程的时候,素数研究是很多数学家玩的游戏,没想到在哈希表大小选择上,用处那么大,例如上面的安利, smallRange选择为11比10会好很多。

3. Hash函数描述

value = hash(key),我们希望key和value之间是唯一的映射关系。

Hash(散列、杂凑)函数,是将任意长度的数据映射到有限长度的域上。Hash 函数(或者成为散列函数)也可以看成是单向函数的一个逼近。即它接近于满足单向函数的定义。

单向函数是:如果某个函数在给定输入的时候,很容易计算出其结果来;而当给定结果的时候,很难计算出输入来。

我认为: 这是一种从数据重新表达上的描述,他能实现数据的重新表达,data representation。

一个好的Hash函数(包括大多数加密Hash函数)要具有快速的计算速度和均匀的真正随机输出,因而平均只需要一两次探测(依赖于装填因子)就能找到目标。同样重要的是,随机Hash函数不太会出现非常高的冲突率。在很多情况下,heuristic Hash 函数所产生的冲突比随机Hash 函数少的多。在数据重新表达里面,我们却想去找这种相似性。与传统的Hash 算法的思想是不同的。​​​​​​​

常见的几个简单的hash函数可以简单的划分为如下几类:具体code链接
1. 加法Hash; 2. 位运算Hash; 3. 乘法Hash;4. 除法Hash;5. 查表Hash;6. 混合Hash;

虽说好的hash能极大程度地避免冲突,但是冲突是在所难免的。所以无论用哪种hash函数,都要加上处理冲突的方法。

猜你喜欢

转载自blog.csdn.net/weixin_42067234/article/details/81159797
今日推荐