1.2 Hash构造函数的方法

1.2.1 直接定址法:

直接定址法是以数据元素关键字k本身或它的线性函数作为它的哈希地址,即:H(k)=k 或 H(k)=a * k + b ; (其中a,b为常数)

例1,有一个人口统计表,记录了从1岁到100岁的人口数目,其中年龄作为关键字,哈希函数取关键字本身,如图(1):
  
  可以看到,当需要查找某一年龄的人数时,直接查找相应的项即可。如查找99岁的老人数,则直接读出第99项即可。
  
  显然对空间需求较大,这种哈希函数简单,并且对于不同的关键字不会产生冲突,但可以看出这是一种较为特殊的哈希函数,实际生活中,关键字的元素很少是连续的。用该方法产生的哈希表会造成空间大量的浪费,因此这种方法适应性并不强。
  此法仅适合于:地址集合的大小 = 关键字集合的大小,其中a和b为常数。

1.2.2 数字分析法:

假设关键字集合中的每个关键字都是由 s 位数字组成 (u1, u2, …, us),分析关键字集中的全体,并从中提取分布均匀的若干位或它们的组合作为地址。

数字分析法是取数据元素关键字中某些取值较均匀的数字位作为哈希地址的方法。即当关键字的位数很多时,可以通过对关键字的各位进行分析,丢掉分布不均匀的位,作为哈希值。它只适合于所有关键字值已知的情况。通过分析分布情况把关键字取值区间转化为一个较小的关键字取值区间。

例2,要构造一个数据元素个数n=80,哈希长度m=100的哈希表。不失一般性,我们这里只给出其中8个关键字进行分析,8个关键字如下所示:
  
  分析上述8个关键字可知,关键字从左到右的第1、2、3、6位取值比较集中,不宜作为哈希地址,剩余的第4、5、7、8位取值较均匀,可选取其中的两位作为哈希地址。设选取最后两位作为哈希地址,则这8个关键字的哈希地址分别为:2,75,28,34,15,38,62,20。

此法适于:能预先估计出全体关键字的每一位上各种数字出现的频度。

1.2.3 折叠法:

将关键字分割成若干部分,然后取它们的叠加和为哈希地址。两种叠加处理的方法:移位叠加:将分 割后的几部分低位对齐相加;边界叠加:从一端沿分割界来回折叠,然后对齐相加。

所谓折叠法是将关键字分割成位数相同的几部分(最后一部分的位数可以不同),然后取这几部分的叠加和(舍去进位),这方法称为折叠法。这种方法适用于关键字位数较多,而且关键字中每一位上数字分布大致均匀的情况。

折叠法中数位折叠又分为移位叠加和边界叠加两种方法,移位叠加是将分割后是每一部分的最低位对齐,然后相加;边界叠加是从一端向另一端沿分割界来回折叠,然后对齐相加。
  
  此法适于:关键字的数字位数特别多。

1.2.4 平方取中法:

这是一种常用的哈希函数构造方法。这个方法是先取关键字的平方,然后根据可使用空间的大小,选取平方数是中间几位为哈希地址。

哈希函数 H(key)=key2 的中间几位”因为这种方法的原理是通过取平方扩大差别,平方值的中间几位和这个数的每一位都相关,则对不同的关键字得到的哈希函数值不易产生冲突,由此产生的哈希地址也较为均匀。

例4,若设哈希表长为1000则可取关键字平方值的中间三位,如图所示:


此法适于:关键字中的每一位都有某些数字重复出现频度很高的现象.

1.2.5 减去法

减去法是数据的键值减去一个特定的数值以求得数据存储的位置。

例5,公司有一百个员工,而员工的编号介于1001到1100,减去法就是员工编号减去1000后即为数据的位置。编号1001员工的数据在数据中的第一笔。编号1002员工的数据在数据中的第二笔…依次类推。从而获得有关员工的所有信息,因为编号1000以前并没有数据,所有员工编号都从1001开始编号。

1.2.6 基数转换法

将十进制数X看作其他进制,比如十三进制,再按照十三进制数转换成十进制数,提取其中若干为作为X的哈希值。一般取大于原来基数的数作为转换的基数,并且两个基数应该是互素的。

