哈希表的大小为何最好是素数

引言

为什么散列函数采用取模运算?又为什么取模运算的被取模数最好是素数?素数是如何在取模运算中很好的规避冲突的?

这些问题可能困扰诸多程序员很久了。我们总是说素数可以更好的避免冲突,但总是对各种长篇大论的分析望而却步。

这篇文章是我在学习散列时针对素数在哈希函数中的如何成功避免大量冲突的原因总结。

尽可能言简意赅地描述为什么素数那么香。

一、结论

素数能够在取模运算中避免冲突并不是一个数学定律,而且能够避免冲突也不是绝对的。

从规律上来看,如果待存储的数列间隔恰好是是被取模数因子大小,那么合数要比素数更容易呈现周期性取模重复

这仅仅是一个规律,目前数学家也无法对这一规律进行严格定义,毕竟这个规律也并不是绝对的。

二、演示

我们通过一个简单的例子来印证一下上面的这个规律:

从规律上来看,如果待存储的数列间隔恰好是是被取模数因子大小,那么合数要比素数更容易呈现周期性取模重复

这个规律不是绝对的。下面选取了一个合数和一个素数,待存储的数列间隔为 2 或 3,请仔细观察规律:

1

数列间隔 3

(3是12的因子)

数列343740434649525558
2mod 11 =1471025803
3mod 12 =101471014710
4mod 13 =81114710036
5mod 14 =691214710132
6

数列间隔 2

(2是12、14的因子)

数列676971737577798183
7mod 11 =135790246
8mod 12 =79111357911
9mod 13 =24681012135
10mod 14 =1113135791113

上图中,数列代表待存储的整型数据,一般在很多散列表(如HashMap)中,都是通过对关键字进行某种变换得到一个整型数字,比如,如果key是字符串,那么可以通过计算字符编码得到一个整数值。

mod 11 代表对11取模,mod 12 代表对 12 取模,依此类推。

我们分别选取了比较普通的两组数列,分别对合数(12、14)和素数(11、13)进行取模运算,可以看到,取模结果重复的已经使用红色标记。

当数列间隔为 3 时,由于 3 是 12 的因子,因此,可以看到表中 mod 12 的结果呈现了周期性的模冲突。而其他的 11、13、14,并没有发现明显的冲突问题,而是很好地分散了取模结果。

当数列间隔为 2 时,由于 2 是 12、14 的因子,因此,可以看到表中 mod 12 和 mod 14 的结果都呈现了周期性的模冲突,而 11、13 两个素数并没有发现明显的冲突问题,而是很好地分散了取模结果。

总结

从实验结果可以清晰的看到,素数要比合数更适合取模运算。在不知道数列间隔的情况下,拥有较少因子的素数可以有效的避免规律性的取模冲突。

大家如果对我的结论感兴趣,可以通过对比试验来尝试寻找数列间隔与因子之间的关系。

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

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

相关文章

Java常用设计模式————适配器模式

引言 由于无法直接使用某个类中的方法而采取的一种中间类转换的策略。将一个类的接口转换成另一个接口,让原本接口不兼容的类可以兼容。 适配器模式可以分为三种:类适配器、对象适配器、接口适配器。它们之间的区别主要体现在适配器角色与被适配角色之…

Java常用设计模式————桥接模式

引言 在实际的业务中,经常会遇到多维度的概念组合,公园的门票,颐和园有年票、月票、日票,故宫也有年票、月票、日票。那么不同的公园和票种类型就可以视为两种不同的纬度,它们之间会形成相互组合的关系。 在类的设计…

Java常用设计模式————装饰者模式

引言 装饰者模式,又叫装饰器模式。它可以动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更灵活,同时装饰者模式也体现了OCP原则。 在客户端调用使用了装饰者模式的对象时,就好像在使用构造器层层包裹核心对象&#x…

Java常用设计模式————组合模式

引言 组合模式,是一种类似递归算法的结构性设计模式,通过以简单的 List ,组合本类对象,实现树状对象结构的“部分、整体”的层次。 它可以让调用程序不需要关心复杂对象与简单对象的区别,而统一地实现处理逻辑。 对…

MySQL 高级 —— MVCC 多版本并发控制

引言 MySQL的大多数事务型存储引擎实现的都不是简单的行级锁。基于提升并发性能的考虑,它们一般都同时实现了多版本并发控制——MVCC。包括其他数据库如Oracle等,由于MVCC并没有一个统一的实现标准,因此它们的实现原理都不尽相同。 MVCC简介…

Java常用设计模式————外观模式

引言 外观模式(Facade Pattern),又叫“过程模式”。外观模式为子系统中的一组接口提供一个一致的入口,此模式定义了一个高层接口,这个接口使得这一组子系统更加易用。 一、案例分析 生活中有很多类似的案例&#xf…

