当前位置: 首页 > news >正文

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

😁博客主页😁:🚀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

相关文章:

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

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…...

go创建对象数组

在 Go 语言中,可以使用字面量的方式创建结构体对象数组。以下是一个示例代码,展示了如何使用字面量创建一个结构体对象数组: package mainimport "fmt"// 定义一个结构体 type Person struct {Name stringAge intAddress Address…...

Golang | Leetcode Golang题解之第278题第一个错误的版本

题目: 题解: func firstBadVersion(n int) int {return sort.Search(n, func(version int) bool { return isBadVersion(version) }) }...

自动化网络爬虫:如何它成为提升数据收集效率的终极武器?

摘要 本文深入探讨了自动化网络爬虫技术如何彻底改变数据收集领域的游戏规则,揭示其作为提升工作效率的终极工具的奥秘。通过分析其工作原理、优势及实际应用案例,我们向读者展示了如何利用这一强大工具加速业务决策过程,同时保持数据收集的…...

软件测试---测试需求分析

课程目标 什么是软件测试需求 软件测试需求的必要性 如何对软件测试需求进行分析(重点) 课程补充 灰度测试(基于功能):先发布部分功能,然后看用户的反馈,再去发布另外一部分的功能更新。 A/B测…...

Android11 framework 禁止三方应用通过广播开机自启动-独立方案

之前的文章Android11 framework 禁止三方应用开机自启动记录了我调试Android11应用自启动限制的全过程,但是之前的方案感觉还能再研究,所以有了这一篇文章。 这一篇文章主要探讨Android11上,以广播来进行自启动的应用的限制,极个别…...

Node:解决Error: error:0308010C:digital envelope routines::unsupported的解决方法

问题描述 在使用vuepress搭建博客的时候,运行项目发现报错了,检查了node的版本是18,之前用的是16或14的版本,现在报:Error: error:0308010C:digital envelope routines::unsupported错误。 查找了一些资料&#xff0…...

spring boot(学习笔记第十四课)

spring boot(学习笔记第十四课) Spring Security的密码加密,基于数据库认证 学习内容: Spring Security的密码加密基于数据库认证 1. Spring Security的密码加密 如果用户的密码保存在数据库中是以明文保存,对于公司的安全将是灾难性的&…...

Android 11 Unable to start/bind service

今天在Android11上发现了一个的问题,如果目标Service的进程没有启动,那么无论是bindService还是startService都没有办法拉起指定的Service。 网上查了很多资料如下: 1.目标Service 设置 android:exported"true" 2.目标Service需要声明自定义权…...

走难而正确的路并持之以恒

走难而正确的路并持之以恒 接近八月,台风频繁。气象台说台风“格美”今夜将至,往粤北走,而留在粤东的将是持续的高温。高温的广州,这几晚的天空惊喜不断,成片的火烧云,站在猎德大桥观望,丹红的凤…...

规范:Redis规范

在公司项目中,redis属于高频使用,在使用中,我们遇到了各种各样的redis问题,于是针对自身情况梳理了一个redis使用规范。 一、键名设计 1、key名设计 1. 禁止包含特殊字符(比如空格、换行、单双引号以及其他转义字符) 2. 建议以…...

比较 WordPress 、 Baklib 和 BetterDocs

对于希望管理其产品和服务的在线文档或知识库以支持其客户和员工的组织来说,市场上有太多的平台和工具。一些组织使用 WordPress 作为 Web 内容管理,并打算使用可用的插件。如果您是这样的组织之一,正在考虑使用广泛使用的 WordPress 插件之一…...

Redis 哨兵搭建

Redis哨兵(sentinel)搭建 7.2.5 文章目录 一、单节点哨兵1. 环境介绍2. 环境前准备工作3. 安装 Redis 7.2.54. redis 配置修改并且启动4.1 修改配置文件4.2 编写启动脚本 5. 开启主从5.1 开启5.2 主库实例查看主从信息 6. 创建sentinel的配置文件并启动6.1 创建配置文件6.2 启…...

HackTheBox--Knife

Knife 测试过程 1 信息收集 端口扫描 80端口测试 echo "10.129.63.56 knife.htb" | sudo tee -a /etc/hosts网站是纯静态的,无任何交互功能,检查网页源代码也未发现任何可利用的文件。 检查页面请求时,请求与响应内容&#xff0…...

Linux_实现TCP网络通信

目录 1、实现服务器的逻辑 1.1 socket 1.2 bind 1.3 listen 1.4 accept 1.5 read 1.6 write 1.7 服务器代码 2、实现客户端的逻辑 2.1 connect 2.3 客户端代码 3、实现服务器与客户端的通信 结语 前言: 在Linux下,实现传输层协议为TCP…...

正则表达式与文本三剑客之grep

目录 前言 一、grep命令 二、基础正则表达式常见元字符 2.1、特殊字符 2.2、定位符 2.3、非打印字符 三、元字符操作实例 3.1、查找特定字符 3.2、利用中括号“[]”来查找集合字符 3.3、查找行首“^”与行尾字符“$” 3.4、查找任意一个字符“.”与重复字符“*” 3.…...

微信小程序开发:项目程序代码构成

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…...

【云原生】Kubernetes微服务Istio:介绍、原理、应用及实战案例

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...

【Docker】Docker-consul容器服务自动发现与注册

目录 一.Consul概述 1.解决了什么问题 2.什么叫微服务或者注册与发现 3.consul的模式 4.相关命令 二.consul 部署 1.consul服务器部署 2.部署docker容器 3.Nginx负载均衡器 3.1.安装启动nginx 3.2.配置nginx负载均衡 3.3.创建配置consul complate模板文件 3.4.添加…...

Go 1.22 remote error: tls: handshake failure

Golang 1.22 remote error: tls: handshake failure 1.22之前运行下面代码是没有错误 package mainimport ("crypto/tls""fmt""net/http" )func main() {http.DefaultTransport.(*http.Transport).TLSClientConfig &tls.Config{InsecureS…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...