数据结构和算法——散列函数的构造方法(直接定址法、除留余数法、数字分析法、折叠法、平方取中法、ASCII码加和法、前三字符移位法)

目录

数字关键词的散列函数构造

直接定址法

除留余数法

数字分析法

折叠法

平方取中法

字符关键词的散列函数构造

ASCII码加和法

前三字符移位法

移位法


数字关键词的散列函数构造

一个“好”的散列函数一般应考虑下列两个因素

  1. 计算简单,以便提高转换速度;
  2. 关键词对应的地址空间分布均匀,以尽量减少冲突。

直接定址法

取关键词的某个线性函数值为散列地址,即h(key)=a\times key+b(a、b为常数)。

例如以年份(1990-2011)为关键词,那么就可以将散列函数构造成h(key)=key-1990

地址h(key)出生年份(key)人数(attribute)
019901285万
119911281万
219921280万
..................
1020001250万
..................
2120111180万

除留余数法

散列函数为:h(key)=key\: \: mod\: \: p

例如上篇里提到的:

地址012345678910111213141516
关键词34182202374227113015

这里的散列函数就为:h(key) = key % 17

  • 此处p = TableSize = 17
  • 一般地,p取素数

选择素数p可以避免余数之间的相关性,降低哈希冲突的概率。如果选择合数作为模数,可能存在公因数,增加了冲突的概率。

数字分析法

分析数字关键字在各位上的变化情况,取比较随机的位作为散列地址。

比如:取11位手机号码key的后4位作为地址,则散列函数为:h(key)=atoi(key+7)(char *key)

即,手机号码为12345678910,其地址就为“8910”。

例子

关键词key是18位的身份证号码:

123456789101112131415161718
330106199010080419

区(县)下

属辖区编号

(出生)年份月份日期该辖区中的序号校验

根据分析,发现变化比较大的就是我们标红的六位,所以我们以他们六位来设计散列函数:

\begin{matrix} h_1(key)=(key[6]-'0')\times 10^4+(key[10]-'0')\times 10^3+\: \: \: \: \: \: \: \\ (key[14]-'0')\times 10^2+(key[16]-'0')\times 10+(key[17]-'0') \end{matrix}

当key[18] = ‘X’时,h(key)= h_1(key)\times 10+10

当key[18]为‘0’~‘9’时,h(key)=h_1(key)\times 10+key[18]-'0'

(以十进制来计算地址,所以最高位为10的5次方)

 

折叠法

把关键词分隔成位数相同的几个部分,然后叠加。

比如:56793542,拆分成三部分

\begin{matrix} \: \: \: \: \: \, 542\\ \: \: \: \: \:\, 793\\ +\: \: 056\\ \overline{\: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: }\\ \: \: \: 1391 \end{matrix},取后三位391,所以h(56793542) = 391

平方取中法

将一个数平方之后再取中间位数的值。

比如:56793542

\begin{matrix} \: \: \: \: \: \, \: \: \: \: 56793542\\ \: \: \: \: \:\,\times \: \: 56793542 \: \: \\ \overline{\: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: \: }\\ \: \: \: 322550\mathbf{641}2905764 \end{matrix}

所以h(56793542)=641

字符关键词的散列函数构造

ASCII码加和法

对字符型关键词key定义散列函数如下:

h(key)=(\sum key[i])\:\: \: mod\:\: \: TableSize

但是这种方法冲突比较严重,a3(97+3)、b2(98+2)、c1(99+1)的ASCII码值加起来都等于100,eat(101+97+116)和tea(116+101+97)的ASCII码值加起来都等于314.

进行一下简单的改进

前三字符移位法

h(key)=(key[0]\times27^2+key[1]\times 27+key[2])\: \: \: mod\: \: \: TableSize

(这里用27进制计算地址,原因是包括空格在内的单个字符共有27个)

但是这种方法仍然容易冲突:string、street、strong、structure等等;

而且会造成空间浪费,理论上来说,前三字符所有可能性的组合为26^3种,但经过统计得到,实际中的组合约3000种,3000/26^3\approx 0.3,即空间利用率大约30%,浪费了70%的空间。

移位法

涉及关键词所有n个字符,并且分布得很好;

h(key)=(\overset{n-1}{\underset{i=0}{\sum}}key[n-i-1]\times 32^i)\: \: mod\: \: TableSize

例如:h(“abcde”) = ‘a’ * 32^4 + ‘b’ * 32^3  + ‘c’ * 32^2  + ‘d’ * 32 + ‘e’。

