哈希与哈希表

哈希表的概念

哈希表又名散列表,官话一点讲就是:

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

 —— 摘自百度百科

那么通俗一点讲,哈希表就是一张映射表,通过哈希映射,将关键字映射到哈希表中,使得关键字与哈希值具有一一对应的关系。

图片出处: 算法数据结构基础——哈希表(Hash Table)-CSDN博客

这样我们就可以直接通过找到

哈希函数

哈希函数的一个关键就是通过哈希方法来得到一个映射值,理论上关键字与映射值一一对应。一般来说,哈希方法大致有如下这些:

  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为随机数函数(伪代码)。通常应用于关键字长度不等时采用此法
  6. 数学分析法
    设有n个d位数,每一位可能有r种不同的符号,这r种不同的符号在各位上出现的频率不一定相同,可能在某些位上分布比较均匀,每种符号出现的机会均等,在某些位上分布不均匀只有某几种符号经常出现。可根据散列表的大小,选择其中各种符号分布均匀的若干位作为散列地址。

其中,直接定址法、除留余数法是两种较为常用的哈希方法。而直接定址法有非常多的实现方式比如:各种字符串Hash函数 - clq - 博客园 (cnblogs.com),所以哈希表的大体思路很好理解,但具体实现上却大有讲究。

哈希冲突及其解决方案

不管是哪种哈希方法,随着数据量的增大,必然会造成哈希冲突。哈希冲突就是多个关键字映射的是同一个哈希值的情况。一般来说,解决哈希冲突通常有两种方式:闭散列和开散列。

闭散列 - 开放定址法

简单来说,如果当前哈希映射值对应的位置已经有数据了,就产生了哈希冲突。开放定址法的做法是,再找一个映射位置。常用的有线性探测和二次探测两种方式:

  • 线性探测法:$F(i) = 1, 2, 3, ..., m - 1$。

  • 二次探测法:$F(i) = 1^2, -1^2, 2^2, -2^2, ..., \pm n^2(n \le m / 2)$。

简单来说就是,线性探测在发生哈希冲突之后,线性地向后寻找,直到找到一个空位为止。二次探测是指,第一个在哈希值上加上一个1的平方,如果发生哈希冲突,第二次就减去一个1的平方,第三次加上2的平方,第四次……这样以此类推。那么查找时也是按照对应的探测方式进行查找的。

开散列 - 链地址法(开链法)

而开散列则相对更容易接受一些。开散列又称连地址法,是指的每个哈希表中存放的数据不再是一个单纯的数据,而是一个链表,所有映射值相同的关键字都被这个链表所链起来,就像下面这样:

图片出处: 算法数据结构基础——哈希表(Hash Table)-CSDN博客

注意事项与总结

  1. 哈希表的两个核心内容在于哈希函数与哈希冲突的解决。哈希函数大致有如下这几类:直接定址法、除留余数法、平方取中法、基数转换法、数字分析法、折叠法、随机数法、乘积法、点积法等。哈希冲突的解决常用的有开放地址法和链地址法。
  2. 在哈希表的具体实现中,因为扩容操作会改变哈希的映射关系,所以扩容时每一个元素都需要重新插入。
  3. 在具体实现时,可以通过负载因子(有效值与最大容量的比值)来控制扩容的时机。
  4. 哈希与哈希表的区别是,哈希是一种思想,哈希表是哈希这种思想的一种实现方式,其它的还有比如位图、布隆过滤器等也是哈希思想的一种体现。

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

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

相关文章

SpringBoot集成Redis

引入依赖 建议使用 Lettuce 连接驱动 <!--一&#xff1a;Jedis连接驱动缺点&#xff1a;Jedis基于TCP的阻塞性的连接方式1. 阻塞性IO2. 不能异步3. 线程不安全的Lettuce连接驱动优点&#xff1a;Lettuce基于Netty的多路复用的异步非阻塞的连接方式&#xff0c;1. 线程安全2…

公开Java框架开源到Maven中央仓库(避坑)

前言: gpg下载地址&#xff1a;http://www.gnupg.org/download 安装勾选 kleopatra 下载完成验证 gpg --version 当时为了开源Java框架&#xff0c;真的是绞尽脑汁&#xff0c;耗费很多精力查了很多资料&#xff0c;躺了很多坑&#xff0c;最终的结果无不是以发布失败而告终&am…

线程变量引发的session混乱问题

最近不是在救火&#xff0c;就是在救火的路上。 也没什么特别可写的&#xff0c;今天记录下最近遇到的一个问题&#xff0c;个人觉得挺有意思&#xff0c; 待有缘人阅读 言归正传&#xff0c;售后反馈&#xff1a; 营业查询中付款方式为第三方支付的几条银行缴费&#xff0c;创…

ai绘画Midjourney绘画提示词Prompt教程

一、Midjourney绘画工具 SparkAi【无需魔法使用】&#xff1a; SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧&#xff01;本系统使用NestjsVueTypescript框架技术&#xff0c;持续集成AI能力到…

成为AI产品经理——模型稳定性评估(PSI)

一、PSI作用 稳定性是指模型性能的稳定程度。 上线前需要进行模型的稳定性评估&#xff0c;是否达到上线标准。 上线后需要进行模型的稳定性的观测&#xff0c;判断模型是否需要迭代。 稳定度指标(population stability index ,PSI)。通过PSI指标&#xff0c;我们可以获得不…

chatgpt、百度、讯飞、阿里写一小段SQL对比

