数据结构-哈希表(一)哈希函数、哈希表介绍、优缺点

哈希表

哈希函数

在这里插入图片描述

哈希表使用了哈希函数来完成key到地址的快速映射,所以在了解哈希表之前,需要先明白哈希函数的概念和特点。

哈希函数的定义

  • 哈希函数
    • 哈希函数是一种将任意长度输入的数据,转换成固定长度输出算法
    • 哈希函数H可以表示为y=H(x)
      • H指代哈希函数
      • x输入数据,可以是任意长度
      • y输出的哈希值,具有固定长度
  • Hashcode
    • 这部分被固定长度输出的数据被称为Hashcode哈希值散列值

哈希函数的特点

  • 确定性

    • 不管执行多少次,通过某个key所得到的内存数组索引位置(即哈希值)是不变
  • 固定长度输出

    • 哈希函数的核心任务是将无限映射到有限,即不管输入值数据大小是1kb还是1G,数据长度是1位还是1000位,它的通过哈希函数产生的哈希值长度都是固定的,具体输出长度由算法决定
      • SHA-256算法输出永远是256位(32字节)
      • MD5算法输出永远是128位(16字节)
        在这里插入图片描述
  • 单向性

    • 输入值可以单向通过哈希函数获得哈希值,但是通过哈希值不可以反向获取输入值原数据。哈希函数是一个“单向门”或“单向函数”。从 x 计算 H(x) 很容易,但从H(x)反推出 x 极其困难。
      • 这一点在密码存储上至关重要,系统可以存储用户密码的哈希值,即时数据库泄漏,攻击者也无法轻易从哈希值还原出用户的原始密码
  • 高效性

    • 计算哈希值的过程快速且高效,即时是处理大量数据也能快速完成
    • 哈希函数算法是由简单的位运算(与、或、非、异或、移位、旋转)构成,这些操作在现代计算机上执行是非常快速的
  • 需要处理哈希冲突/哈希碰撞

    • 哈希函数因为是无限映射到有限,输入空间是无限的,所以有可能出现两个不同的输入,对应了同一个哈希值,即出现了碰撞
    • 哈希函数设计目标需要尽可能的避免出现碰撞

引申问题1:哈希函数和加密函数的区别

  • 哈希函数和加密函数最大的区别是
    • 哈希函数是单向的,不可逆,即通过哈希值很困难找到原始值
    • 加密函数式双向的,可逆(需密钥解密),通过密文也可以找到原文
维度哈希函数 (Hash)加密函数 (Encryption)
可逆性单向,不可逆双向,可逆(需密钥解密)
密钥无密钥有密钥(对称或公私钥)
输出长度固定(如 256 位)可变(通常 ≥ 明文长度)
速度目标尽量快,便于校验对称快、非对称慢,但都比哈希慢
碰撞必须抗碰撞(难以找到两输入同输出)无碰撞概念(一对一映射)
典型应用密码摘要、数据完整性、数字签名机密传输、磁盘加密、HTTPS
示例算法SHA-256, BLAKE3, MD5AES, ChaCha20(对称);RSA, ECC(非对称)

引申问题2:MD5算法和SHA256算法是哈希函数还是加密函数

  • MD5算法和SHA256算法都是哈希算法,不算加密算法
    • 两者都是任意长度的输入,压缩成固定长度摘要(SHA256为256bit,MD5为128bit)
    • 两者都不设秘钥,不可逆,不具备加密/界面功能
    • 常见用途
      • 校验文件完整性
      • 数字签名前置压缩
      • 密码存储(配合盐值和KDF)

引申问题3:位运算为什么快

  • 位运算是直接在CPU寄存器上用最简硬件逻辑完成的
    • AND/OR/XOR/NOT/SHIFT 都只需少量晶体管组成的组合逻辑门(与门、或门、异或门、移位器)
  • 零内存访问零复杂算法单周期延迟,是所有运算中成本最低

哈希表的定义

在这里插入图片描述

定义

  • 哈希表是一种动态数据结构,以key-value键值对存储数据
  • 核心思想是使用哈希函数key转换为数组下标索引保存后,下次再次查询时,使用仍然通过哈希函数将key转化为数组下标,快速定位到数据的位置

目的

  • 实现快速数据存储检索
  • 注意,此处的快速检索指的是通过key来查询value是快速的;如果仅仅只是查找某个value,数据检索效率并不高

核心公式

  • index = hash(key) mod capacity

组成部分

  • 哈希函数

    • 将key转换为数组索引的算法
  • 数组

    • 用于存储键值对数据的数组
  • 哈希冲突/碰撞解决方法

    • 因为哈希函数式无限(输入)转化为有限(输出),一定存在不同的输入产生相同的输出,即碰撞(或称为冲突)
    • 冲突/碰撞解决方法,指的是当碰撞发生时,不同key被映射到同一个数组下标索引时,如何处理,一般使用以下方法
      • 链表法
      • 开放寻址法

