【java基础 10】hash算法冲突解决方法
导读:今天看了java里面关于hashmap的相关源码(看了java6和java7),尤其是resize、transfer、put、get这几个方法,突然明白了,为什么我之前考数据结构死活考不过,就差那么一点点。答:代码积累太少了!这段时间,看了java的源码、演变过程等,被虐的很惨,但是,很开心! 本篇文章,主要介绍解决hash算法冲突的方法
一、基本概念
散列表:
hash:a mixture of meat, potatoes, and vegetables cut into small pieces and baked or fried
简单说来,hash就是一组碎片的集合!所以,我们常说的hash函数,即散列函数指:数据元素的键值和存储位置之间建立的对应关系H !而用键值通过散列函数获取存储位置的这种存储方式构造的存储结构称为散列表(hash table),这一映射过程称为散列。如果选定了某个散列函数H及相应的散列表L,则对每个数据元素X,函数值H(X.key)就是X在散列表L中的存储位置,这个存储位置也称为散列地址(可以理解为hashcode)
PS:在理想情况下,应用的散列函数可以使每个键值与散列地址是意义对应的,但在实际应用中,这种情况很少或几乎不会出现。经常出现的问题有:冲突
冲突:如果有散列函数H和键值A、B(A不等于B),但是H(A)=H(B)即算出的散列地址是一样的,这种现象称为冲突! ——A、B为相对于H的同义词
二、常用的解决hash冲突的方法
2.1,开放地址法
当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。沿此序列逐个单元地查找,直到找到给定 的关键字,或者碰到一个开放的地址(即该地址单元为空)为止,常用的方法有:线性探测法、二次探测法(解决线性探测的堆积问题)、随机探测法(和二次探测原理一致,不一样的是:二次探测以定值跳跃,而随机探测的散列地址跳跃长度是不定值)
缺点:1,删除工作很困难,假如要从哈希表 HT 中删除一个记录,应将这个记录所在位置置为空,但我们只能标上已被删除的标记,否则,将会影响以后的查找。
2,不易探测到整个散列表的所有空间(线性探测法除外,但线性探测会出现堆积)
2.2,拉链法(链地址法)
将所有关键字为同义词的结点链接在同一个单链表中,【例】设有 m = 5 , H(K) = K mod 5 ,关键字值序例 5 , 21 , 17 , 9 , 15 , 36 , 41 , 24 ,按外链地址法所建立的哈希表如下图所示:
优点:1,处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短。
2,由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况。
3,更易于实现插入和删除
缺点:指针需要额外的空间,故当结点规模较小时,开放定址法较为节省空间,而若将节省的指针空间用来扩大散列表的规模,可使装填因子变小,这又减少了开放定址法中的冲突,从而提高平均查找速度。
2.3,多重散列法(再哈希法)
这种方法是同时构造多个不同的哈希函数:
Hi=RH1(key) i=1,2,…,k
当哈希地址Hi=RH1(key)发生冲突时,再计算Hi=RH2(key)……,直到冲突不再产生。这种方法不易产生“堆积”,但增加了计算时间。
2.4,公共溢出区法
散列表由两个一维数组组成,一个称为基本表,它实际上就是一个散列表。另外一个称为溢出表。插入首先在基本表上进行,假如发生冲突,则将同义词存入溢出表。这样,可以保证基本表不会发生“堆积”
PS:基本表是不会发生堆积了,那溢出表呢?当进行查找时,查找到溢出表,这是不是又开启了新一轮的冲突解决?
三、总结
再次看了一遍书,对于hash函数有了更深一层的理解。尤其是看了一些代码之后,发现自己真的很low!如上述介绍,综合而言,开放地址法、再哈希法、公共溢出区法都无可避免的多次冲突或堆积的解决或者消费了大量的时间,所以,选择链地址法是相对而言最合适的。
现在,终于解决了一个自己之前的疑惑,为什么hashmap或者hashtable会选择用一个数组和链表的形式来实现?我那时候就在想,为啥不是全用数组呢?我只想到了把数据放进去,却没有去想怎么把数据拿出来用、综合效率问题!
【java基础 10】hash算法冲突解决方法的更多相关文章
- Hash算法冲突解决方法分析
采用开放定址法处理散列表的冲突时,其平均查找长度? 高于链接法处理冲突 低于二分查找 开放定址法:一旦发生冲突,就去寻找下一个空的散列地址,只要散列地址够大,空的地址总会找到 链地址法: 一旦发生冲 ...
- [转]Hash碰撞冲突解决方法总结
我们知道,对象Hash的前提是实现equals()和hashCode()两个方法,那么HashCode()的作用就是保证对象返回唯一hash值,但当两个对象计算值一样时,这就发生了碰撞冲突.如下将介绍 ...
- Java基础系列-equals方法和hashCode方法
原创文章,转载请标注出处:<Java基础系列-equals方法和hashCode方法> 概述 equals方法和hashCode方法都是有Object类定义的. publi ...
- Java实现一致性Hash算法
Java代码实现了一致性Hash算法,并加入虚拟节点.,具体代码为: package com.baijob.commonTools; import java.util.Collection; im ...
- IIS上虚拟站点的web.config与主站点的web.config冲突解决方法 分类: ASP.NET 2015-06-15 14:07 60人阅读 评论(0) 收藏
IIS上在主站点下搭建虚拟目录后,子站点中的<system.web>节点与主站点的<system.web>冲突解决方法: 在主站点的<system.web>上一级添 ...
- IIS上虚拟目录下站点的web.config与根站点的web.config冲突解决方法
IIS7.5上在站点下部署虚拟目录,访问虚拟目录下的项目提示与父节点配置冲突.,节点与的<system.web>节点与主站点的<system.web>冲突解决方法: 在站点下的 ...
- java.lang.OutOfMemoryError: PermGen space及其解决方法(转载)
java.lang.OutOfMemoryError: PermGen space及其解决方法 分类: java2007-09-11 12:34 162242人阅读 评论(51) 收藏 举报 gene ...
- Ubuntu Hash Sum mismatch 解决方法
有时候通过校园网对Ubuntu14.04进行更新时,会出现以下问题: W: Failed to fetch http://xxxxxxx Hash Sum mismatch 解决方法:打开搜索 → ...
- 转:git合并冲突解决方法
git合并冲突解决方法 1.git merge冲突了,根据提示找到冲突的文件,解决冲突 如果文件有冲突,那么会有类似的标记 2.修改完之后,执行git add 冲突文件名 3.git commit注意 ...
随机推荐
- slf4j介绍以及与Log4j、Log4j2、LogBack整合方法
翻了一下百度和官网.这么介绍slf4j. slf4j 全称 Simple Logging Facade for Java,是日志框架的一种抽象,那么也就是说 slf4j 是不能单独使用的必须要有其他实 ...
- AJPFX关于单例设计模式
单例设计模式优势:保证一个类在内存中的对象唯一性. 比如:多程序读取一个配置文件时,建议配置文件封装成对象.会方便操作其中数据,又要保证多个程序读到的是同一个配置文件对象,就需要该配置文件对象在内存中 ...
- apache安装报错
libtool: install: error: cannot install `libaprutil-1.la' to a directory not ending /some_directory ...
- jmeter常量吞吐量定时器
jmeter常量吞吐量定时器
- MYSQL 写入emoji表情字符处理
这个鬼emoji表情是4个字节,mysql使用的utf8编码,UTF8占3个字节,要存储那个emoji表情需要将mysql编码由UFT8改为UFT8的超集,utf8mb4; 改数据库编码容易引起大面的 ...
- asp.net core mvc 异步表单(Ajax.BeginForm)
.net core中已经没有beginform扩展函数了. 通过Bower引入jquery-ajax-unobtrusive: <script src="~/lib/jquery-aj ...
- Robot Framework(十) 执行测试用例——测试执行
3.2测试执行 本节描述如何执行从解析的测试数据创建的测试套件结构,如何在失败后继续执行测试用例,以及如何正常停止整个测试执行. 3.2.1执行流程 执行套房和测试 设置和拆卸 执行顺序 3.2.2继 ...
- 面向对象编程OOP-2
用ES6的方法 实现类的继承 //类的定义 class Animal { //ES6中新型构造器 constructor(name,age) { this.name = name; this.age= ...
- OpenCV2:第十一章 图像转换
一.简介 二.例子 #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #inclu ...
- Lazy Instantiator
lazy instantiator (懒加载.延迟实例化.延迟初始化) 最开始看斯坦福的视频,对 延迟初始化 这个概念,不太理解 只见到,有些属性的初始化是在init做的,有些是在viewDidLoa ...