《哈希表》

news2025/1/17 15:12:24

【一】哈希概念

顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码的多次比较,顺序查找时间的复杂度为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.coloradmin.cn/o/117080.html

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

相关文章

JavaWeb技术栈概述

1.1 Web概述 Web是全球广域网&#xff0c;也称为万维网&#xff08;www&#xff09;&#xff0c;能够通过浏览器访问的网站。 在我们日常的生活中&#xff0c;经常会使用浏览器去访问百度、京东、传智官网等这些网站&#xff0c;这些网站统称为Web网站。如下就是通过浏览器访问…

实验三 第四章 MongoDB 副本集

一、实验目的&#xff1a; 了解MongoDB副本集 熟悉MongoDB副本集成员 掌握MongoDB副本集部署 掌握MongoDB副本集操作 理解副本集机制 二、实验环境&#xff1a; 一台win10系统的笔记本电脑 三、实验内容&#xff1a; 4.3部署副本集 4.3.1环境准备 创建的三台虚拟机配置如下&a…

python中的split()、rsplit()、splitlines()用法比较

1 split() 从左向右切割2 rsplit() 从右向左分割3 splitlines() 根据换行符切割4 rsplit()妙用split(分隔符&#xff0c;分割几次)从左向右寻找&#xff0c;分割元素并放入列表中&#xff0c;该分隔符丢弃&#xff1b; rsplit(分隔符&#xff0c;分割几次)从右向左寻找&#x…

算法的复杂性分析

算法的复杂性分析 文章目录算法的复杂性分析0、 算法评价的基本原则1、影响程序运行时间的因素2、算法复杂度2.1 算法的时间复杂度2.2 渐进表示法2.2.1 运行时间的上界2.2. 运行时间的下界2.2.3 运行时间的准确界3、总结4、参考0、 算法评价的基本原则 评价一个算法的好坏实际就…

第二证券|市场短期盘整 不改中期向好格局

12月初以来A股商场全体走势偏弱&#xff0c;上星期首要指数更是五连跌&#xff0c;上证指数重回3100点下方。关于商场近期的再度调整&#xff0c;本周组织观念显现&#xff0c;疫情带来的扰动或是首要原因。 不过&#xff0c;大都组织以为&#xff0c;心情面要素对商场的影响仅…

面试官:ui组件可以自动加载,那么业务组件可以吗?

大厂面试题分享 面试题库 前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 背景 笔者在最近在公司接手了一个老的对内使用的项目&#xff0c;接手后体验了下 发现首屏加载比较慢。分析了下大概的原因是main.js挂…

算法进阶:双指针(一)c++leetcode例题

82. 删除排序链表的重复元素 力扣传送&#xff1a; https://leetcode.cn/problems/remove-duplicates-from-sorted-list-ii/description/ 给一个排好序的链表&#xff0c;删除把链表中出现的所有的重复的项&#xff1a; 1 2 2 3 3 3 4 5 -----> 1 4 5 这道题有很多种解法&a…

Unity3D——第一人称FPS生存游戏(resident zombies)

游戏源文件和游戏试玩程序:链接&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1Ln2tFizqEO_uEoQhuxvgrQ?pwdl6w0 提取码&#xff1a;l6w0 游戏思路前身搭建: 用一些正方体和胶囊做出来的基础场景&#xff0c; 人物设计:红色的胶囊体是敌人&#xff0c;手持枪械是…

一文说透BIO以及非阻塞IO

目录1. 一次I/O到底经历了什么2. 什么是Socket3. 阻塞I/O&#xff08;Blocking I/O&#xff0c;BIO&#xff09;3.1. 客户端的socket流程3.1.1. 何为socket&#xff1f;3.1.2. 何为连接&#xff1f;3.2. 服务端的socket流程3.2.1. 创建socket3.2.2. 绑定端口号3.2.3. listen()的…

项目实战之旅游网(六)认证与授权

一.编写相关页面 在本项目中&#xff0c;我们使用Spring Security 进行认证和授权&#xff0c;首先我们先编写相关页面。 1.编写登录页面admin_ login.html 2.编写登录失败页面admin_ fail.html 3.编写权限不足页面no_ permission.html 略过。知道其功能即可。 二.编写配置…

数字孪生城市可视化大屏设计,智慧楼宇开源项目

纵观城市发展历史&#xff0c;技术的革命必然会带动城市内部的变革。当前&#xff0c;以数字孪生为代表的前言信息技术飞速发展&#xff0c;必然会使社会对数字城市的深度和广度有着更为清晰的认知。加快构建数字孪生城市管理平台&#xff0c;通过三维可视化大屏直观展示&#…

图表控件LightningChart.NET 系列教程(六):许可证管理介绍(中)

LightningChart.NET SDK 是一款高性能数据可视化插件工具&#xff0c;由数据可视化软件组件和工具类组成&#xff0c;可支持基于 Windows 的用户界面框架&#xff08;Windows Presentation Foundation&#xff09;、Windows 通用应用平台&#xff08;Universal Windows Platfor…

Apache ShardingSphere-Proxy <5.3.0 存在身份认证绕过漏洞

漏洞描述 Apache ShardingSphere 是一款分布式的数据库生态系统&#xff0c;ShardingSphere-Proxy 是支持 MySQL、PostgreSQL 和 openGauss 协议的数据库代理模块。 ShardingSphere-Proxy 5.3.0 之前的版本中在使用 MySQL 作为后端数据库时&#xff0c;在客户端认证失败后没有…

Linux进程状态与优先级

Ⅰ. OS进程状态的概念 进程状态反映进程执行过程的变化。这些状态随着进程的执行和外界条件的变化而转换。 在三态模型中&#xff0c;进程状态分为 运行态&#xff0c;就绪态&#xff0c;阻塞态。 在五态模型中&#xff0c;进程状态分为 新建态、终止态&#xff0c;运行态&a…

服务雪崩预防Sentinel

服务雪崩效应 在分布式系统中,由于网络原因或自身的原因,服务一般无法保证 100% 可用。如果一个服务出现了 问题&#xff0c;调用这个服务就会出现线程阻塞的情况&#xff0c;此时若有大量的请求涌入&#xff0c;就会出现多条线程阻塞等 待&#xff0c;进而导致服务瘫痪。 由于…

【HTML+CSS+JavaScript】实现鼠标点击烟花效果

文章目录【HTMLCSSJavaScript】实现鼠标点击烟花效果&#xff08;爆炸型、心型、圆形&#xff09;一. 效果图二. 鼠标点击烟花效果 - 心型实现代码(1) HTML部分代码(2) CSS部分代码(3) 内部的JavaScript部分代码三. 鼠标点击烟花效果 - 圆型实现代码(1) HTML部分代码(2) CSS部分…

【mysql】优化系列文章之一-索引

mysql优化系列 不是教程&#xff0c;不是官方文档&#xff0c;而是自己实战的点滴记录&#xff0c;不一定适合新手和系统学习者 第一章 mysql索引 文章目录mysql优化系列前言1、Mysql索引2、B Tree2.1.特点2.2. 结构分解2.3. 例题分析2.4. 验证索引2.5.索引插入耗时3. MySQL 中…

Oracle数据库同步复制工具Beedup产品功能(一)

1、全量复制 Beedup全量复制功能通过遍历比对主从库用户模式及其下包含的各类对象来保证主从库的相关对象一致性。 支持角色、用户、架构、登录用户、表 (列定义 主外键 索引)、视图存储过程、函数、触发器、类型、类型体、包、包体、序列、同义词、数据库链接等对象复制全量…

技术干货 | 人大金仓KFS基于分区索引的分片入库技术解析

在之前的文章《技术干货&#xff1a;人大金仓KFS精准过滤和分片并行入库技术解析》中&#xff0c;KFS利用分片并行入库技术&#xff0c;解决了某金融POC数据同步项目中数据入库持续积压问题。经过优化后&#xff0c;在200并发的压测场景中&#xff0c;整体同步性能指标从压测30…

基于BP神经网络、RBF神经网络以及PSO优化的RBF神经网络进行数据的预测(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑…