【数据结构 | 哈希表】一文了解哈希表(散列表)

news2024/9/24 0:08:36

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍哈希表 🍭
😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭
⏰发布时间⏰: 2024-07-24 14:48:55

本文未经允许,不得转发!!!

目录

  • 🎄一、概述
  • 🎄二、键值对(key-value pair)
  • 🎄三、哈希函数
  • 🎄四、哈希冲突(哈希碰撞)
    • ✨4.1 开发地址法
    • ✨4.2 链地址法
  • 🎄五、哈希表的使用
  • 🎄六、总结


在这里插入图片描述

在这里插入图片描述

🎄一、概述

在学习过的简单数据结构当中,
数组的特点:访问(寻址)速度较快的、但插入、删除操作较慢;
链表的特点:访问(寻址)速度较慢的、但插入、删除操作很快
所以,有些大牛就想着能不能结合这数组、链表的优点,造出一个 访问(寻址)速度较快的、插入、删除操作也很快 的数据结构,后面就造出来一个 哈希表。

哈希表(Hash Table):也叫做散列表。是根据关键码值(Key Value)直接进行访问的数据结构。

哈希表存储的都是键值对(Key-Value),即一个关键字对应一个内容,给出关键字就可以在哈希表中找到对应内容。

哈希表的工作过程:哈希表通过键值对的 关键字(key)哈希函数 计算出对应的一个位置,通常是数组下标,然后把整个 键值对(代码中叫Entry)存放到这个位置,以加快查找的速度。如果多个 关键字(key) 得到同一位置就会产生 哈希冲突,需要通过一个方法去解决。

这里面有好几个概念,会在后面的内容去介绍。


在这里插入图片描述

🎄二、键值对(key-value pair)

键值对(key-value pair):就是一个关键字(key)对应一个值(value)的组合,要求每个键值对的 关键字(key) 不能重复。下面表格就是一些键值对。

KeyValue
xia
za
zai
zan
zang

在代码里可以使用下面结构体去表现一个键值对:

struct table_entry{
	const char* key;
	void *value;
}

哈希表是存储 键值对 的,那它是怎样存储的呢?
哈希表要求每个键值对的 关键字(key) 不能重复,然后通过键值对的 关键字(key) 来定位每个键值对存放的位置,这个位置就是 哈希地址,而将 关键字(key) 映射成 哈希地址 的函数就是 哈希函数

在哈希表中,会把 键值对(key-value) 的key称为键值。


在这里插入图片描述

🎄三、哈希函数

哈希函数(Hash Function):也叫散列函数,将哈希表中元素的关键键值(key)映射为元素存储位置(哈希地址)的函数。

哈希函数是哈希表中最重要的部分。一般来说,哈希函数会满足以下几个条件:

  • 哈希函数应该易于计算,并且尽量使计算出来的索引值均匀分布。
  • 哈希函数计算得到的哈希值是一个固定长度的输出值。
  • 计算出来的哈希地址不同,则传入键值(key)肯定不同;
    Hash(key1) != Hash(key2),则 key1 != key2。
    
  • 如果 Hash(key1) 等于 Hash(key2),那么 key1、key2 可能相等,也可能不相等(会发生哈希冲突)

在哈希表的应用中,最常见的2种键值类型是:字符串、数字。而其他键值类型还可以是是字符串类型、浮点数类型、大整数类型,甚至还有可能是几种类型的组合。设计哈希函数时,要根据键值类型的特点去设计,一般会先将键值转成整型再去计算,因为最终计算出来的一般是一个数组下标(Index)。

常见的哈希函数方法有:直接定址法、除留余数法、平方取中法、基数转换法、数字分析法、折叠法、随机数法、乘积法、点积法等。

假设我们把上个小节的键值对存到一个哈希表,并通过哈希函数计算出哈希地址,如下表:

KeyValue哈希地址(Index)
xia517
za597
zai597
zan599
zang600

就像上面表格一样,哈希函数有时就将两个不同的键值计算出同一个哈希地址,这就造成了哈希冲突(哈希碰撞)


在这里插入图片描述

🎄四、哈希冲突(哈希碰撞)

哈希冲突(Hash Collision):不同的关键字通过同一个哈希函数可能得到同一哈希地址,即 key1 ≠ key2,而 Hash(key1) = Hash(key2),这种现象称为哈希冲突。

理想状态下,是每个key通过哈希函数都计算出不同的哈希地址,这样直接将键值对存入即可。但实际使用中一般都会出现哈希冲突的,这时就需要处理哈希冲突。处理哈希冲突的方法一般有两种:开放地址法、链地址法。

✨4.1 开发地址法

开放地址法(Open Addressing):指的是将哈希表中的 空地址 向处理冲突开放。当哈希表未满时,处理冲突时需要尝试另外的单元,直到找到空的单元为止。

