Java之解决散列表的冲突用开放定址法和链表法

1 问题

理想状态下,散列表就是一个包含关键字的固定大小的数组,通过使用散列函数,将关键字映射到数组的不同位置,哈希函数可以将关键字均匀的分散到数组的不同位置,不会出现两个关键字散列值相同(假设关键字数量小于数组的大小)的情况。但是在实际使用中,经常会出现多个关键字散列值相同的情况(被映射到数组的同一个位置),我们将这种情况称为散列冲突。为了解决散列冲突,主要采用下如下两种方式:


 

 

 

2 链表法

分散链表法使用链表解决冲突,将散列值相同的元素都保存到一个链表中。当查询的时候,首先找到元素所在的链表,然后遍历链表查找对应的元素。下面是一个示意图:

 

 

 

3 开放定址法

在散列算法得到一个存储地址之后,如果发生冲突,不是在原处创建一个链表而是按照一定规则寻找周围可用的地址进行插入

这个规则我么可以是线性探测法、平方探测法、

1)线性探测法

线性探测法中,函数ff是ii的函数,记为:f(i)=i (i为寻址次数)这相当于相继探测每个单元。例子:我们在M=10点散列表中,按顺序插入下列数字{89,18,49,58,69}

按照散列方式(这里直接对数组大小取余),在插入89和18时,直接插入到散列位置9和位置8。但是插入第三个数49时,散列位置为9,跟已有89冲突,于是开始线性探测,即按照顺序寻找下一个位置。i=1时,探测位置为散列位置M+i,即探测位置0,位置0无冲突,49存入位置0。插入第四个树58时,散列位置M=8,但是位置8已经存在18,发生冲突开始线性探测,i=1时,探测位置为散列位置M+i,位置9已有89存在发生冲突,i=2时,探测位置为0,位置0已有49存在,发生冲突,i=3时,探测位置1,位置1无冲突,58存入位置1。同理,69在探测到第3次后,存入位置2。

 

 

 

2)平方探测法

在线性探测法中,函数f是i的函数,记为:f(i)=i 。而在平方探测法中,我们通常使用的是f(i)=i^2 。还是上面的例子,我们利用平方探测法插入{89,18,49,58,69}

按照散列方式,在插入89和18时,直接插入到散列位置9和位置8。但是插入第三个数49时,散列位置为9,跟已有89冲突,于是开始平方探测,第一次探测i=1,f(i)=i^2=1,所以我们探测位置为位置0(位置9+1)。发现位置0不冲突,那么在位置0插入49。插入第四个数58时,散列位置8,跟已有18冲突,开始平方探测,第一次探测i=1,f(i)=i^2=1探测位置9(位置8+1),发生冲突,第二次探测i=2,f(i)=i^2=4,探测位置2(位置8+4),位置2不冲突,在位置2插入58

 

 

4 两种办法对比总结

1) 、链表法

的缺点是使用链表。在新单元分配地址需要时间,不同的语言需要的时间不一致,这会导致算法的速度有些减慢。链表法也是固定定址的一种,它处理冲突简单,且无堆积现象,平均查找长度短;链表中的结点是动态申请的,适合构造表不能确定长度的情况;相对而言,拉链法的指针域可以忽略不计,因此较开放地址法更加节省空间。插入结点应该在链首,删除结点比较方便,只需调整指针而不需要对其他冲突元素作调整。

hashmap解决冲突用的是链表法。

 

2) 、开放定址法

容易产生堆积问题;不适于大规模的数据存储散列函数的设计对冲突会有很大的影响;插入时可能会出现多次冲突的现象,删除的元素是多个冲突元素中的一个,需要对后面的元素作处理,实现较复杂;结点规模很大时会浪费很多空间

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/287853.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python 手把手教你基于搜索引擎实现文章查重

前言 文章抄袭在互联网中普遍存在,很多博主都收受其烦。近几年随着互联网的发展,抄袭等不道德行为在互联网上愈演愈烈,甚至复制、黏贴后发布标原创屡见不鲜,部分抄袭后的文章甚至标记了一些联系方式从而使读者获取源码等资料。这…

lru算法实现 redis_使用数组与双向链表实现一个简单的LRU算法

什么是LRU算法?redis大家都玩过吧,你们好奇redis内存数据存满之后会发生什么吗?抛出异常?禁止使用?还是删除数据?其实redis设计了一种内润淘汰机制。noeviction(默认策略):屏蔽写操作&#xff0…

bzoj3224 Tyvj 1728 普通平衡树题解--Treap

题面: Description您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 1. 插入x数 2. 删除x数(若有多个相同的数,因只删除一个) 3. 查询x数的排名(若有多个相同的数&…

Blazor University (18)使用 RenderFragments 模板化组件 —— 创建 TabControl

原文链接:https://blazor-university.com/templating-components-with-renderfragements/creating-a-tabcontrol/创建一个 TabControl 组件源代码[1]接下来我们将创建一个 TabControl 组件。这将教您如何实现以下目标:将数据传递到 RenderFragment 以为其…

Java之GC机制

1 JVM基本结构 1)类加载器classLoader:在JVM启动时或者类运行时将需要的.class文件加载到内存中 2)内存区域(运行时数据区): 是在JVM运行的时候操作所分配的内存区 3)执行引擎:负…

