上一篇说到了,设计一个简单、均匀、存储利用率高的散列函数是散列技术中最关键的问题。那么我们今天开始就看看,如何去设计散列函数。

散列函数的设计原则

  • 不管做什么事情,要做到最优都不容易,既要付出尽可能的少,又要得到最大化的多。那么什么才算是好的散列函数呢?这里我们有两个原则可以参考。

1. 计算简单

你说设计一个算法可以保证所有的关键字都不会产生冲突,但是这个算法需要很复杂的计算,会耗费很多时间,这对于需要频繁地査找来说,就会大大降低査找的效率了。因此散列函数的计算时间不应该超过其他査找技术与关键字比较的时间。

2. 散列地址分布均匀

我们前面也提到冲突带来的问题,最好的办法就是尽量让散列地址均匀地分布在存储空间中,这样可以保证存储空间的有效利用,并减少为处理冲突而耗费的时间。

  • 简单科普一下,以PHP为例。PHP的Hash采用的是目前最为普遍的DJBX33A (Daniel J. Bernstein, Times 33 with Addition),这个算法被广泛运用与多个软件项目,Apache、Perl和Berkeley DB等。对于字符串而言这是目前所知道的最好的哈希算法,原因在于该算法的速度非常快,而且分类非常好(冲突小,分布均匀)。

下面我们逐个介绍一些常用的散列函数构造方法。估计设计这些方法的前辈们当年可能是从事间谍工作,因为这些方法都是将原来数字按某种规律变成另一个数字而已。首先是直接定址法。

直接定址法

如果我们现在要对0-100岁的人口数字统计表,那么我们对年龄这个关键字就可以直接用年龄的数字作为地址。此时f(key) = key。

  • 这个时候,我们可以得出这么个哈希函数:f(0) = 0,f(1) = 1,……,f(20) = 20。这个是根据我们自己设定的直接定址来的。人数我们可以不管,我们关心的是如何通过关键字找到地址。

如果我们现在要统计的是80后出生年份的人口数,那么我们对出生年份这个关键字可以用年份减去1980来作为地址。此时f (key) = key-1980。

  • 假如今年是2000年,那么1980年出生的人就是20岁了,此时 f(2000) = 2000 - 1980,可以找得到地址20,地址20里保存了数据“人数500万”。

也就是说,我们可以取关键字的某个线性函数值为散列地址,即:

f(key) = a × key + b

这样的散列函数优点就是简单、均匀,也不会产生冲突,但问题是这需要事先知道关键字的分布情况,适合査找表较小且连续的情况。由于这样的限制,在现实应用中,直接定址法虽然简单,但却并不常用。

(3)散列函数设计:直接定址法相关推荐

  1. (4)散列函数设计:除留余数法

    除留余数法介绍 除留余数法此方法为最常用的构造散列函数方法.对于散列表长为m的散列函数公式为: f( key ) = key mod p ( p ≤ m ) mod是取模(求余数)的意思.事实上,这方 ...

  2. 散列函数设计:除留余数法

    散列函数设计:除留余数法 转载地址 感谢分享 除留余数法介绍 除留余数法此方法为最常用的构造散列函数方法.对于散列表长为m的散列函数公式为: f( key ) = key mod p ( p ≤ m ...

  3. 数据结构—— 构造散列函数的六种方法【直接定址法-数字分析法-平方取中法-折叠法-除留余数法-随机数法】

    目录: 一:直接定址法 二:数字分析法 三:平方取中法 四:折叠法 五:除留余数法 六:随机数法 这些方法原理都是将原来数字按某种规律变成另一个数字 一:直接定址法 取关键字的某个线性函数值作为散列地 ...

  4. (5)散列冲突处理:开放定址法

    前面我们讲了一些设计散列函数的方法,从前面的除留余数法的例子也可以看出,我们设计得再好的散列函数也不可能完全避免冲突,这就像我们再健康也只能尽量预防疾病,但却无法保证永远不得病一样,既然冲突不能避免, ...

  5. 冲突处理方法----开放定址法

    1 前言 常用处理冲突的思路: 换个位置: 开放地址法 同一位置的冲突对象组织在一起:链地址法 2 开放定址法(Open Addressing) 一旦产生了冲突(该地址已有其它元素),就按某种规则去寻 ...

  6. 散列表(开放定址法)

    散列表(开放定址法) 1.线性探测法 将具体的值输入到哈希函数中,映射出的具体的哈希表中的下标索引.当下标索引冲突时. 离散链表法:将重复了的值用链表的方式挂在对应索引的链表下. 线性探测法:一个位置 ...

  7. 数据结构与算法——19. 散列函数设计方法

    文章目录 一.散列(哈希)函数设计方法 1. 折叠法 2. 平方取中法 二.散列函数设计:非数项 总结 一.散列(哈希)函数设计方法 1. 折叠法 折叠法设计散列函数的基本步骤: 将数据项按照位数分为 ...

  8. 对散列冲突的处理——开放定址法

    对散列冲突的处理--开放定址法 之前聊了聊用分离链接法解决散列冲突的问题,这次就来聊聊对散列冲突的另一种解决办法:开放定址法.开放定址法分为线性探测,平方探测,双散列三种方法. 开放定址法 分离链接法 ...

  9. 0x08算法设计与分析复习(二):算法设计策略-回溯法2

    参考书籍:算法设计与分析--C++语言描述(第二版) 算法设计策略-回溯法 子集和数 问题描述 已知n个不同的正数wi(0≤i≤n−1)的集合,求该集合的所有满足条件的子集,使得每个子集中的正数之和等 ...

最新文章

  1. Entity Framework Core 2.0的新特性
  2. fatal error C1075: “{”: 未找到匹配令牌
  3. jboss7 Java API for RESTful Web Services (JAX-RS) 官方文档
  4. 都说程序员加班很严重,来听听国外的程序员怎么说
  5. Spring MVC DispatcherServlet介绍(2)
  6. 04737 c++程序设计 第二章 课后程序设计题 第一题
  7. 搭建网站随笔(WordPress)
  8. 聊聊Eureka Server的REST API
  9. 中科大软件学院硕士:实习秋招百多轮面试总结(中)
  10. MapGIS考试大纲
  11. wifi mouse hd for linux,wifi mouse hd客户端PC版下载_wifi mouse hd客户端PC版官方下载-太平洋下载中心...
  12. 寻找隐藏在CloudFlare和Tor后的真实IP
  13. PS制作logo图片
  14. @property基本概念
  15. 关于STAR法则简历
  16. matlab 2015 积分,Matlab中如何求解积分?
  17. 【应用多元统计分析】-王学民Python主成分分析例题,特征值处理和可视化(2)
  18. 如何记录日常收支,将账目导出生成表格保存
  19. 微信抢红包算法实现(JAVA)
  20. 分享 |转录组测序那些事儿

热门文章

  1. 机器翻译学习1:pytorch官方教程与代码逐行详解
  2. 正则匹配——python用一个正则表达式从字符串中提取数字(包括整数、小数、正负数)
  3. 上传docker到阿里云镜像仓库
  4. python range函数报错:TypeError: ‘float‘ object cannot be interpreted as an integer
  5. python123测验4程序题_Python面试题245道(从基础到高级)123~141——网络编程,Web—Flask...
  6. 分页缓冲池占用很高怎么解决_一次线上服务高 CPU 占用优化实践
  7. 怎么用计算机搜索文件,Win7系统如何使用内置搜索功能筛选文件名与内容
  8. 转行进入测试一年有感
  9. 第四单元作业——UML分析总结学期总结
  10. 算法47----大数