导读:今天看了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算法冲突解决方法的更多相关文章

  1. Hash算法冲突解决方法分析

    采用开放定址法处理散列表的冲突时,其平均查找长度?  高于链接法处理冲突 低于二分查找 开放定址法:一旦发生冲突,就去寻找下一个空的散列地址,只要散列地址够大,空的地址总会找到 链地址法: 一旦发生冲 ...

  2. [转]Hash碰撞冲突解决方法总结

    我们知道,对象Hash的前提是实现equals()和hashCode()两个方法,那么HashCode()的作用就是保证对象返回唯一hash值,但当两个对象计算值一样时,这就发生了碰撞冲突.如下将介绍 ...

  3. Java基础系列-equals方法和hashCode方法

    原创文章,转载请标注出处:<Java基础系列-equals方法和hashCode方法> 概述         equals方法和hashCode方法都是有Object类定义的. publi ...

  4. Java实现一致性Hash算法

    Java代码实现了一致性Hash算法,并加入虚拟节点.,具体代码为: package com.baijob.commonTools;   import java.util.Collection; im ...

  5. IIS上虚拟站点的web.config与主站点的web.config冲突解决方法 分类: ASP.NET 2015-06-15 14:07 60人阅读 评论(0) 收藏

    IIS上在主站点下搭建虚拟目录后,子站点中的<system.web>节点与主站点的<system.web>冲突解决方法: 在主站点的<system.web>上一级添 ...

  6. IIS上虚拟目录下站点的web.config与根站点的web.config冲突解决方法

    IIS7.5上在站点下部署虚拟目录,访问虚拟目录下的项目提示与父节点配置冲突.,节点与的<system.web>节点与主站点的<system.web>冲突解决方法: 在站点下的 ...

  7. java.lang.OutOfMemoryError: PermGen space及其解决方法(转载)

    java.lang.OutOfMemoryError: PermGen space及其解决方法 分类: java2007-09-11 12:34 162242人阅读 评论(51) 收藏 举报 gene ...

  8. Ubuntu Hash Sum mismatch 解决方法

    有时候通过校园网对Ubuntu14.04进行更新时,会出现以下问题: W: Failed to fetch http://xxxxxxx Hash Sum mismatch 解决方法:打开搜索 →  ...

  9. 转:git合并冲突解决方法

    git合并冲突解决方法 1.git merge冲突了,根据提示找到冲突的文件,解决冲突 如果文件有冲突,那么会有类似的标记 2.修改完之后,执行git add 冲突文件名 3.git commit注意 ...

随机推荐

  1. GIMP 无法设置中文的问题解决

    首先按照网上说的安装了language-pack-gnome-zh-hant 参考链接:http://www.ubuntu-tw.org/modules/newbb/viewtopic.php?top ...

  2. this详解,对执行上下文说 Yes

    this 指向多变,很多隐蔽的 bug 都缘于它.与此同时,this 强大灵活,如果能熟练驾驭,就会写出更简洁.优雅的代码. 社区上对于 this 的讲解虽然不少,但缺乏统一梳理. this 相关知识 ...

  3. 超简单!一步创建自己的wifi热点~

    还在用某某卫士.某某管家创建wifi热点,甚至被忽悠专门买一个随身wifi吗?现在答案明确了:你完全用不着它们了.因为有更简单的方法. 只需要两个bat文件.一个用来启动wifi热点,另一个用来关闭w ...

  4. 查看Windows激活信息

    使用 Windows + R组合快捷键打开运行命令框 1.运行: slmgr.vbs -dlv 可以查询到Win10的激活信息,包括:激活ID.安装ID.激活截止日期等信息. 2.运行: slmgr. ...

  5. 编译驱动链接到了Kernel32库问题

    最近开始学习驱动编程,根据网上的配置方法配置了驱动开发环境,用了一个简单的例子测试发现驱动居然链接到了kerner32库里面去了如图 : 显然是把Kernel.lib添加到了附加依赖库 如图 : 去掉 ...

  6. python 基础网络编程2

    python 基础网络编程2 前一篇讲了socketserver.py中BaseServer类, 下面介绍下TCPServer和UDPServer class TCPServer(BaseServer ...

  7. iOS5 and iOS6都只支持横屏的方法

    If your app uses a UINavigationController, then you should subclass it and set the class in IB. You ...

  8. RMQ求区间最大最小值

    #include<iostream> #include<cmath> #include<cstdio> #define N 50005 using namespac ...

  9. WPF中窗体调用窗体

    在WPF中有时候我们需要在一个窗体中去调用另外的一个窗体,下面给出调用方法. 下面实现在MainWindow中通过点击一个按钮调用另外的一个窗口. 首先创建你要调用的另外一个窗口:点击最上面的项目  ...

  10. ios多线程NSThread

    1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1..NSThread 2.Cocoa NSOperation (iOS多线程编程之NSOperation和NSOperationQueue ...