哈希表的优点

  • 操作高效

    • 增、删、查操作的时间复杂度为O(1),非常高效
  • 实现简单

    • 大多数编程语言中都有内置支持(Java的Hashmap;Python的dict)
  • 灵活性强

    • 可以存储各种类型的键值对

哈希表的缺点

  • 哈希冲突处理

    • 哈希冲突处理不当,会影响性能
  • 空间浪费

    • 为了避免哈希冲突,一般都会预留较大内存空间
  • 不支持有序遍历

    • 哈希表中的元素是无序的(因为保存时是通过hash函数计算出应该放在哪个数组下标,导致整体是随机的)
  • 设计复杂

    • 需精心设计哈希与冲突策略、负载因子、并发、缩容等工程细节,难度较高

引申问题4:哈希表为什么操作这么高效

  • 哈希表操作时可以直接定位数据存储位置(前提通过key来操作)

    • 哈希表的核心是哈希函数,哈希函数可以将key直接转换为数据在数组中的下标,比如get(key)等同于直接查array[5],时间复杂度是常数时间 O(1)
  • 数据结构支持随机访问

    • 因为是直接查下标不需要遍历数据
  • 哈希冲突处理优化

    • 对于可能存在的哈希冲突,哈希表会通过链表法开放寻址法来优化防止出现哈希冲突,从而减少哈希冲突对性能的影响

哈希表的应用场景

  • 快速查找

    • 通过索引key快速定位内容
    • 统计字符或单次出现的频率
      • 计算方式:对于每个字符,如果它已经在哈希表(这一步可以使用哈希函数通过key快速索引)中,将对应的值加 1。
      • 如果它不在哈希表中,将其加入哈希表,值设为 1。
    • 快速判断一个元素是否在数组中
  • 数据库索引

    • 数据库中的哈希索引(比如MySQL的Memory引擎)
  • 缓存系统

    • LRU 缓存(Least Recently Used Cache)常用哈希表 + 双向链表实现

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

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

相关文章

Shader开发(一)什么是渲染

