`
wen866595
  • 浏览: 267982 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

散列/哈希

 
阅读更多

本文首先发表在: http://coderbee.net/index.php/algorithm/20130919/479 

 

散列一般也叫哈希。散列表也叫哈希表。本位将介绍散列表的基本知识、一致性哈希、哈希碰撞攻击及Java里的哈希实现。

 

介绍

散列表是普通数组概念的推广,在最坏情况下查找一个元素需要O(n),在一些合理假设下,查找一个元素的期望时间为O(1)。

 

在散列表中,不是直接把关键字用作数组下标,而是根据关键字计算出下标。

 

散列函数:作用就是根据关键字计算出数组下标。

 

碰撞(collision):多个关键字映射到同一个数组下标位置。

 

槽:一般把散列表的数组的一个存储单元(元素)叫做槽。

 

简单一致性散列:(Simple uniform hashing)假设任何元素散列到m个槽中的每一个的可能性是相同的,且与其他元素已被散列到什么位置上独立无关,这个假设称为简单一致性散列。

 

直接寻址表

当关键字的集合较小时,直接把对象放在表的槽中,节省空间;通常不需要存储对象的关键字域,因为如果有了一个对象在表中的下标,就可以得到它的关键字。由于没有存储关键字,就必须有某种方法来确定某个槽是否为空。

 

在直接寻址的方式下,具有关键字k的元素被存放在槽k中。

 

散列表

在散列表中,具有关键字k的元素存放h(k)中,也就是通过散列函数h来确定存储的槽位。

 

使用散列函数的问题是两个关键字可能映射到同一个槽上,也就是发生碰撞。通过精心设计的随机散列函数可以尽量减少碰撞。

 

通过链接法解决碰撞

在链接法(chaning)中,把散列到同一槽中的所有元素都放在一个链表中。

hash_collision_chaining

从图可知,插入和搜索的时间与链表的长度成正比。

 

查找时,首先要计算出关键字对应的槽,然后遍历链表匹配元素。

 

散列函数

一个好的散列函数应(近似地)满足简单一致性散列的假设。一种好的做法是以独立于数据中可能存在的任何模式的方式导出散列值。

 

除法散列法

通过取关键字k除以m的余数,来将关键字k映射到m个槽的某一个去。散列函数为:h(k) = k mod m。m一般取与2的整数幂不太接近的质数。

 

乘法散列法

用关键字k乘上常数A(0<A<1),并抽取出kA的小数部分,用m乘以这个值,再取结果的底(floor)。散列函数为: h(k) = floor(m * (k*A mod 1))

 

全域散列

universal hashing:随机地选择散列函数,使之独立于要存储的关键字。

 

全域散列的基本思想是在执行开始时,就从一族仔细设计的函数中,随机地选择一个作为散列函数。

 

开放寻址法

在开放寻址法(open addressing)中,所有的元素都存放在散列表里。即每个表项或包含动态集合的一个元素,或包含NIL。当查找一个元素时,要检查所有的表项,直到找到所需的元素或者最终发现元素不在表中。

不像在链接法中,这里没有链表,也没有元素存放在散列表外。

 

在开放寻址法中,当要插入一个元素时,可以连续地检查(或称探查)散列表的各项,直到找到一个空槽来防止待插入的关键字为止。如果需要,会检查所有的槽。

 

探查方法一般有三种:线性探查、二次探查、双重探查。

 

一致性哈希

假如有N台cache 服务器(简称 cache),那么如何将一个对象object映射到N个cache上呢?很可能会采用类似下面的通用方法计算object的hash值,然后均匀的映射到到N个cache ;hash(object)%N

 

这样的话,如果有一台cache当机,映射关系变为:hash(object)%(N-1);新增一台cache时,映射关系变为:hash(object)%(N+1)。这两种情况都会导致对象被映射到不同的缓存,从而导致缓存失效。一致性哈希就是解决这类场景的。

 

单调性

单调性( Monotonicity ):是指如果已经有一些内容通过哈希映射到相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。

 

consistent hashing 是一种 hash 算法,简单的说,在移除 / 添加一个 cache 时,它能够尽可能小的改变已存在 key 映射关系,尽可能的满足单调性的要求。

 

假设有一个哈希空间,一致性哈希需要把对象和cache映射到这个缓存空间去。 consistent_hashing

圆圈表示哈希空间,是固定的,独立于cache 和 对象;蓝色的结点表示cache;红色的结点表示对象。

 

一致性哈希算法的巧妙之处在于:对于一个对象object,通过给定的哈希算法得到它的的哈希值hashCode,这个hashCode对应在哈希 空间的一个点,但这个hashCode不直接对应一个cache;为了找到这个hashCode对应的cache,需要按一种固定的顺序(比如顺时针)在 哈希空间上查找它cache,查找到的第一个cache即为这个对象所对应的cache。相当于二次散列。

 

要注意的是:通过hashCode在哈希空间查找cache时,找到的第一个cache就是对象所对应的cache,不会查找后续的cache,这就确保了一致性哈希算法具有访问局部性的特性。

 

假如哈希空间上的查找顺序为顺时针的:

  • 当新增一个cache D时,它映射到key2和key3之间,那么受影响的对象只局限在:cache D和它的上一个cache结点(即cache B) 之间的对象,这些对象会被映射到新cache上去;cache B之前和cache D之后的对象都不会受影响。

  • 当移除一个ceche B时,B和A之间的对象会被映射到B的下一个结点C上去。B和C之间的及A之前的对象也不会受影响。

更多详细介绍可参考:一致性hash算法 – consistent hashing

 

哈希碰撞攻击

哈希碰撞攻击是指:对于使用链接法解决碰撞的散列表实现,通过精心构建一组对象,使这些对象映射到同一个槽位,从而使散列表退化为一个链表,由于链表的操作效率平均比散列表低,从而导致散列表的性能下降,进而让整个应用程序的性能以级数下降。

 

关于通过哈希碰撞攻击的可以参考这篇文章:Hash Collision DoS 问题

 

Java里的散列

java.util.HashMap类是JDK里的散列表实现,它的实现方式是槽+链表,也就是用链接法解决碰撞。

它的散列算法是除法散列的思想,与大多数教科书里讲的不同是,它的槽的长度是2的整数次幂,而不是一个质数;且用按位与运算代替除法:

//  计算给定哈希值h所对应的槽下标
static int indexFor(int h, int length) {
    // assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2";
    return h & (length-1);
}

h是对象的哈希值,length是槽的长度。这样做主要是出于性能的考虑。

 

对于哈希碰撞攻击,java.util.HashMap类从JDK1.8开始会在链表的长度达到某个阀值时,将散列表的实现转换为一个定制的红黑树。

 

如果对了解更多,当然应该通过google去查找更多资料。

分享到:
评论

相关推荐

    pandas-1.3.5-cp37-cp37m-macosx_10_9_x86_64.zip

    pandas whl安装包,对应各个python版本和系统(具体看资源名字),找准自己对应的下载即可! 下载后解压出来是已.whl为后缀的安装包,进入终端,直接pip install pandas-xxx.whl即可,非常方便。 再也不用担心pip联网下载网络超时,各种安装不成功的问题。

    基于java的大学生兼职信息系统答辩PPT.pptx

    基于java的大学生兼职信息系统答辩PPT.pptx

    基于java的乐校园二手书交易管理系统答辩PPT.pptx

    基于java的乐校园二手书交易管理系统答辩PPT.pptx

    tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl

    tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl

    Android Studio Ladybug(android-studio-2024.2.1.10-mac.zip.002)

    Android Studio Ladybug 2024.2.1(android-studio-2024.2.1.10-mac.dmg)适用于macOS Intel系统,文件使用360压缩软件分割成两个压缩包,必须一起下载使用: part1: https://download.csdn.net/download/weixin_43800734/89954174 part2: https://download.csdn.net/download/weixin_43800734/89954175

    基于ssm框架+mysql+jsp实现的监考安排与查询系统

    有学生和教师两种角色 登录和注册模块 考场信息模块 考试信息模块 点我收藏 功能 监考安排模块 考场类型模块 系统公告模块 个人中心模块: 1、修改个人信息,可以上传图片 2、我的收藏列表 账号管理模块 服务模块 eclipse或者idea 均可以运行 jdk1.8 apache-maven-3.6 mysql5.7及以上 tomcat 8.0及以上版本

    tornado-6.1b2-cp38-cp38-macosx_10_9_x86_64.whl

    tornado-6.1b2-cp38-cp38-macosx_10_9_x86_64.whl

    Android Studio Ladybug(android-studio-2024.2.1.10-mac.zip.001)

    Android Studio Ladybug 2024.2.1(android-studio-2024.2.1.10-mac.dmg)适用于macOS Intel系统,文件使用360压缩软件分割成两个压缩包,必须一起下载使用: part1: https://download.csdn.net/download/weixin_43800734/89954174 part2: https://download.csdn.net/download/weixin_43800734/89954175

    基于MATLAB车牌识别代码实现代码【含界面GUI】.zip

    matlab

    基于java的毕业生就业信息管理系统答辩PPT.pptx

    基于java的毕业生就业信息管理系统答辩PPT.pptx

    基于Web的毕业设计选题系统的设计与实现(springboot+vue+mysql+说明文档).zip

    随着高等教育的普及和毕业设计的日益重要,为了方便教师、学生和管理员进行毕业设计的选题和管理,我们开发了这款基于Web的毕业设计选题系统。 该系统主要包括教师管理、院系管理、学生管理等多个模块。在教师管理模块中,管理员可以新增、删除教师信息,并查看教师的详细资料,方便进行教师资源的分配和管理。院系管理模块则允许管理员对各个院系的信息进行管理和维护,确保信息的准确性和完整性。 学生管理模块是系统的核心之一,它提供了学生选题、任务书管理、开题报告管理、开题成绩管理等功能。学生可以在此模块中进行毕业设计的选题,并上传任务书和开题报告,管理员和教师则可以对学生的报告进行审阅和评分。 此外,系统还具备课题分类管理和课题信息管理功能,方便对毕业设计课题进行分类和归档,提高管理效率。在线留言功能则为学生、教师和管理员提供了一个交流互动的平台,可以就毕业设计相关问题进行讨论和解答。 整个系统设计简洁明了,操作便捷,大大提高了毕业设计的选题和管理效率,为高等教育的发展做出了积极贡献。

    机器学习(预测模型):2000年至2015年期间193个国家的预期寿命和相关健康因素的数据

    这个数据集来自世界卫生组织(WHO),包含了2000年至2015年期间193个国家的预期寿命和相关健康因素的数据。它提供了一个全面的视角,用于分析影响全球人口预期寿命的多种因素。数据集涵盖了从婴儿死亡率、GDP、BMI到免疫接种覆盖率等多个维度,为研究者提供了丰富的信息来探索和预测预期寿命。 该数据集的特点在于其跨国家的比较性,使得研究者能够识别出不同国家之间预期寿命的差异,并分析这些差异背后的原因。数据集包含22个特征列和2938行数据,涉及的变量被分为几个大类:免疫相关因素、死亡因素、经济因素和社会因素。这些数据不仅有助于了解全球健康趋势,还可以辅助制定公共卫生政策和社会福利计划。 数据集的处理包括对缺失值的处理、数据类型转换以及去重等步骤,以确保数据的准确性和可靠性。研究者可以使用这个数据集来探索如教育、健康习惯、生活方式等因素如何影响人们的寿命,以及不同国家的经济发展水平如何与预期寿命相关联。此外,数据集还可以用于预测模型的构建,通过回归分析等统计方法来预测预期寿命。 总的来说,这个数据集是研究全球健康和预期寿命变化的宝贵资源,它不仅提供了历史数据,还为未来的研究和政策制

    基于微信小程序的高校毕业论文管理系统小程序答辩PPT.pptx

    基于微信小程序的高校毕业论文管理系统小程序答辩PPT.pptx

    基于java的超市 Pos 收银管理系统答辩PPT.pptx

    基于java的超市 Pos 收银管理系统答辩PPT.pptx

    基于java的网上报名系统答辩PPT.pptx

    基于java的网上报名系统答辩PPT.pptx

    基于java的网上书城答辩PPT.pptx

    基于java的网上书城答辩PPT.pptx

    婚恋网站 SSM毕业设计 附带论文.zip

    婚恋网站 SSM毕业设计 附带论文 启动教程:https://www.bilibili.com/video/BV1GK1iYyE2B

    基于java的戒烟网站答辩PPT.pptx

    基于java的戒烟网站答辩PPT.pptx

    基于微信小程序的“健康早知道”微信小程序答辩PPT.pptx

    基于微信小程序的“健康早知道”微信小程序答辩PPT.pptx

    机器学习(预测模型):自行车共享使用情况的数据集

    Capital Bikeshare 数据集是一个包含从2020年5月到2024年8月的自行车共享使用情况的数据集。这个数据集记录了华盛顿特区Capital Bikeshare项目中自行车的租赁模式,包括了骑行的持续时间、开始和结束日期时间、起始和结束站点、使用的自行车编号、用户类型(注册会员或临时用户)等信息。这些数据可以帮助分析和预测自行车共享系统的需求模式,以及了解用户行为和偏好。 数据集的特点包括: 时间范围:覆盖了四年多的时间,提供了长期的数据观察。 细节丰富:包含了每次骑行的详细信息,如日期、时间、天气条件、季节等,有助于深入分析。 用户分类:数据中区分了注册用户和临时用户,可以分析不同用户群体的使用习惯。 天气和季节因素:包含了天气情况和季节信息,可以研究这些因素对骑行需求的影响。 通过分析这个数据集,可以得出关于自行车共享使用模式的多种见解,比如一天中不同时间段的使用高峰、不同天气条件下的使用差异、季节性变化对骑行需求的影响等。这些信息对于城市规划者、交通管理者以及自行车共享服务提供商来说都是非常宝贵的,可以帮助他们优化服务、提高效率和满足用户需求。同时,这个数据集也

Global site tag (gtag.js) - Google Analytics