问题&#xff1a;有一张表pay&#xff0c;表中只有一个字段url&#xff0c;字段类型为text&#xff0c;没有其它字段。请写一段sql脚本&#xff0c;删除重复的url行记录&#xff0c;只保留一条记录。 通义千问的回答&#xff1a; DELETE FROM pay WHERE url IN (SELECT url F…

Windows使用Redis

Windows使用Redis 前言一、安装wsl2&#xff08;Windows Subsystem for Linux&#xff09;二、在wsl中下载并安装Redis一主二仆哨兵模式 前言 主要是记录一下&#xff0c;免得自己忘了。 一、安装wsl2&#xff08;Windows Subsystem for Linux&#xff09; Redis官网中说&…

GitHub上1.5K标星的QA和软件测试学习路线图

​最近在GitHub上发现一个项目&#xff0c;项目描述了作为QA工程师&#xff0c;进行软件测试技能提升时的&#xff0c;建议的软件测试学习顺序图​。 虽然2021年起就不再更新了&#xff0c;但是居然有1.5K的​星。 整个项目有两个部分​&#xff1a; ​1.QA和软件测试学习顺序…

嵌入式面试题

1. new和malloc 做嵌入式&#xff0c;对于内存是十分在意的&#xff0c;因为可用内存有限&#xff0c;所以嵌入式笔试面试题目&#xff0c;内存的题目高频。 1&#xff09;malloc和free是c/c语言的库函数&#xff0c;需要头文件支持stdlib.h&#xff1b;new和delete是C的关键…

craco + webpack 4 升 5

craco webpack 4 升 5 更新包版本尝试build升级其他依赖库使用process插件打印进度信息到底需要多少内存分析构建产出添加 splitChunk总结记录一些好文章&#xff1a; 我的项目使用 craco react 开发 我的 package.json {// ......"dependencies": {"ant-desi…

沐风老师3DMAX拼图随机生成器Puzzle建模工具使用教程

3DMAX拼图随机生成器Puzzle建模工具使用教程 3DMAX拼图随机生成器Puzzle&#xff0c;是一款用MAXScript脚本语言开发的3dsMax小工具&#xff0c;可以随机创建可编辑多边形3D拼图对象。可批量生成阵列。 【适用版本】 3dMax2015-2024&#xff08;不仅限于此范围&#xff09; 【…

[算法思考记录]力扣1094.拼车JavaScript

Problem: 1094. 拼车 相当于在一条路上开车&#xff0c;乘客在某个时间点上车&#xff0c;他们会影响在下车之前的路程的车载人数。 很明显这是差分的做法&#xff0c;只要把行车的路程抽象成一个差分数组&#xff0c;把上下车抽象成区间更改&#xff0c;一切都变得简单 Code…

前端大文件上传webuploader(react + umi)

使用WebUploader还可以批量上传文件、支持缩略图等等众多参数选项可设置&#xff0c;以及多个事件方法可调用&#xff0c;你可以随心所欲的定制你要的上传组件。 分片上传 1.什么是分片上传 分片上传&#xff0c;就是将所要上传的文件&#xff0c;按照一定的大小&#xff0c;将…

Langchain-Chatchat的安装过程

参考&#xff1a;LLMs之RAG&#xff1a;LangChain-Chatchat(一款中文友好的全流程本地知识库问答应用)的简介(支持 FastChat 接入的ChatGLM-2/LLaMA-2等多款主流LLMs多款embe_一个处女座的程序猿的博客-CSDN博客 1、安装过程中出现了 GPU驱动版本 是11.8 而 python -c "…

探索人工智能领域——每日20个名词详解【day8】

目录 前言 正文 总结 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高兴与大家相识&#xff0c;希望我的博客能对你有所帮助。 &#x1f4a1;本文由Filotimo__✍️原创&#xff0c;首发于CSDN&#x1f4da;。 &#x1f4e3;如需转载&#xff0c;请事先与我联系以…

学习使用三个命令实现在腾讯云服务器TencentOS Server 3.1或者CentOS 8上安装ffmpeg

学习使用三个命令实现在腾讯云服务器TencentOS Server 3.1或者CentOS 8上安装ffmpeg Error: Unable to find a match: ffmpeg添加RPMfusion仓库安装SDL安装ffmpeg执行命令测试 Error: Unable to find a match: ffmpeg 添加RPMfusion仓库 yum install https://download1.rpmfus…

Vue3动态表单

示例代码如下&#xff1a; // 引入需要的依赖包 import { ref, reactive } from vue; import { useForm } from /composables/useForm;// 定义表单数据模型 const formModel reactive({name: ,age: ,gender: , });// 使用自定义的useForm函数创建表单实例 const { register, …

[Java学习日记]多线程练习、线程池

目录 一.案例&#xff1a;五个人抢红包 二.案例&#xff1a;两个抽奖池抽奖 三.案例&#xff1a;两个抽奖池抽奖&#xff1a;获取线程运行的结果 四.线程池&#xff1a;用来存放线程&#xff0c;避免多次重复创建线程 五.自定义线程池 六.最大并行数与线程池大小 一.案例&…

Python核心编程之认识python中的数字

目录 一、数字类型 如何创建数值对象并用其赋值 (数字对象) 如何更新数字对象

PTA 7-237 特殊排序

输入一个整数n和n个各不相等的非负整数&#xff0c;将这些整数从小到大进行排序&#xff0c;要求奇数在前&#xff0c;偶数在后。 输入格式: 首先输入一个正整数T&#xff0c;表示测试数据的组数&#xff0c;然后是T组测试数据。每组测试先输入一个整数n(1<n<100)&…