散列

算法系列(十二)散列 Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。 标准库中包括Set和Map的散列实现,即HashSet类和HashMap类。HashSet的实现直接借助了HashMap。JDK中是使用 阅读详情

散列:

    散列是一种用于以常数平均时间执行插入、删除、查找的技术。但是那些需要元素间任何
排序信息的树操作将不会得到有效的支持。因此,诸如findMin、findMax以及线性时间将排过序的
整个表进行打印的操作都是散列表所不支持的。

一般想法:

    理想的散列表数据结构只不过是一个包含一些项(item)的具有固定大小
的数组。通常查找是对项的某个部分(数据域)进行的。这个部分就叫做关键字(key)。例如,项
可以由一个串(它可以作为关键字)和其他一些数据域(例如:姓名是大型雇员结构的一部分)。我们把
表的大小记作TableSize,并将其理解为散列数据结构的一部分,而不仅仅是浮动与全局的某个变量。通常的习惯
是让表从0到tableSize - 1变化。

下标Tables
0
1
2
3john 25000
4phil 31250
5
6dave 27500
7mary 28200
8
9

    每个关键字被映射到0到tableSize - 1这个范围中的某个数,并且放到适当
的单元中。这个映射就叫做散列函数(hash function),理想情况下他应该计算起来简单,并且应该
保证任何两个不同的元素映射到不同的单元。不过这是不可能的,因为表格的单元数量有限的,而关键字是
用不完的。因此,我们要寻找一个散列函数, 该函数在表中均匀的分配关键字。上面一个是完美情况的一个
典型,john散列到了3, phil散列到了4, dave散列到了6,mary散列到了7。
    这就是散列的基本思想。剩下的问题就是要选择一个函数决定当两个关键字
散列到同一个值得时候(这就叫做冲突(collision))应该做什么以及如何确定散列表的大小问题。

散列函数

    如果输入的关键字是整数,则一般合理的方法就是直接返回Key mod Tablesize,除非Key碰巧据有某些不合乎需要的性质。在这种情况下, 散列函数的选择需要仔细的考虑。最好的方法就是保证表的大小是素数。
    通常一般来说, 关键字是字符串;在这种情形下,散列函数需要仔细的选择。

1.第一种策略就是把字符串中的ASCLL(或Unicode码)值加起来。

public static int hash(String key, int tableSize){
    int hashVal = 0;
    for(int i = 0; i < key.length(); i++)
        hashVal += key.charAt(i);
    return hashVal % tableSize;
}

这个散列函数实现起来简单而且能够很快地计算出答案。不过如果表很大函数将不会很好的分配关键字。
例如,设TableSize = 10007(10007是素数),并且设所有的关键字的至多8个字符。ASCLL码最多127,
因此散列函数只能假设值在0和1016之间,其中1016为127 * 8.显然这不是一种均匀的分配。

2.第二种值27表示英文字母外加一个空格, 但是这种设计是不是非常的合理的,Key至少有3个字符, 假如它的值是10007, 那么其实2的立方是17576种组合, 但是实际上只有2851

public static int hash(String key, int tableSize){
    return (key.charAt(0) + 27 * key.chatAt(1) + 729
    * key.charAt(2)) % tableSize;
}

3.利用Horner法则计算一个(37的)多项式函数。这个散列函数利用到事实:允许溢出。这可能会引进负的数, 所以在末尾有附加的测试。加入关键字特别长那么就有可能会在散列过多的时间。这种是有多种解决的方法的, 其中一种就是利用只是在奇数上的位置上的字符来实现他们的散列函数这里有这么一层想法:用计算散列函数节省下的时间来补偿由此产生对均匀地分布的函数轻微干扰。

public static int hash(String key, int tableSize){
    int hashVal = 0;
    for(int i = 0; i < key.length(); i++)
        hashVal = 37 * hashVal + key.charAt(i);

    hashVal %= tableSize;
    if(hashVal < 0)
        hashVal += tableSize;

    return hashVal; 
}
散列算法、斐波那契散列 需要注意的是,不同的散列算法具有不同的特点和用途,选择哪种算法取决于具体的应用场景和需求。:当HashMap中的元素数量超过其容量(capacity)的负载因子(load factor,默认为0.75)时,HashMap会进行扩容,即创建一个新的、容量更大的数组,并重新计算所有元素的散列值和新位置。综上所述,乘法散列(或更广泛地说,散列算法中的扩容机制)使用2的幂值作为每次的扩容条件,主要是为了提高效率、保证哈希分布的均匀性、优化内存利用率、简化实现以及平衡空间和时间成本。 阅读详情

相关推荐

开散列、闭散列实现及性能比较

总程序实现了添加数据信息,建立开散列表,闭散列表,开散列和闭散列的查找,时间性能分析,还有溢出表的建立与查找这些功能。 下面分开说明原理: 开散列表:运用单链表存储方式,不产生堆积现象,但因为附加了指针域而增加了空间开销。 闭散列表:运用顺序表存储,存储效率较高,但容易产生堆积,查找不易实现,需要用到二次再查找。 溢出表:开、闭散列的结合运用,第一个顺序表存放类似指针域,第二个则存放溢出。

Velocity_light 5931

散列(hash)算法——Java表示

Hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。 百度百科给出的散列算法的解释如上,个人理解散列算法就是给个输入通过散列算法后输出得道固定长度的输出。 输入—>散列算法—>输出(固定长度) 第一个接触的散列算法应该是MD5吧…学JavaWeb的时候做密码加密。虽然现在已经不推荐使用...

Songcz的博客 3575

散列表

散列思想 散列表采用的是数组支持按照下标随机访问,时间复杂度是O(1)的特性。通过散列函数将元素的键值映射到数组下标,然后将数据存储到对应下标的位置。当查找数据时,通过同样的散列函数计算键值,按照键值查找数据下标对应的值即可。 散列函数 散列函数基本要求: 散列函数计算得到的散列值是一个非负整数 如key1=key2,则hash(key1)==hash(key2) 如key1≠key2,则hash(key1)≠hash(key2) 注意:第三点不是绝对的,可能存在key不同,散列函数相同的情况,这个就是散列

weixin_46757553的博客 2171

构造hash表的方法

一、整数的Hash函数 常用的方法有三种:直接取余法、乘积取整法、平方取中法。下面我们对这三种方法分别进行讨论。以下假定我们的关键字是,Hash表的容量是,Hash函数为 。 1.直接取余法 我们用关键字 除以 ,取余数作为在Hash表中的位置。函数表达式可以写成: 例如,表容量 ,关键值 ,那么 。该方法的好处是实现容易且速度快,是很常用的一种方法。但是如果选择的

追梦赤子心 2046

散列技术

翻了一下数据结构的书,复习了散列的相关知识点,总结如下:      散列方法的主要思想是根据结点的关键码值来确定其存储地址:以关键码值K为自变量,通过一定的函数关系h(K)计算出对应的函数值,把这个值解释为结点的存储地址,将结点存入到此存储单元中。在一般的情况下,散列表的空间必须比结点的集合大,此时虽然浪费了一定的空间,但是换取的是检索效率。散列的好坏依赖于散列函数的设计。散列函数可能对于不相等的关键码计算出相同的散列地址即发生冲突,发生冲突的两个关键码称为该散列函数的同义词。       采用散列技术时候

zsuguangh的专栏 1985

散列查找

散列函数:一个把查找表中的关键字映射成该关键字对应的地址的函数,记为Hash(key)=Addr(这里的地址可以是数组下标、索引或内存地址等)。 散列函数可能会把两个或两个以上的不同关键字映射到同一地址,称这种情况为冲突,这些 发生碰撞的不同关键字称为同义词。一方面, 设计得好的散列函数应尽量减少这样的冲突;另一方面,由于这样的冲突总是不可避免的,所以还要设计好处理冲突的方法。 散列表:根据关键字而直接进行访问的数据结构。也就是说,散列表建立了关键字和存储地址之间的一种直接映射关系。 理想情况下,对散列表进

qq_36314864的博客 3323

数据结构与算法分析---散列

