《哈希表》

news/2024/12/29 0:18:01/

【一】哈希概念

顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码的多次比较,顺序查找时间的复杂度为O(N),平衡树中为树的高度,即O(log2N),搜索的效率取决于搜索过程中元素的比较次数。

理想的搜索方式:可以不经过任何比较,一次直接从表中得到要搜索的元素。

如果构造一种存储结构,通过某种函数(hashfunc)使元素的存储位置和它的关键码之间能够建立一一映射的关系,那么在查找时可以通过该函数直接锁定该元素的位置。

当向该元素中:

插入元素:根据插入元素的关键码,以此函数计算出该元素的存储位置并且按此位置进行存放

搜索函数:对元素的关键码进行同样的计算,把求得的函数值当作元素的存储位置,在结构中按此位置取元素比较,若关键码相同,则搜索成功。

这就是我们所说的哈希(散列)方法,哈希方法中使用的函数被称为哈希(散列)函数,构造出来的结构称为哈希表或者散列表。

用这种存储方式不必进行多次关键码的搜索,所以搜索的速度是很快的。

tips:如果插入两个相同的数据时,会发生什么事?

【二】哈希冲突

定义:不同关键字通过相同哈希函数计算出相同的哈希地址,这种现象被称为哈希冲突或者哈希碰撞,把具有不同关键码而具有相同哈希地址的数据元素称为同义词。那么如果发生哈希冲突如何处理呢?

引起哈希冲突的一个原因可能是:哈希函数设计不是很合理,哈希函数的设计原则:

1.哈希函数的定义域必须包括需要存储的关键码,如果散列表允许有m个地址时,其值域必须在0-m-1之间,哈

2.哈希函数计算出来的地址能均匀分布在整个空间中

3.哈希函数尽可能按照简单的方式来设计。

常见的几个哈希函数:

1.直接定址法(常用)

取关键字的某个线性函数为散列地址:Hash(Key)=A*Key + B

优点:简单,均匀

缺点:需要先知道关键字分布的状态

2.除留余数法

设散列表中允许的地址为m,取一个不大于m,但是接近或者等于m的质数p作为除数,按照哈希函数:Hash(key)=key%p(p<=m),将关键码转为哈希地址。

3.平方取中法则:

假设关键字为1234,对它平方就是1522756,抽取中间的3位227作为哈希地址; 再比如关键字为4321,对它平方就是18671041,抽取中间的3位671(或710)作为哈希地址。平方取中法比较适合:不知道关键字的分布,而位数不是很大的情况。

4.折叠法:

折叠法是将关键字从左到右分割成位数相等的几部分(最后一部分位数可以短些),然后将这 几部分叠加求和,并按散列表表长,取后几位作为散列地址。

5.随机数法:

选择一个随机函数,取关键字的随机函数值为它的哈希地址,即H(key) = random(key),其中 random为随机数函数。

关键字不长时均采用此法。

哈希冲突解决:哈希函数设计的越精妙,产生哈希冲突的可能性就越低,但是无法避免哈希冲突

所以哈希冲突的两种解决方式:闭散列和开散列

闭散列:也叫开放地址法,当发生哈希冲突时,如果哈希表未被填满,说明在哈希表中必然还有空位置,那么可以把key存放到冲突的下一个位置取,那如何取寻找下一个空位置呢?

线性探测:从发生冲突的位置开始,依次向后探测,直到寻找到下一个空位置为止,

插入:通过哈希函数获取待插入元素在哈希表中的为止

如果该位置中没有元素则直接插入新元素,如果该位置中有元素发生哈希冲突,使用线性探测找到下一个空位置,插入新元素。

删除:采用闭散列处理哈希冲突时,不能随便删除哈希表中已有的元素,若直接删除元素会影响其它元素的搜索。所以哈希表使用的时候删除使用的标记位删除的方式。

思考:哈希表什么情况下需要进行扩容?如何进行扩容?

散列表的负载因子:填入表中的因子/散列表的长度

负载因子是散列表负载程度的标志性因子,由于表长是定值,a与填入表中的元素个数成正比,所以a越大,填入表中的元素越多,产生冲突的可能性就越大,对于开放定址法,荷载因子是特别重要因素,应严格限制在0. 7-0. 8以下。超过0. 8,查表时的CPU缓存不命中(cache 对于开放定址法,荷载因子是特别重要因素,应严格限制在0.7-08以下。超过0.查表时的cpu缓存不命中(缓存)missing)按照指数曲线上升。因此,- - 些采用开放定址法的hash库,如Java的系统库限制了荷载因子为0. 75,超过此值将 失踪)按照指数曲线上升。因此,--些采用开放定址法的散列库,如Java的系统库限制了荷载因子为0.75。

二次探测

线性探测的缺陷是产生冲突的数据堆积在一起,这与其寻找下一个空位置有关系,因为找空位置的方式是挨个向后找,因此二次探测为了避免该问题,找下一个空位置的方法 为:$H_i$ = ($H_0$ + $i^2$ )% m, 或者:$H_i$ = ($H_0$ - $i^2$ )% m。其中:i = 1,2,3…, $H_0$是通过散列函数Hash(x)对元素的关键码 key 进行计算得到的位置,m是表 的大小。