Java常用设计模式————享元模式

引言 享元模式,也叫蝇量模式(Flyweight Pattern)。运用共享技术有效地支持大量细粒度的对象。 享元模式常用于系统底层开发,解决系统的性能问题。例如数据库连接池,里面都是创建好的连接对象,在这些连接对…

IDEA——常用基础设置

一、设置入口 File—>Settings... 或者 在工具栏的“小扳手”图标。 二、主题设置 三、编辑通用设置 设置面板中的 Editor 3.1 自动导包 可以设置IDEA自动为程序导包,在书写时加入准确的导包,在书写时优化导包(自动去掉未使用的&#…

IDEA——常用快捷键

引言 总结 IDEA 的常用快捷键,除了部分快捷键与 Eclipse 保持一致之外,枚举更多的实用快捷键。 一、如何设置快捷键 在 Settings -> Keymap 中,下拉框里选择 Eclipse ,即可将 IDEA 的快捷键设置为与 Eclipse 保持一致。但并…

IDEA——常用代码模板

引言 IDEA 提供了一些内置的代码模板,可以让开发者快速方便的使用,当然 eclipse 中也是有的,比如输入 syso 快速生成输出语句,main 快速生成主函数等。 idea 的模板设置都在 Settings --> Live Templates 和 General-->Po…

IDEA——Git 的设置与使用

引言 在本机下载好 Git 之后,再去在 IDEA 中设置 Git 相关的参数。详细的 Git 操作和 Eclipse 大同小异,可以移步至:《Git必知必会》 一、设置Git执行程序路径 二、导入一个新的远程 git 托管项目 打开 File ——> New ——> Project…

IDEA——Maven的配置与使用

引言 简单介绍一下如何在 idea 中配置maven,以及如何去使用 maven 。 一、配置 Maven home Maven home 和 settings 文件一般都需要进行重新设置,关联到本机已经安装好的 maven 版本,settings 这里可以使用默认,也可以设置为 ma…

Spring Cloud Alibaba——Nacos实现服务治理

引言 本博客总结微服务开发中各个微服务调用的实现,并使用 Nacos 完成服务注册和发现。 文章中会涉及到 maven 的使用,以及 spring boot 的一些知识。开发工具采用 IDEA 2020.2。 设计一个电商订单和商品购买微服务,实现微服务的注册发现与…

Spring Cloud —— Feign 实现服务调用

引言 本篇博客简单介绍 Feign 的基础知识和基本应用,以前一篇博客《Spring Cloud Alibaba——Nacos实现服务治理》为代码基础,实现更简单的微服务调用方式。 一、什么是Feign restTemplate 实现的微服务调用方式: // 调用商品微服务&…

Spring Cloud —— 负载均衡与 Ribbon 应用

引言 本篇博客简单介绍微服务负载均衡的概念,并通过 IDEA 多端口启动应用的方式,模拟多个应用实例,使用自定义和 Ribbon 两种方式实现基本的负载均衡策略。 微服务代码以《Spring Cloud Alibaba——Nacos实现服务治理》为基础。 一、什么是…

控制反转 IOC 与依赖注入 DI

引言 简单总结和巩固一下spring的核心原理——IOC和DI的概念,为什么IOC要叫控制反转?IOC和DI的关系是怎样的? 一、IOC 控制反转 初学者可能很好奇,为什么spring framework的对象托管容器叫做 IOC容器(Inversion of …

Spring —— 容器内部逻辑

引言 上一篇关于IoC容器的详解《Spring —— IoC 容器详解》真是工程浩大,可以说Spring官网对核心中的核心IOC容器做了非常全面的使用说明,包括在《Spring揭秘》中让我一直没有成功的Method Injection,官网也解决了我的疑惑,并最…

2020 年度总结

2020年给我的感觉是短平快的一年。 由于年初的新冠肺炎疫情,我大半年都呆在北京的破旧出租屋里写代码。整个春天和夏天,平平无奇。 2月1日返京,居家办公,夜跑。8月复工,疯狂爆痘、烂脸,月末落户天津。9月…

Spring 全局异常捕获

引言 前后端分离开发,后台有时候会出现不可预知的异常(运行时异常),在实际生产中通常需要统一返回符合一定响应结构的异常信息给前端,这一方面可以避免用户看到后台的报错信息,一方面也是保护后端程序免受…

JDBC——概述与JDBC的使用

引言 一直希望深入学习一下数据库持久化技术,接触过Hibernate、Mybatis,也使用过Spring事务管理来控制回滚操作,但是越发觉得底层知识有一定的知识盲区和空洞。 很多ORM框架都是基于JDBC规范来进行构建的,因此,学习J…