散列 1. 散列函数 如果输入的关键字是整数,则一般合理的方法就是直接返回 Key mod Tablesize。散列的函数的选择需要仔细考虑。通常保证表的大小是素数,当输入的关键字是随机数字时,散列函数不仅计算起来简单而且关键字的分配也很均匀。 通常,关键字是字符串 一种选择方法是把字符串的ASCII码(或 Unicode码)值加起来。 public static int hash(String...

qq_37976565的博客 383

无人机蜂群联合指挥作战技术详解

随着人工智能、通信技术、新材料等领域的不断进步,无人机蜂群联合指挥作战技术将迎来更加广阔的发展前景。未来,无人机蜂群将更加智能化、自主化,能够执行更加复杂、精细的作战任务。同时,加强国际合作,共同制定国际规则和标准,将是推动无人机蜂群技术健康发展的重要方向。无人机蜂群技术,是指通过先进的通信技术、自主导航与决策算法,将大量小型、低成本、功能各异的无人机组织成一个高度协同的群体,执行复杂多样的军事任务。2. 通信与数据链:采用高速、低延迟、抗干扰的通信技术,保障群体内无人机间的信息交换。

专注多旋翼、复合翼无人机技术研究,从事低空经济行业。 1544

简单的hash算法

/** * 散列 * 将字符串中字符的ASCII码值加起来 * 但是这个算法存在问题 * 如何均匀得分布4个字符长度的字符串在2000的table中, * 一个ASCII字符的值最多是127,因此散列函数只能在0~127*4中分布 * 思路:可以分段存放,0~500,501~1000,1001~1500,1501~2000 *

沉下心来,戒骄戒躁 1774

DeepLearningTool-深度学习分类-和HALCON的详细过程

损失函数:衡量预测误差,用于模型优化。混淆矩阵:评估分类模型性能,提供详细预测结果分析。两者结合使用,可以全面评估和优化模型。过拟合:模型过于复杂,捕捉了噪声,表现为训练集误差低,测试集误差高。欠拟合:模型过于简单,无法捕捉数据模式,表现为训练集和测试集误差都高。调整参数过拟合:简化模型、增加数据、使用正则化、早停、Dropout。欠拟合:增加模型复杂度、特征工程、增加训练时间、调整学习率、使用集成方法。通过合理调整参数和方法,可以有效避免过拟合和欠拟合,提升模型性能。

weixin_36672036的博客 6181

golang任意代码免杀绕过火绒+电脑管家

火绒和电脑管家主要以静态规则为主,但是有时候静态杀起来也挺让人奔溃的,这边分享一下如何拿捏火绒和电脑管家本文主要介绍如何通过garble进行混淆编译来绕过火绒,garble也可以绕过其他杀软,但是对火绒和电脑管家特别有效果,以火绒为例 下面来对比一下golang原生和garble混淆编译后得差距来一个很原始的的shellcode loader代码,将原始shellcode base64后就进行加载执行。

2301_79571829的博客 1533

散列的基本概念

散列的基本概念 什么是散列?为什么需要散列? 散列是一种思想。与已经学过的其他数据结构相比较,向量是采用循秩访问(call by rank)的访问方式,列表是采用循位置访问(call by position)的访问方式,二叉搜索树是采用循关键码访问(call by key)的访问方式,散列与他们都不一样,是采用循值访问(call by value)的访问方式。 举个例子,你现在身处同济大学嘉定...

Shine__Wong的博客 1万+

C#实战:5分钟搞定Modbus RTU通讯(基于NModbus4库)

本文详细介绍了如何使用C#和NModbus4库快速实现Modbus RTU通讯,包括环境配置、核心功能实现、性能优化及常见问题排查。通过代码示例和实用技巧,帮助开发者高效完成工业自动化设备的数据采集与控制任务。

weixin_30689307的博客 467

双散列和再散列暨散列表总结(附理解)

目录双散列再散列回顾总结 先说明一下,她们两个属于不同的范畴,双散列属于开放定址法,仍是一种解决冲突的策略。而再散列是为了解决插入操作运行时间过长、插入失败问题的策略。简而言之,她们的区别在于:前者让散列表做的“对”(把冲突元素按规则安排到合理位置),后者让散列表具有了可扩充性,可以动态调整(不用担心填满了怎么办)。 双散列 我们来考察最后一个冲突解决方法,双散列(double hashing...

小胡同的诗 1万+

WPS和Excel通用!省市区四级联动下拉菜单保姆级教程(附最新行政区划数据包)

本文详细介绍了在WPS和Excel中实现省市区四级联动下拉菜单的完整教程,包含2024年最新行政区划数据的获取与整理方法。通过名称管理器和INDIRECT函数的组合,以及WPS的特色功能,帮助用户高效准确地录入四级行政区划信息,提升数据录入效率并减少错误。

s1t2u3的博客 610

使用Kettle进行数据同步(增量)

文章目录kettle介绍kettle安装kettle使用使用kettle同步关系型数据库数据(MySQL示例)1. 创建一个转换2. 选择表输入3. 格式转换4. 执行脚本5. 创建job使用kettle同步NoSql数据(MongoDB示例)创建转换时的注意事项MongoDBInput怎么创建job的创建如何在Linux上面运行已经创建好的job?1、把创建好的job传输到Linux机器上面2、编辑kjb文件3、执行任务 kettle介绍 Kettle 是一款国外开源的 ETL 工具,纯 Java 编写

JenKin的博客 7349

散列、散列函数

1.散列表(Hash table) 散列表(又称哈希表)是一种数据集,其中数据项的存储方式尤其有利于将快速的查找定位。 散列表中的每一个存储位置,称为槽(slot),可以用来保存数据项,每个槽有一个唯一的名称 例如:一个包含11个槽的散列表,槽的名称分别为0~10。在插入数据项之前,每个槽的值都是None,表示空槽。 散列函数 实现从数据项到存储槽名称的转换的,称为散列函数(Hash function)。 下面示例中,散列函数接受数据项作为参数,返回整数值0~10,表示数据项存储的槽号。 有一种常用的散列

weixin_38324954的博客 3633

Unity 接入HybridCLR的点点滴滴,亲测三平台(PC、Android、WebGL)妥妥的。-问题分享

一入热更深似海啊,没有热更是真恼火啊,干啥啥不方便,动不动就得重新发包;说实在的,也是工作之余研究这个,在原有框架基础上接入这个热更,既要保持原有功能,还要支持热更,实实在在、断断续续搞了这么久,终于是接入并测通了,这一路是坎坎坷坷,下面把走过的弯弯绕绕记录下,希望对后来想接入的小伙伴有帮助吧。

GarFe的博客 1万+

什么是散列表?

https://juejin.im/user/5b2cc5fee51d4553156be12f/posts 散列表 散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表。 散列函数 散列函数,顾名...

cowbin2012的专栏 1万+

c++ mysql_init 返回无效指针_C++操作MYSQL遇到的一些问题

首先 我使用的是 vcpkg上面是我装的一些库《大大安利vcpkg 安装时一定要使用powershell进行编译装上vcpkg后装ligmariadb这个库,这个对Mysql操作还是挺方便的,然后说一下 在装库时碰到的一些问题1.网络问题1.参考了一下 github上的答案 将下载失败的url拷下来 自己下 然后再重新开始安装《vcpkg在安装时每一个需要下载的 都会提供url-仔细找,2.这个问...

weixin_32176627的博客 680

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

散列表及散列冲突解决方案

1、散列表 看过HashMap源码的同学应该知道,HashMap是基于哈希表(散列表)的 Map 接口的非同步实现。 在我们put了一条key-value数据后,如下图,程序会先将key通过hash(key)这个函数转化成整形,这个整形做为数组的下标,插入数据或查找数据。 我们发现,散列表用的是数组支持按照下标随机访问数据的特性(时间复杂度O(1)),所以散列表其实就是数组的一种扩展...

u010530712的博客 1万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

散列表、散列函数、散列冲突、哈希算法

当装载因子达到阈值之后,只申请新空间不进行数据迁移的操作,当有新的数据要插入的时候,将新数据插入到新的散列表中,并且从老的散列表中拿出一部分数据放入到新的散列表中。比如,我们可以从图片的二进制码串开头取100个字节,从中间取100个字节,从最后再取100个字节,然后将这300个字节放到一块,通过哈希算法(比如MD5),得到一个哈希字符串,用它作为图片的唯一标识。举一个极端的例子,如果散列表当前大小为1GB,想要扩容为原来的两倍大小,那就需要对1GB的数据重新计算哈希值,并且从原来的散列表迁移到新的散列表。

weixin_46290302的博客 991

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

散列表、常见散列函数及处理冲突的方法

文章目录散列表的概念常见的散列函数处理冲突的方法处理冲突的开放地址法处理冲突的拉链法散列查找及性能分析 散列表的概念 散列法  散列法又称哈希法或杂凑法,它在元素的存储位置与元素关键码之间建立一个确定的对应函数关系Hash(),使得每个关键码与结构中的一个唯一的存储位置相对应: Address=Hash(key) Address = Hash(key)Address=Hash(key)  在插入时,依此函数计算存储位置并按此位置存放。  在查找时,对元素的关键码进行同样的函数计算,把求得的函数值当作元素的

薛定谔的猫的博客 3858

散列表是什么(散列函数、散列冲突、HashMap、LinkedHashMap)

一、什么是散列表 ? 散列表用的是数组支持下标随机访问数据的特性,所以散列表其实就是数组的一种扩展,由数组演化而来。 举个例子,我们将参赛选手设置一个编号,比如051167,表示 5 年级 11 班 67 号选手,然后在数组索引下标对应 67 的位置存储该选手,这就是典型的散列思想,我们将参赛选手的编号叫做键(key)或者关键字,用它来标识一个选手,把参赛编号转化为数组下标的映射方法就叫作散列函数...

Seina 8233

深入理解数据结构之散列表、散列、散列函数

前言                            笔者以前对散列是什么?哈希又是什么?何谓散列表?散列函数又是个什么东东比较的迷惑。                     通过看一些书,查找一些资料总算是有一些眉目了,现将相关的知识与体会记录下来。留待日后                     的再学习!            基本概念

LCore的专栏 8616

哈希之开散列和闭散列

目的:实现一种结构,不经过任何比较,一次直接得到想要的元素。通过某种函数使元素的存储位置与它的关键码之间建立一种一一映射的关系。那么就可以在查找时快速的找到需要的元素。 哈希概念 哈希之散列方法: 插入元素时:根据需要插入元素的值,通过某种计算得出元素的存储位置,将该元素插入到其对应的位置。 查找元素时:根据需要查找的元素进行某种计算得到其存储位置,将该位置的元素与查找的元素进行比...

Yinghuhu333333的博客 8569
上一篇: JSTL的使用和语法规则
下一篇: 散列冲突
LuFei_java
博客等级 码龄10年 1粉丝 30原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值