开放地址法主要有三种实现:

  • 线性探测(Linear Probing):发生冲突时,依次检查下一个地址,直到找到空闲位置。
  • 二次探测(Quadratic Probing):冲突时,以二次函数的方式探查空闲位置。
  • 双重哈希(Double Hashing):使用两个哈希函数,当发生冲突时,使用第二个哈希函数计算新的探查位置。

✨4.2 链地址法

链地址法(Chaining):将具有相同哈希地址的元素(或记录)存储在同一个线性链表中。

链地址法是一种更加常用的哈希冲突解决方法。相比于开放地址法,链地址法更加简单。

具体的做法是当哈希地址的位置是空的话,就直接将 键值对 存入该位置;如果不为空,就将 键值对 存到该地址的链表中,所以在代码实现时,会在键值对所在结构体中加一个next指针,用于实现链表。

struct TableEntry {
    TableEntry* fNext;
    char const* key;
    void* value;
};

在这里插入图片描述


在这里插入图片描述

🎄五、哈希表的使用

虽然上面说了那么多的概念,但只是使用哈希表并不需要知道这些。如果是要看别人实现哈希表的代码,则必须要清楚上面的那些概念,这里再总结一下:

  • 1、键值对(Key-Value Pair):是一种数据结构的表示形式,其中“键(Key)”是用于标识和查找数据的唯一标识符,“值(Value)”则是与该键相关联的数据。例如,在字典中,单词(键)与其释义(值)就构成了键值对。
  • 2、哈希函数(Hash Function):是一种将输入(通常是键)转换为固定长度输出(称为哈希值)的函数。哈希函数的设计目标是使得不同的输入尽可能产生不同的输出,并且输出分布均匀。
  • 3、哈希值(Hash Value):通过哈希函数对输入(键)进行计算得到的固定长度的数值。
  • 4、哈希地址(Hash Address):哈希值所对应的存储位置。通常,哈希表会根据哈希值来确定数据在内存中的存储位置。
  • 5、哈希冲突(Hash Collision):当两个或多个不同的键通过哈希函数计算得到相同的哈希值时,就发生了哈希冲突。这可能导致这些键对应的元素需要存储在同一个哈希地址,从而引发数据存储和检索的问题。

如果只是使用哈希表的话,只需要知道哈希表提供了哪些操作即可。哈希表至少会提供三个操作:插入、删除、查询。我们只需要知道怎样插入键值对、怎样删除、怎样查询就差不多了。


在这里插入图片描述

🎄六、总结

👉本文介绍哈希表实现过程中的重要概念:键值对、键值、哈希函数、哈希冲突、处理哈希冲突等,看完后可以对哈希表有一定的了解。

在这里插入图片描述
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

参考:
https://blog.csdn.net/zy_dreamer/article/details/131036258
https://blog.csdn.net/sinat_33921105/article/details/103344078
https://blog.csdn.net/m0_65781965/article/details/136987203

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

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

相关文章

【SQL语句大全(MySQL)】

SQL语法 添加删除修改查询基本查询条件查询分组函数/聚合函数分组查询排序分页查询(限制查询)多表查询连接查询根据年代分类连接查询根据连接方式分类1、内连接2、左外连接3、右外连接 多张表连接的语法格式 嵌套查询 SQL语句书写顺序 添加 INSERT INTO…

什么是STP环路保护

在运行生成树协议的网络中,根端口和其他阻塞端口状态是依靠不断接收来自上游设备的BPDU维持。当由于链路拥塞或者单向链路故障导致这些端口收不到来自上游交换设备的BPDU时,设备会重新选择根端口。原先的根端口会转变为指定端口,而原先的阻塞…

2019年9月全国英语等级考试第三级笔试真题

2019年9月全国英语等级考试第三级笔试真题

vue3.0学习笔记(三)——计算属性、监听器、ref属性、组件通信

1. computed 函数 定义计算属性: computed 函数,是用来定义计算属性的,计算属性不能修改。 计算属性应该是只读的,特殊情况可以配置 get set 核心步骤: 导入 computed 函数 执行函数 在回调参数中 return 基于响应…

尚品汇-sku存入Redis缓存(二十三)

目录: (1)分布式锁改造获取sku信息 (2)使用Redisson 分布式锁 AOP实现缓存 (3)定义缓存aop注解 (1)分布式锁改造获取sku信息 前面学习了本地锁的弊端,…

Springboot validated JSR303校验

1.导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency> 2.测试类 package com.jmj.gulimall.product.testC;import lombok.Data;import javax.val…

《0基础》学习Python——第二十讲__网络爬虫/<3>

一、用post请求爬取网页 同样与上一节课的get强求的内容差不多&#xff0c;即将requests.get(url,headershead)代码更换成requests.post(url,headershead),其余的即打印获取的内容&#xff0c;如果content-typejson类型的&#xff0c;打印上述代码的请求&#xff0c;则用一个命…

argon主题调整日记