《零基础看得懂的C语言入门教程 》——(一)脱离学习误区

本节视频连接: https://www.bilibili.com/video/BV1Qv411t7ae 新手C语言学习有些误区你应该知道,这样学习起来事半功倍~一、前言 距离上一次编写C语言的教程是5年前了(2015年),由于自己是从初一时开始学习编程&#…

一套完整的导视设计案例_色彩导视艺术:乌克兰基辅语言学校导视设计案例

学校导视设计案例建筑师Emil Dervish为乌克兰基辅Underhub语言学校设计了色彩缤纷的导视系统,该设计灵感来源于伦敦地铁,他希望通过彩色线条的大胆应用来营造轻松而欢乐的氛围。让我们一起来看看这座由“彩虹”做导视的学校。彩虹导视设计跟着红色导视线…

C# 创建匿名管道

下面对匿名管道执行类似的操作。通过匿名管道,创建两个彼此通信的任务。为了给管道的创建发出信号,使用 ManualResetEventSlim 对象,与内存映射文件一样。在 Program 类的 Run 方法中,创建两个任务,调用 Reader 和 Wri…

内测投票

create table DiaoYanTiMu (  Ids int(10) auto_increment not null primary key(),//把所需要的都写上中间不需要符号隔开,设自增长列类型必须是int,主键的话必须不能为空not null, Title varchar(50) not null );/…

Mysql 查询统计练习

2019独角兽企业重金招聘Python工程师标准>>> 1、建表 customers 顾客表 products 产品表 orders 订单表 -- 顾客表 CREATE TABLE customers (c_id INT NOT NULL AUTO_INCREMENT,lastname VARCHAR(255),firstname VARCHAR(255),address VARCHAR(255),birthday DATETI…

C++11模版元编程的应用

1.概述 关于C11模板元的基本用法和常用技巧,我在程序员2015年2月B《C11模版元编程》一文(后称前文)中已经做了详细地介绍,那么C11模版元编程用来解决什么实际问题呢,在实际工程中又该如何应用呢?本文将侧重…

《零基础看得懂的C语言入门教程 》——(二)C语言没那么难简单开发带你了解流程

一、学习目标 了解DevC集成开发环境了解集成开发环境了解HelloWorld程序了解HelloWorld程序的编写方法 目录 C语言真的很难吗?那是你没看这张图,化整为零轻松学习C语言。 第一篇:(一)脱离学习误区 第二篇&#xff1…

11选5下期算法_本周六周日【高二直播】辅导网课预告:通用技术电控二三极管、多用电表测量、数字逻辑电路、解析枚举递归算法,2022浙江选考技术...

01第19-21讲 2020年11月28日29日开课目录鲸学名师考点精讲系统提高高二共3阶段精品课夯实基础冲刺技术选考97-100分!11月28日【高二|提高|直播】高二精品直播课讲授:浙江选考技术科目第19讲 高二综合提高鲸学名师讲授高中通用技术:第19讲 电控…

十分钟完成Bash 脚本进阶!列举Bash经典用法及其案例

前言:在linux中,Bash脚本是很基础的知识,大家可能一听脚本感觉很高大上,像小编当初刚开始学一样,感觉会写脚本的都是大神。虽然复杂的脚本是很烧脑,但是,当我们熟练的掌握了其中的用法与技巧&am…

【经典回放】多种语言系列数据结构算法:基数排序

目录 一、算法思路 二、C#语言实现 三、C语言实现 一、算法思路 1. 思想基础 基数排序的思想就是先找出待排序中的最大者,然后按最大者申请一个足够大的内存空间,并将其初始化为零,然后将所有待排序的数装入其中,标记装入的数…

探索链路追踪在.NET6工业物联网项目中的应用

如果觉得有用,请留言学到了。已经会了的老哥,请留言就这?可能遇到的问题工业物联网系统自上而下一般分为ERP、Mes、SCADA、WCS、边缘网关、设备等一个生产订单从SAP发送到设备要经过上述多个系统,当某个环节出现问题,可…

《零基础看得懂的C语言入门教程 》——(三)轻轻松松理解第一个C语言程序

一、学习目标 了解C语言代码的一般结构了解函数的概念了解printf函数的使用方法了解头文件的概念了解system函数的使用方法 目录 C语言真的很难吗?那是你没看这张图,化整为零轻松学习C语言。 第一篇:(一)脱离学习误…

hdu_1728_逃离迷宫(bfs)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid1728 题意:走迷宫,找最小的拐角 题解:对BFS有了新的理解,DFS剪枝应该也能过,用BFS就要以拐角作为增量来搜,即以当前点为坐标,4…

把文件放在SD卡

2019独角兽企业重金招聘Python工程师标准>>> 在程序中访问SDCard&#xff0c;你需要申请访问SDCard的权限。 在AndroidManifest.xml中加入访问SDCard的权限如下: <!-- 在SDCard中创建与删除文件权限--> <uses-permissionandroid:name"android.permiss…

如何用 windbg 导出 C# 中的 string 内容?

咨询区 driis我在用 windbg 调试一个生产上的 程序卡死 故障 &#xff0c;在线程栈上有一个 string 类型的参数相当大&#xff0c;我用 !dumpobj 命令不能正常显示内容&#xff0c;参考如下&#xff1a;0:036> !do 00000001b30d8668 Name: System.String MethodTable: 00000…