用这个计算方法需要乘10次,我们看一下比较快的计算方法:

h(“abcde”) = (((‘a’ * 32 + b) * 32 + c) * 32 + d ) * 32 + e,

用这种方法,在计算时就只需要乘4次

还有没有更巧妙的办法呢?

我们发现32是2的5次方,于是可以通过移位,也就是将一个数往左二进制移位五次,就相当于*32.

于是有:

Index Hash(const char *Key, int TableSize)
{unsigned int h = 0; /* 散列函数值,初始化为0  */while( *Key != '\0'){h = (h << 5) + *Key++;}return h % TableSize;
}

end


学习自:MOOC数据结构——陈越、何钦铭

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

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

相关文章

QT生成可执行文件的步骤

QT生成可执行文件的步骤 第一步&#xff1a;debug为release&#xff0c;然后进行编译 第二步&#xff1a;添加QT生成必要的库 首先&#xff0c;建立一个新的文件夹&#xff0c;然后将Release中的可执行文件拷贝到新的文件夹中 然后&#xff0c;在新建文件夹中生成必要的库 …

Nginx(1)

目录 1.Nginx概述2.Nginx的特点3.Nginx主要功能1.反向代理2.负载均衡 1.Nginx概述 Nginx (engine x) 是一个自由的、开源的、高性能的HTTP服务器和反向代理服务器&#xff0c;也是一个IMAP、POP3、SMTP代理服务器。 Nginx是一个强大的web服务器软件&#xff0c;用于处理高并发…

别再被问倒了!Mysql索引竟然在这些情况下失灵?

嗨&#xff0c;亲爱的读者们&#xff01;小米又来啦~ 今天我们要聊一个在数据库面试中常常被问到的热门话题&#xff1a;Mysql索引失效。想要在面试中脱颖而出&#xff0c;掌握这个知识点可是必不可少哦&#xff01;废话不多说&#xff0c;咱们现在就深入剖析一下&#xff0c;看…

C#,数值计算——基于模拟退火的极小化问题单纯形(下山)算法的计算方法与C#源程序

1 模拟退火 模拟退火算法其实是一个类似于仿生学的算法&#xff0c;模仿的就是物理退火的过程。 我们炼钢的时候&#xff0c;如果我们急速冷凝&#xff0c;这时候的状态是不稳定的&#xff0c;原子间杂乱无章的排序&#xff0c;能量很高。而如果我们让钢水慢慢冷凝&#xff0c…

小研究 - 微服务系统服务依赖发现技术综述(一)

微服务架构得到了广泛的部署与应用, 提升了软件系统开发的效率, 降低了系统更新与维护的成本, 提高了系统的可扩展性. 但微服务变更频繁、异构融合等特点使得微服务故障频发、其故障传播快且影响大, 同时微服务间复杂的调用依赖关系或逻辑依赖关系又使得其故障难以被及时、准确…

pycharm中opencv库导入 cv2. 无函数提示跳出解决方法

pycharm中opencv库导入 cv2. 无函数提示跳出解决方法 1、找到当前解释器安装目录 例如&#xff1a; 2、进入D:\Python37\Lib\site-packages\cv2文件&#xff0c;进入cv2文件夹&#xff1a; 找到cv2.pyd, 把cv2.pyd复制一份&#xff0c;放到上层文件夹下&#xff0c;即site-p…

数据结构 | 二叉树的应用

目录 一、解析树 二、树的遍历 一、解析树 我们可以用解析树来表示现实世界中像句子或数学表达式这样的构造。 我们可以将((73)*(5-2))这样的数学表达式表示成解析树。这是完全括号表达式&#xff0c;乘法的优先级高于加法和减法&#xff0c;但因为有括号&#xff0c;所以在…

ffmpeg下载安装教程

ffmpeg官网下载地址https://ffmpeg.org/download.html 这里以windows为例,鼠标悬浮到windows图标上,再点击 Windows builds from gyan.dev 或者直接打开 https://www.gyan.dev/ffmpeg/builds/ 下载根据个人需要下载对应版本 解压下载的文件,并复制bin所在目录 新打开一个命令…

基于YOLOv7开发构建MSTAR雷达影像目标检测系统

MSTAR&#xff08;Moving and Stationary Target Acquisition and Recognition&#xff09;数据集是一个基于合成孔径雷达&#xff08;Synthetic Aperture Radar&#xff0c;SAR&#xff09;图像的目标检测和识别数据集。它是针对目标检测、机器学习和模式识别算法的研究和评估…