前言在现代游戏开发和计算机图形学领域,渲染技术是连接虚拟世界与视觉呈现的关键桥梁。无论你是刚接触图形编程的新手,还是希望深入理解渲染原理的开发者,掌握渲染的核心概念都是必不可少的第一步。什么是渲染?渲染(Re…

策略模式+工厂模式(案例实践易懂版)

最近,可以说这2025年度,自己更文的次数都大大减少,主要最近大环境不景气,自己职业也受到波及,学习的东西也是因为AI而变得更多, 没办法,你不学,总有人会学,关于AI的我也准备出个专辑,相信绝对帮助到大家 额,好像说多了,言归正传,我们看一下今天的主题:策略模式工厂模式 本文主要…

【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - snowNLP库实现中文情感分析

大家好,我是java1234_小锋老师,最近写了一套【NLP舆情分析】基于python微博舆情分析可视化系统(flaskpandasecharts)视频教程,持续更新中,计划月底更新完,感谢支持。今天讲解snowNLP库实现中文情感分析 视频在线地址&…

大根堆,小根堆,双指针

码蹄集OJ-大约 #include<bits/stdc.h> using namespace std; priority_queue<int>max2,maxDel; priority_queue<int,vector<int>,std::greater<int>>min2,minDel; const int N1e51; int n,result0,a[N]; int main( ) {cin>>n;for(int i1…

RS485和Modbus

UART协议中&#xff0c;空闲状态为高电平&#xff0c;也就是1,R25和R27&#xff0c;485收发器特性MAX485 (美信)SSP485 (国产替代)AZRS3080 (安格)供电电压5V5V3.3V ~ 5.5V静态电流300μA (接收模式)120μA (接收模式)150μA (接收模式)传输速率2.5Mbps10Mbps20Mbps总线负载能力…

【Android】交叉编译faiss库 | 问题解决

目录 一 解决 FAISS 交叉编译到 Android 时的 BLAS/MKL 依赖问题 二 交叉编译faiss ■禁用 BLAS并交叉编译faiss ■使用 OpenBLAS 的 Android 移植版本并交叉编译faiss 三 报错处理 ■报错 ■SWIG 一 解决 FAISS 交叉编译到 Android 时的 BLAS/MKL 依赖问题

《使用 IDEA 部署 Docker 应用指南》

使用 IDEA 部署 Docker 应用的详细步骤 一、创建 Dockerfile 配置文件 在项目根目录下创建Dockerfile文件&#xff0c;配置内容如下&#xff1a; # 使用官方的OpenJDK镜像作为基础镜像 FROM openjdk:17-jdk-slim# 设置维护者信息(可选) LABEL maintainer"三木豪"# 设…

【Docker#3】Window 和 Linux 上 docker安装 相关知识

前置了解&#xff1a; X86 高并发&#xff1a;基于 x86 架构的处理器&#xff0c;在高负载下处理大量并发请求的能力。ARM &#xff1a;使用 ARM 架构处理器的移动设备&#xff0c;具有低功耗和高性能的特点。 操作系统&#xff1a; CentOS&#xff1a;基于 Red Hat Enterprise…

一次 POI 版本升级踩坑记录

前言 结论先行。 开发过程中由于可能涉及到二次开发&#xff0c;若原系统开发时间久远&#xff0c;没有达成一致规范设计&#xff0c;导致风格各异&#xff0c;确实满足当时开发场景&#xff0c;但增大了后续的更新的难度&#xff0c;容易出现俄罗斯套娃现象&#xff0c;新的更…

硬件设计学习DAY13——电源缓冲电路设计全解

每日更新教程&#xff0c;评论区答疑解惑&#xff0c;小白也能变大神&#xff01;" 目录 一.缓冲电路介绍 1.1缓冲电路的作用 1.2寄生参数的来源 1.3缓冲电路的类型 1.4常见缓冲电路设计 1.5设计原则 二.吸收与缓冲 2.1吸收与缓冲的核心作用 2.2电压尖峰与吸收措…

鸿蒙搜狐新闻如何在Native调用ArkTS方法

01前言鸿蒙作为一款新兴的智能操作系统&#xff0c;现在适配鸿蒙系统的应用越来越多&#xff0c;同时会面临三端兼容问题&#xff0c;如同一产品功能&#xff0c;需要维护iOS、Android、鸿蒙三端代码。拿文件上传、下载功能场景举例&#xff0c;同时要适配iOS、Android、鸿蒙三…

Java行为型模式---中介者模式

中介者模式基础概念中介者模式&#xff08;Mediator Pattern&#xff09;是一种行为型设计模式&#xff0c;其核心思想是通过一个中介对象来封装一系列对象之间的交互&#xff0c;使各对象不需要显式地相互引用&#xff0c;从而降低耦合度&#xff0c;并可以独立地改变它们之间…

Python爬虫实战:研究Korean库相关技术

一、引言 1.1 研究背景与意义 随着韩流文化在全球的传播,韩语网页内容急剧增加。韩国在科技、娱乐等领域的信息具有重要研究价值。然而,韩语独特的黏着语特性(如助词体系、词尾变化)给信息处理带来挑战。传统爬虫缺乏对韩语语言特点的针对性处理,本研究旨在开发一套完整…

表单校验--数组各项独立校验

写需求时遇到一个这样的问题&#xff0c;就是校样项是多个的&#xff0c;但是其字段名称相同这时我们可以这样校验&#xff0c;注意字段之间的关联性<div v-for"(item,index) in formData.hospitalDoctorList" :key"item.key || index"><el-form-…

基于SpringBoot和leaflet-timeline-slider的历史叙事GIS展示-以哪吒2的海外国家上映安排为例

目录 前言 一、哪吒2的海外之路 1、海外征战历程 2、上映国家空间查询 二、后端接口的实现 1、模型层的实现 2、上映时间与国家 3、控制层的实现 三、基于leaflet-timeline-slider的前端实现 1、时间轴控件的引入及定义 2、时间轴绑定事件 3、成果展示 四、总结 前言…

tar 解压:Cannot change ownership to uid 1000, gid 1000: Operation not permitted

tar 解压 tar.gz 压缩包报错&#xff1a; # tar xzf $INPUT_FOLDER/archive.tar.gz -C /mnt/test-nas/[..] tar: xx.jpg: Cannot change ownership to uid 1000, gid 1000: Operation not permitted原因是用普通用户执行的解压缩脚本&#xff0c;用root用户执行tar解压缩&…

腾讯客户端开发面试真题分析

以下是针对腾讯客户端开发工程师面试问题的分类与高频问题分析&#xff08;基于​​105道问题&#xff0c;总出现次数118次​​&#xff09;。按技术领域整合为​​7大类别​​&#xff0c;按占比排序并精选高频问题标注优先级&#xff08;1-5&#x1f31f;&#xff09;&#x…

线上问题排查之【CPU飙高100%】

目录 案例 发现问题 排查问题 步骤一 步骤二 步骤三 案例 import java.util.concurrent.TimeUnit;/*** 简单写一个CPU飙高的案例*/ public class CpuLoadUp {// 这里定义了一个标识private volatile static int flag 0;public static void main(String[] args) {// 执行…

c语言 进阶 动态内存管理

动态内存管理1. 为什么存在动态内存分配2. 动态内存函数的介绍​2.1 malloc 和 freemalloc 函数free 函数2.2内存泄漏2.3 calloc2.4 realloc3. 常见的动态内存错误3.1 对NULL指针的解引用操作3.2 对动态开辟空间的越界访问3.3 对非动态开辟内存使用free释放3.4 使用free释放一块…

Redis的五大基本数据类型

一、Redis基本知识与Redis键&#xff08;key&#xff09;常用操作命令。redis的默认端口6379。mysql默认端口号3306。 默认16个数据库&#xff0c;类似数组的下标从0开始&#xff0c;初始默认使用0号库。可以使用select index来切换数据库&#xff0c;如&#xff1a;select 1&a…