前言 argon主题是一款由solstice23开发的一款简洁美观的WordPress主题&#xff0c;在使用过程中也发现了几个可以优化的点&#xff0c;在查阅主题文档无果后对其进行以下几点修改。 1、使用子主题 为了避免修改源文件而引起主题更新后修改丢失的问题&#xff0c;还是尽量使用子…

一个C++模板工厂的编译问题的解决。针对第三方库的构造函数以及追加了的对象构造函数。牵扯到重载、特化等

一窥模板的替换和匹配方式&#xff1a;偏特化的参数比泛化版本的还要多&#xff1a;判断是不是std::pair&#xff1c;,&#xff1e;。_stdpair模板参数太多-CSDN博客 简介 在一个项目里&#xff0c;调用了第三封的库&#xff0c;这个库里面有个类用的很多&#xff0c;而且其构…

Mindspore框架循环神经网络RNN模型实现情感分类|(六)模型加载和推理(情感分类模型资源下载)

Mindspore框架循环神经网络RNN模型实现情感分类 Mindspore框架循环神经网络RNN模型实现情感分类|&#xff08;一&#xff09;IMDB影评数据集准备 Mindspore框架循环神经网络RNN模型实现情感分类|&#xff08;二&#xff09;预训练词向量 Mindspore框架循环神经网络RNN模型实现…

【Vue实战教程】之 Vue Router 路由详解

Vue Router路由 1 路由基础 1.1 什么是路由 用Vue.js创建的项目是单页面应用&#xff0c;如果想要在项目中模拟出来类似于页面跳转的效果&#xff0c;就要使用路由。其实&#xff0c;我们不能只从字面的意思来理解路由&#xff0c;从字面上来看&#xff0c;很容易把路由联想…

CV13_混淆矩阵、F1分数和ROC曲线

1.1 混淆矩阵Confusion Matrix 混淆矩阵&#xff08;Confusion Matrix&#xff09;是机器学习和统计学中用于描述监督学习算法性能的特定表格布局。它是一种特定类型的误差矩阵&#xff0c;可以非常直观地表示分类模型在测试数据集上的预测结果与实际结果之间的对比。 混淆矩…

谣言检测文献阅读十二—A Convolutional Approach for Misinformation Identification

系列文章目录 谣言检测文献阅读一—A Review on Rumour Prediction and Veracity Assessment in Online Social Network谣言检测文献阅读二—Earlier detection of rumors in online social networks using certainty‑factor‑based convolutional neural networks谣言检测文…

FreeModbus学习——读输入寄存器eMBFuncReadInputRegister

FreeModbus版本&#xff1a;1.6 当功能码为04时&#xff0c;也就是读输入寄存器MB_FUNC_READ_INPUT_REGISTER 看一下它是怎么调用读输入寄存器处理函数的 当功能码为04时&#xff0c;调用读输入寄存器处理函数 这个函数在数组xFuncHandlers中&#xff0c;也就是eMBFuncRead…

Mysql数据库第四次作业

mysql> create table student(sno int primary key auto_increment,sname varchar(30) not null unique,Ssex varchar(2) check (Ssex男 or Ssex女) not null,Sage int not null,Sdept varchar(10) default计算机 not null); mysql> create table Course(Con int primar…

【通信协议-RTCM】MSM语句(2) - RINEXMSM7语句总结(重要!自动化开发计算卫星状态常用)

注释&#xff1a; 在工作中主要负责的是RTCM-MSM7语句相关开发工作&#xff0c;所以主要介绍的就是MSM7语句相关内容 1. 相位校准参考信号 2. MSM1、MSM2、MSM3、MSM4、MSM5、MSM6和MSM7的消息头内容 DATA FIELDDF NUMBERDATA TYPENO. OF BITSNOTES Message Number - 消息编…

1. Docker的介绍和安装 (二)

5 Docker的原理 5.1 Namespace Namespace&#xff08;命名空间&#xff09;提供了一个独立的工作环境&#xff0c;Docker使用Namespace来隔离容器&#xff0c;使得每个容器都有自己独立的系统资源&#xff08;如进程ID、主机名、网络等&#xff09;。 PID Namespace&#xf…

SBTI科学碳目标认证是什么?SBTI科学碳目标的重要性

SBTI科学碳目标认证&#xff0c;作为企业在应对气候变化和追求可持续发展道路上的重要里程碑&#xff0c;其认证过程严谨而系统。以下是获得SBTI科学碳目标认证的详细步骤&#xff1a; 首先&#xff0c;企业需要在线注册并提交承诺书&#xff0c;郑重承诺在未来24个月内提交科学…

Linux网络-配置IP

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 本来IP配置应该放在Linux安装完成的就要配置的&#xff0c;但是由于那个时候对Linux不怎么熟悉&#xff0c;所以单独列了一个…

每日一题 LeetCode03 无重复字符的最长字串

1.题目描述 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的最长字串的长度。 2 思路 可以用两个指针, 滑动窗口的思想来做这道题,即定义两个指针.一个left和一个right 并且用一个set容器,一个length , 一个maxlength来记录, 让right往右走,并且用一个set容器来…