《算法导论》之hash表
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表相关推荐
- 一步一步写算法(之hash表)
[ 声明:版权全部,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] hash表,有时候也被称为散列表.个人觉得,hash表是介于链表和二叉树之间的一种中间结构.链 ...
- 【算法导论33】跳跃表(Skip list)原理与java实现
Skip list是一个用于有序元素序列快速搜索的数据结构,由美国计算机科学家William Pugh发明于1989年.它的效率和红黑树以及 AVL 树不相上下,但实现起来比较容易.作者William ...
- 【数据结构bull;hash表】重排九宫…
[数据结构•hash表]重排九宫 Time Limit:10000MS Memory Limit:65536K Total Submit:47 Accepted:15 Description 我先来 ...
- 算法导论 直接寻址表
算法导论 第11章 散列表 11.1 直接寻址表 如果某应用要用到一个动态集合,其中每个元素都是全域U={0,1-.,m}中的一个关键字 为表示动态集合,使用数组.称为直接寻址表,记为T[m],其中每 ...
- 从头到尾彻底解析Hash表算法
从头到尾彻底解析Hash表算法 发布时间: 2013-10-02 10:26 阅读: 25156 次 推荐: 14 原文链接 [收藏] 作者:July.wuliming.pkuoliv ...
- 转 从头到尾彻底解析Hash表算法
出处:http://blog.csdn.net/v_JULY_v. 说明:本文分为三部分内容, 第一部分为一道百度面试题Top K算法的详解:第二部分为关于Hash表算法的详细阐述:第三部 ...
- 假设一动态集合S用一个长度为m的直接寻址表T来表示。请给出一个查找S中最大元素的过程。(算法导论第十一章11.1-1)
假设一动态集合S用一个长度为m的直接寻址表T来表示.请给出一个查找S中最大元素的过程.你所给的过程在最坏情况下的运行时间是多少. (算法导论第十一章11.1-1) #include "Key ...
- Times33算法与最快的Hash表
关于times33算法 不约而同的,几乎所有的流行的hash map都采用了DJB hash function,俗称"Times33"算法.Perl.Berkeley DB .Ap ...
- SCU4438 Censor(审查员) (KMP算法与模拟栈的应用 || HASH表与模拟栈的结合)
Censor frog is now a editor to censor so-called sensitive words (敏感词). She has a long text pp. Her j ...
最新文章
- vscode 配置 Latex 编译后自动清理多余文件(.log .out等文件)
- 使用Command模式实现撤销机制 (Code Project 精选翻译)
- 解决Mac nginx问题 [emerg] 54933#0: bind() to 0.0.0.0:80 failed (13: Permission denied)
- hdu 4291 矩阵幂 循环节
- 原创 | 微服务网关 Kong 科普
- Magento 通知朋友 Tell A Friend Extensions
- wsl Java开发_WSL2开发环境搭建
- 浅谈C#中的枚举 【转自http://www.cnblogs.com/liyingyi/archive/2005/12/28/306772.html】
- 面试—每日一题(5)
- [转载] 朴素贝叶斯python实现预测_Python实现朴素贝叶斯分类器的方法详解
- 最新android studio 第三方库包导入方法jar,so,module
- html5 3d动画效果代码,精选9款迷人的HTML5 3D动画效果及源码
- 什么软件可以测试网络的稳定性,手机怎么测试网络稳定性
- vue+js纯手写日历(包含农历,节假日)
- mysql只能存1000条数据_为什么我mysql的表添加了1000条记录之后就存不进去数据了,客户端也没报错...
- font-weight与ps字体粗细对应
- 【python turtle小demo分享】一闪一闪亮晶晶,祝你每天都开心~
- golang的一些测试技巧和工具
- 离群索居者,不是野兽便是神灵!
- C语言 局部变量和全局变量