Hash表原理不难,难在如何选择表的大小以及hash函数,这个涉及到很多数学的东西,这里就先不详述了,而是先整理下基本概念和一些结论。

Hash就是通过函数,将大范围的key值映射到小范围的hash表中,相比起直接映射来说更加节省空间。而这种方法的一个问题就是会出现“碰撞”,即有多个值会映射到同一个表格项(槽)中。

所以Hash主要问题有两个:1.如何将key值尽量随机(少碰撞地)映射到hash表中,即如何设计hash函数。2.如果发生碰撞,如何解决。

一. 如何设计hash函数:三种方法——除法散列、乘法散列、全域散列。当然这些前提是key为自然数。如果key不是自然数,应设法转换为自然数。

1. 除法散列

散列函数:h(k) = k mod m,其中k为key值,m为槽数。

注意事项:其中一种情况是,m应为与2的整数幂不太接近的质数。否则等于取k的低位,没有随机效果。

2. 乘法散列

散列函数:h(k) = floor(m(kA mod 1)),其中0<A<1。

注意事项:优点是对m没特别要求,通常是2的某个幂次,因为适合计算机运算。对A没特别要求,有研究认为最好的A是(sqrt(5)-1)/2 = 0.618....。

3. 全域散列

散列函数:在计算时从一组hash函数中随机的选择一个函数

散列函数样例:ha,b(k) = ((ak + b)mod p) mod m,其中p为大于最大k的质数,0<a<p,0<=b<p,a,b属于N。

注意事项:对于m没有特别要求。散列函数簇就是所有符合条件的a与b不同组合得到的函数。

二. 如何解决碰撞。解决碰撞有两大类方法:链接法和开放寻址法。

1. 链接法。主要特点是碰撞通过在槽中维护链表来解决碰撞,这样发生碰撞的key都可以存储在同一槽中,通过遍历链表来查找key。

2. 开放寻址。不维护链表,而是通过一些偏移的方法将所有key映射在槽中。有三种方法:线性探查、二次探查、双重探查。

a. 线性探查

散列函数:h(k,i) = (h'(k) + i) mod m, i=0,1,...,其中i为探查次数

注意事项:这个意思就是,先用普通的散列函数计算出一个值,如果发生碰撞,就加上探查次数再取余,直到成功找到空槽。就是依次往后找到空槽。

b. 二次探查

散列函数:h(k,i) = (h'(k) + c1*i + c2*i^2) mod m,其中c2!=0。

注意事项:效果比线性探查好,c1、c2和m要受到限制。

c. 双重散列

散列函数:h(k,i) = (h1(k) + i*h2(k)) mod m。

注意事项:开放寻址最好的方法。为了能查找整个表,h2(k)要与m互质。

另外还有完全散列的方法,即最坏情况下内存访问为O(1)。实现方法可以用二级散列,散列表的每个槽都是一个散列,每级都使用全域散列。当然这要求key是静态的。

《算法导论》之hash表相关推荐

  1. 一步一步写算法(之hash表)

    [ 声明:版权全部,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] hash表,有时候也被称为散列表.个人觉得,hash表是介于链表和二叉树之间的一种中间结构.链 ...

  2. 【算法导论33】跳跃表(Skip list)原理与java实现

    Skip list是一个用于有序元素序列快速搜索的数据结构,由美国计算机科学家William Pugh发明于1989年.它的效率和红黑树以及 AVL 树不相上下,但实现起来比较容易.作者William ...

  3. 【数据结构bull;hash表】重排九宫…

    [数据结构•hash表]重排九宫 Time Limit:10000MS  Memory Limit:65536K Total Submit:47 Accepted:15 Description 我先来 ...

  4. 算法导论 直接寻址表

    算法导论 第11章 散列表 11.1 直接寻址表 如果某应用要用到一个动态集合,其中每个元素都是全域U={0,1-.,m}中的一个关键字 为表示动态集合,使用数组.称为直接寻址表,记为T[m],其中每 ...

  5. 从头到尾彻底解析Hash表算法

    从头到尾彻底解析Hash表算法 发布时间: 2013-10-02 10:26  阅读: 25156 次  推荐: 14   原文链接   [收藏]   作者:July.wuliming.pkuoliv ...

  6. 转 从头到尾彻底解析Hash表算法

    出处:http://blog.csdn.net/v_JULY_v.   说明:本文分为三部分内容,     第一部分为一道百度面试题Top K算法的详解:第二部分为关于Hash表算法的详细阐述:第三部 ...

  7. 假设一动态集合S用一个长度为m的直接寻址表T来表示。请给出一个查找S中最大元素的过程。(算法导论第十一章11.1-1)

    假设一动态集合S用一个长度为m的直接寻址表T来表示.请给出一个查找S中最大元素的过程.你所给的过程在最坏情况下的运行时间是多少. (算法导论第十一章11.1-1) #include "Key ...

  8. Times33算法与最快的Hash表

    关于times33算法 不约而同的,几乎所有的流行的hash map都采用了DJB hash function,俗称"Times33"算法.Perl.Berkeley DB .Ap ...

  9. SCU4438 Censor(审查员) (KMP算法与模拟栈的应用 || HASH表与模拟栈的结合)

    Censor frog is now a editor to censor so-called sensitive words (敏感词). She has a long text pp. Her j ...

最新文章

  1. vscode 配置 Latex 编译后自动清理多余文件(.log .out等文件)
  2. 使用Command模式实现撤销机制 (Code Project 精选翻译)
  3. 解决Mac nginx问题 [emerg] 54933#0: bind() to 0.0.0.0:80 failed (13: Permission denied)
  4. hdu 4291 矩阵幂 循环节
  5. 原创 | 微服务网关 Kong 科普
  6. Magento 通知朋友 Tell A Friend Extensions
  7. wsl Java开发_WSL2开发环境搭建
  8. 浅谈C#中的枚举 【转自http://www.cnblogs.com/liyingyi/archive/2005/12/28/306772.html】
  9. 面试—每日一题(5)
  10. [转载] 朴素贝叶斯python实现预测_Python实现朴素贝叶斯分类器的方法详解
  11. 最新android studio 第三方库包导入方法jar,so,module
  12. html5 3d动画效果代码,精选9款迷人的HTML5 3D动画效果及源码
  13. 什么软件可以测试网络的稳定性,手机怎么测试网络稳定性
  14. vue+js纯手写日历(包含农历,节假日)
  15. mysql只能存1000条数据_为什么我mysql的表添加了1000条记录之后就存不进去数据了,客户端也没报错...
  16. font-weight与ps字体粗细对应
  17. 【python turtle小demo分享】一闪一闪亮晶晶,祝你每天都开心~
  18. golang的一些测试技巧和工具
  19. 离群索居者,不是野兽便是神灵!
  20. C语言 局部变量和全局变量

热门文章

  1. CQUOJ月赛(5月)H题:zzblack与斐波那契数列
  2. Region proposal学习笔记
  3. [Python] 字典 items()方法:同时对字典的键和值进行遍历
  4. [PyTorch] torchvision库及其常用的函数
  5. matlab2c使用c++实现matlab函数系列教程-sinh函数
  6. matlab简单分析信号调制解调
  7. 排序-InsertionSort 插入排序
  8. chromium 一些设置 --插件安装
  9. 【java基础】重载与重写
  10. 【转】.Net 架构图