研究表明:当表的长度为质数且表装载因子不超过0.5时,新的表项一定能够插入,而且任何一个位置不会被探测两次,因此只要表中有一半的空位置,就不会存在表满的问题,在搜索时可以不考虑表装满的情况,但在插入时必须确保表的状态因子不超过0.5,如果超出必须要进行增容,所以比散列的最大缺陷就是空间利用率低,这也是哈希的缺陷

【三】开散列

概念:开散列又叫链地址法(开链法),首先对关键码集合用散列函数计算散列地址,具有相同地址的关键码归于同一子集合,每一个子集合统称为一个捅,各个捅中的元素通过一个单链表链接起来,各链表的头节点存储在哈希表中。

 从上图可以看出,开散列每个捅中存放的都是发生哈希冲突的元素。

开散列的增容

桶的个数是一定的,随着元素的不断插入,每个桶中元素的个数不断增多,极端条件下,可能会导致一个桶节点非常多,会影响的哈希表的性能,因此在一定条件下需要对哈希表进行增容,那该条件怎么确认呢?开散列的最好情况是:每个哈希桶中刚好挂一个节点,再继续插入元素时,每一次都会发生哈希冲突,因此,在元素个数刚好等于插入桶的个数时,可以使用哈希表增容。

开散列与闭散列的比较

应用链地址法处理溢出时,需要增设链接指针,似乎增加了存储开销,事实上,由于开地址法需要保持大量的空闲空间以确保搜索效率,如二次探测法要求装载因子<=0.7,而表项所占空间又比指针大很多,所以使用链地址法反而比开地址发节省空间。    


http://www.ppmy.cn/news/343595.html

相关文章

Haar小波变换

1.哈尔基函数 最简单的基函数是哈尔基函数(Haar basis function)。哈尔基函数在1909年提出&#xff0c;它是由一组分段常值函数组成的函数集。这个函数集定义在半开区间[0,1)上&#xff0c;每一个分段常值函数的数值在一个小范围里是1&#xff0c;其他地方为0&#xff0…

雷达信号波形(一)

1. 功率信号和能量信号及它们的时域和频域性质 确知信号的分类。根据不同的分类标准可以分为周期信号和非周期信号&#xff0c;连续信号和离散信号&#xff0c;能量信号和功率信号等等。这里需要掌握的是信号的能量表达式&#xff0c;功率信号和能量信号的定义以及重点掌握它们…

雷达篇(三)FMCW雷达框图及原理介绍

目录 1 FMCW雷达基本框架 2 FMCW原理介绍 1 FMCW雷达基本框架 调频连续波雷达的基本框图如图 1所示&#xff0c;框架中主要包括上位机显示与控制界面、信号处理机、收发支路以及天线四个部分。 1) 上位机显示与控制界面主要功能&#xff1a; a) 显示…

哈希冲突-哈希碰撞

当我们对某个元素进行哈希运算&#xff0c;得到一个存储地址&#xff0c;然后要进行插入的时候&#xff0c;发现已经被其他元素占用了&#xff0c;其实这就是所谓的哈希冲突&#xff0c;也叫哈希碰撞。 哈希函数的设计至关重要&#xff0c;好的哈希函数会尽可能地保证 计算简单…

哈希碰撞

一、什么是哈希碰撞 所谓哈希&#xff08;hash&#xff09;&#xff0c;就是将不同的输入映射成独一无二的、固定长度的值&#xff08;又称"哈希值"&#xff09;。它是最常见的软件运算之一。如果不同的输入得到了同一个哈希值&#xff0c;就发生了"哈希碰撞&q…

分析数据之雷达图

结果图&#xff1a; 步骤分析如图&#xff1a; 极轴就是极坐标系的开始位置&#xff0c;代码中的angles就是极轴转出来的角度 1、明确有几个特征&#xff0c;将圆平均切分 2、每个特征的数据 3、绘图 代码&#xff1a; import matplotlib.pyplot as plt import numpy as n…

R实战| 雷达图(Radar Chart)

R实战| 雷达图(Radar Chart) 雷达图(radar chart)&#xff0c;又称蜘蛛网图(spider plot)&#xff0c;是一种表现多维数据的强弱的图表。它将多个维度的数据量映射到坐标轴上&#xff0c;这些坐标轴起始于同一个圆心点&#xff0c;通常结束于圆周边缘&#xff0c;将同一组的点使…

echarts 雷达图

Echarts 常用各类图表模板配置 注意&#xff1a; 这里主要就是基于各类图表&#xff0c;更多的使用 Echarts 的各类配置项&#xff1b; 以下代码都可以复制到 Echarts 官网&#xff0c;直接预览&#xff1b; 图标模板目录 Echarts 常用各类图表模板配置一、雷达图二、环形图三…