手把手写深度学习(20):搭建LLM大语言模型的敏感词过滤系统

前言:随着Llama 2、通义千问7B等越来越多的大语言模型开源,开发者们可以基于这些开源的模型搭建自己的对话系统、Agent等。但是因为我们的国情,需要开发者对这些模型进行一些特殊的“安全性”考虑,保证与用户的交互不会出现“有害信息”。这篇博客手把手教大家搭建一个大语…

【Vue3】动态组件

动态组件的基本使用 动态组件&#xff08;Dynamic Components&#xff09;是一种在 Vue 中根据条件或用户输入来动态渲染不同组件的技术。 在 Vue 中使用动态组件&#xff0c;可以使用 元素&#xff0c;并通过 is 特性绑定一个组件的名称或组件对象。通过在父组件中改变 is 特…

2023牛客暑期多校训练营4

Bobo String Construction 结论&#xff0c;字符串哈希 Election of the King 二分查找 Merge the squares! 递归模拟&#xff0c;辗转相除法 Quest-ce Que Cest? DP&#xff0c;前缀和优化 We are the Lights 思维&#xff0c;倒推 猜测是&#xff0c;把n个字符全填0或者1是最…

亿发江西中小型制造企业信息化建设解决方案,2023数字化转型升级

实体经济在经济中的重要性愈发凸显&#xff0c;江西省作为制造业强省&#xff0c;要实现制造业经济高质量发展&#xff0c;信息技术与制造业的深度汇合是不可或缺的关键路径。在这个制造业转型升级的浪潮中&#xff0c;中小企业成为了江西省制造业转型的焦点。让我们深入探讨一…

Redis 7.X Linux 环境安装

Redis 简介 作为一名开发人员&#xff0c;想必大家对Redis一定是耳熟能详&#xff0c;因此在此只做简单介绍。 Remote Dictionary Server(远程字典服务)是完全开源的&#xff0c;使用ANSIC语言编写遵守BSD协议&#xff0c;是一个高性能的Key-Value内存数据库&#xff0c;它提…

分布式 - 服务器Nginx:一小时入门系列之HTTP反向代理

文章目录 1. 正向代理和反向代理2. 配置代理服务3. proxy_pass 命令解析4. 设置代理请求headers 1. 正向代理和反向代理 正向代理是客户端通过代理服务器访问互联网资源的方式。在这种情况下&#xff0c;客户端向代理服务器发送请求&#xff0c;代理服务器再向互联网上的服务器…

抖音seo矩阵系统源代码开发搭建技术分享

抖音SEO矩阵系统是一个较为复杂的系统&#xff0c;其开发和搭建需要掌握一定的技术。以下是一些技术分享&#xff1a; 技术分享 抖音SEO矩阵系统的源代码可以使用JAVA、Python、PHP等多种语言进行开发。其中&#xff0c;JAVA语言的应用较为广泛&#xff0c;因为JAVA语言有良好…

软件架构师思维塑造

一、软件系统设计的六项原则 1、单一职责原则&#xff08;Single Responsibility Principle&#xff09; 2、开闭原则&#xff08;Open Closed Principle&#xff09; 3、里氏替换原则&#xff08;Liskov Substitution Principle&#xff09; 4、迪米特法则&#xff08;Law of …

无涯教程-Lua - nested语句函数

Lua编程语言允许在另一个循环中使用一个循环。以下部分显示了一些示例来说明这一概念。 nested loops - 语法 Lua中嵌套for循环语句的语法如下- for init,max/min value, increment dofor init,max/min value, incrementdostatement(s)endstatement(s) end Lua编程语言中的…

IMV3.0

经历了两个版本&#xff0c;基础内容在前面&#xff0c;可以使用之前的基础环境&#xff1a; v1&#xff1a; https://blog.csdn.net/wtt234/article/details/132139454 v2&#xff1a; https://blog.csdn.net/wtt234/article/details/132144907 一、代码组织结构 二、代码 2.…

下载网络文件到本地

文章目录 目录 前言 操作步骤 1.引入 2.读取出文件内容 3.筛选出URL 4.下载表情包 总结 前言 这里记录一次用代码下载网络文件的过程&#xff0c;以获取抖音表情包为例。 一、操作步骤 1.引入 首先抖音有网页版&#xff0c;用浏览器就可以观看&#xff0c;用户评论发布表情在…