例6:Hash(80127429)=(80127429)13=8* 137+0* 136+1* 135+2* 134+7 * 133+4 * 132+2 * 131+9=(502432641)10
如果取中间三位作为哈希值,得Hash(80127429)=432

为了获得良好的哈希函数,可以将几种方法联合起来使用,比如先变基,再折叠或平方取中等等,只要散列均匀,就可以随意拼凑。

1.2.7 除留余数法:

取关键字被某个不大于哈希表表长m的数p除后所得余数为哈希地址,即设定哈希函数为 Hash(key)=key mod p (p≤m),其中,除数p称作模。
  
  除留余数法不仅可以对关键字直接取模,也可以在折叠、平方取中等运算后取模。对于除留余数法求哈希地址,关键在于模p的选择。使得数据元素集合中每一个关键字通过该哈希函数映射到内存单元的任意地址上的概率相等,从而尽可能减少发生哈希冲突的可能性。
 
 理论研究表明,除留余数法的模p取不大于表长且最接近表长m素数时效果最好,且p最好取1.1n~1.7n之间的一个素数(n为存在的数据元素个数)。例如:当n=7时,p最好取11、13等素数。
 
  此方法的优点是对n的选择不很关键。通常若地址空间为p位就是选n=2p.Knuth对常数f的取法做了仔细的研究,他认为f取任何值都可以,但某些值效果更好。如f=(-1)/2=0.6180329…比较理想。

1.2.10 字符串数值哈希法:

在很多情况下关键字是字符串,因此这样对字符串设计Hash函数是一个需要讨论的问题。下列函数是取字符串前10个字符来设计的哈希函数。

Int Hash _ char (char *X){int I ,sum i=0;while (i<<10 && X[i]) Sum +=X[i++];sum%=N;      //N是记录的条数}

这种函数把字符串的前10个字符的ASCⅡ值之和对N取摸作为Hash地址,只要N较小,Hash地址将较均匀分布[0,N]区间内,因此这个函数还是可用的。对于N很大的情形,可使用下列函数

int ELFhash (char *key )
{Unsigned long h=0,g;while (*key){ h=(h<<4)+ *key;key++;g=h & 0 xF0000000L;if (g) h^=g>>24;h &=~g;}h% =Nreturn (h);
}

这个函数称为ELFHash(Exextable and Linking Format ,ELF,可执行链接格式)函数。它把一个字符串的绝对长度作为输入,并通过一种方式把字符的十进制值结合起来,对长字符串和短字符串都有效,这种方式产生的位置不可能不均匀分布。

1.2.11 旋转法

旋转法是将数据的键值中进行旋转。旋转法通常并不直接使用在哈希函数上,而是搭配其他哈希函数使用。

例11,某学校同一个系的新生(小于100人)的学号前5位数是相同的,只有最后2位数不同,我们将最后一位数,旋转放置到第一位,其余的往右移。

运用这种方法可以只输入一个数值从而快速地查到有关学生的信息。

在实际应用中,应根据具体情况,灵活采用不同的方法,并用实际数据测试它的性能,以便做出正确判定。通常应考虑以下五个因素 :

1.计算哈希函数所需时间 (简单)

2.关键字的长度

3.哈希表大小

4.关键字分布情况

5.记录查找频率

[转自] — — 区块链—密码学中Hash算法(基础)

Hash构造函数的方法相关推荐

  1. HashMap解决hash冲突的方法

    HashMap解决hash冲突的方法 博客分类: jvm虚拟机 在Java编程语言中,最基本的结构就是两种,一种是数组,一种是模拟指针(引用),所有的数据结构都可以用这两个基本结构构造,HashMap ...

  2. 构造函数和方法的区别

    最近回头看了看C#编程的内幕,感觉有点扯- 也不知道该如何朝那个方向努力了 现在就写写构造函数和方法吧 构造函数的作用1.主要是初始化成员变量,2.构造函数名和类名相同,也就是个构造方法.3.构造函数 ...

  3. 计算hash值的方法

    计算hash值的方法: 对于key的hashCode做hash操作,无符号右移16位然后做异或运算. 还有平方取中法,伪随机数法和取余数法.这三种效率都比较低.而无符号右移16位异或运算效率是最高的. ...

  4. 快速改变文件hash值的方法

    查看哈希值命令 Linux : md5sum + 文件名 $ md5sum 1.png fe5c3f5ef1d207bc1b646911b463c907 1.png Windows : certuti ...

  5. 构造函数与方法的区别

    1.在C#中,一些都是对象.你要用一个对象,就必须用new来实例化类(static类例外).当你用new命令时,系统就会自动调用该类的构造函数,做些初始化之类的工作.至于方法,你只能通过手工方式用&q ...

  6. JavaScript构造函数的方法

    文章目录 Object构造函数 使用new声明对象 使用{}声明对象 工厂模式 自定义构造函数模式 构造函数+原型的组合模式 Object构造函数 使用new声明对象 方法:先创建空Object对象, ...

  7. java 方法 函数 区别_Java中的构造函数和方法之间的区别

    Java方法一种方法用于探索对象的行为. 我们可以在方法的前面加上访问修饰符. 方法必须具有返回类型,例如void,任何原始类型(int,char,float等),任何Object类型(Integer ...

  8. java enum 关联_Java:如果EnUM常量在本质上是静态的,那么它如何可以拥有与其相关联的构造函数和方法...

    如果枚举常量本质上是静态的,那么如何将其作为对象和访问方法并具有构造函数. 枚举常量如何同时是对象和静态的? 请参考以下代码: enum Apple { Jonathan(10), GoldenDel ...

  9. java 字段构造函数_依赖注入–字段vs构造函数vs方法

    java 字段构造函数 嗨,今天,我想简短地讨论将依赖项注入您的类的不同方式. 通常,您有以下三种注射方法 直接进入字段/属性 通过显式的setter方法 通过显式的构造函数参数 现场注入 这种类型的 ...

最新文章

  1. vba循环通过键盘某个按键按下退出循环_51单片机按键检测--独立按键与矩阵键盘...
  2. 大厂必问的分布式究竟是什么鬼?
  3. 技术分享 | 一文带你了解测试流程体系
  4. 如何保持MacBook电池健康并延长其使用寿命?
  5. python的序列之列表
  6. 无软驱免F6在联想R510-G6-1U服务器上安装win 2003企业版的经历
  7. Java基础 - 易错知识点整理(待更新)
  8. 两个线程交替打印A1B2C3D4E5输出,6种实现方式
  9. Office Professional Plus 2010 产品密钥
  10. 华为交换机命令 端口速率_华为S5700交换机的端口QOS限速问题
  11. 操作系统学习之文件管理:
  12. 植物大战僵尸游戏内存地址
  13. htc legend 升级到 android 2.2 froyo 后,输入法问题
  14. html5 canvas模拟的爆炸效果
  15. 时代周刊评选的让你拥有健康,快乐的20件事
  16. 【大数据发展篇】大数据的诞生
  17. python manage.py startapp app 执行成功但未生成 app文件夹 解决办法
  18. 磁通 磁通量 磁链 磁通密度 磁场强度 交流磁通密度 直流磁通密度 最大磁通密度 ... .. ...
  19. js实现图片在div内滚轮放大缩小,有滚动条,双击回原状
  20. 织梦模板有电商功能吗?

热门文章

  1. 第10章 SQL UPDATE 语句教程
  2. Could not find any format factory for identifier ‘parquet‘ in the classpath
  3. 新学 PHP 日记。(分页查询)
  4. poj3723 招兵 最大权森林
  5. 已解决:Window11问题 8080、8081、8082端口占用问题 Port 808X was already in use.
  6. Java开发常见漏洞及解决方案
  7. opengl绘制花环(点的个数可以手动输入) 源代码
  8. 借身份证给别人办理流量卡有风险吗?这些情况你必须要知道!
  9. 关于torch.cumprod()累积连乘
  10. Unity UGUI InputField 中文详解-Chinar