哈希表散列表

文章目录

    • 哈希表概述
    • 哈希表详解
    • 什么是 Hash 冲突
    • 哈希冲突的常见解决方法
    • HashMap 如何解决 Hash 冲突的

哈希表概述

哈希表(Hash Table)是一种数据结构,用于实现键值对的存储和快速检索。它通过将键映射到数组的索引位置来实现高效的查找操作。哈希表通常由一个数组和一个哈希函数组成,哈希函数用于将键映射到数组索引位置。
下面是哈希表的一些重要特点和详细解释:

  1. 哈希函数:哈希函数是哈希表的核心,它接受一个键作为输入,并输出该键对应的哈希值。好的哈希函数应该能够将键均匀地映射到数组的不同位置,减少哈希冲突的发生。
  2. 数组:哈希表的底层数据结构通常是一个数组,每个数组元素称为“桶”或“槽”,用于存储键值对。
  3. 哈希冲突:当不同的键经过哈希函数映射到相同的数组索引位置时,就会发生哈希冲突。解决哈希冲突是设计哈希表时需要考虑的重要问题。
  4. 解决哈希冲突的方法:常见的方法包括链地址法(Chaining)和开放定址法(Open Addressing)。链地址法将哈希表中的每个位置设置为一个链表或其他数据结构,用于存储冲突的元素;开放定址法在发生哈希冲突时,通过一定的规则寻找下一个可用的位置来存储冲突的元素。
  5. 时间复杂度:哈希表具有非常快的平均时间复杂度,对于插入、删除和搜索操作,平均情况下可以达到 O(1) 的时间复杂度。
  6. 应用:哈希表被广泛应用于编程中,如实现关联数组、缓存、数据库索引等。

总之,哈希表是一种非常重要且高效的数据结构,对于存储大量键值对并需要快速检索的场景下具有很大的优势。设计合适的哈希函数和解决哈希冲突的方法是哈希表设计的关键。

哈希表详解

散列表(Hash table,也叫哈希表)是一种查找算法,与链表、树等算法不同的是,散列表算法
在查找时不需要进行一系列和关键字(关键字是数据元素中某个数据项的值,用以标识一个数据元素)的比较操作。
散列表算法希望能尽量做到不经过任何比较,通过一次存取就能得到所查找的数据元素,因而必须要在数据元素的存储位置和它的关键字(可用 key 表示)之间建立一个确定的对应关系,使每个关键字和散列表中一个唯一的存储位置相对应。因此在查找时,只要根据这个对应关系找到给定关键字在散列表中的位置即可。这种对应关系被称为散列函数(可用 h(key)表示)。
用的构造散列函数的方法有:
(1)直接定址法: 取关键字或关键字的某个线性函数值为散列地址。
即:h(key) = key 或 h(key) = a * key + b,其中 a 和 b 为常数。
(2)数字分析法
(3)平方取值法: 取关键字平方后的中间几位为散列地址。
(4)折叠法:将关键字分割成位数相同的几部分,然后取这几部分的叠加和作为散列地址。
(5)除留余数法:取关键字被某个不大于散列表表长 m 的数 p 除后所得的余数为散列地址,即:h(key) = key MOD p p ≤ m
(6)随机数法:选择一个随机函数,取关键字的随机函数值为它的散列地址,
即:h(key) = random(key)
哈希表和散列表其实是同一个数据结构的不同称呼。哈希表(Hash Table)是一种基于哈希函数实现的数据结构,用于快速存储和检索键值对。而散列表(Hash Table)则是哈希表的另一种称呼,通常也指使用哈希函数将键映射到存储桶的数据结构。因此,哈希表和散列表在计算机科学中通常是可以互换使用的术语。
哈希表是基于数组的一种存储方式.它主要由哈希函数和数组构成。当要存储一个数据的时候,首先用一个函数计算数据的地址,然后再将数据存进指定地址位置的数组里面。这个函数就是哈希函数,而这个数组就是哈希表。
哈希冲突是指哈希函数算出来的地址被别的元素占用了,也就是,这个位置有人了。好的哈希函数会尽量避免哈希冲突。

什么是 Hash 冲突

Key 值不同 但是 hashcode 值相等
== 对于基本类型来说是值比较,对于引用类型来说是比较的是引用;而 equals 默认情况下是引用比较,只是很多类重新了 equals 方法,比如 String、Integer 等把它变成了值比较,所以一般情况下 equals 比较的是值是否相等。
equals 和== 最大的区别是一个是方法,一个是运算符。
==:如果比较的对象是基本数据类型,则比较的是数值是否相等;如果比较的是引用数据类型,则比较的是对象的地址值是否相等。
equals():用来比较方法两个对象的内容是否相等。
注意:equals 方法不能用于基本数据类型的变量,如果没有对 equals 方法进行重写,则比较的是引用类型的变量所指向的对象的地址。

就是不同数据hash算法计算出来的结果可能是相同的,那么不同的数据就会放在同一个下标位置。
哈希冲突是指在使用哈希函数将不同的输入映射到相同的哈希值时发生的现象。哈希函数通常用于将大量的数据映射到有限的地址空间,比如将键映射到哈希表的索引位置。由于输入的数量远远大于哈希表的大小,所以不同的输入可能会被映射到相同的哈希表位置。

当两个不同的键经过哈希函数后得到相同的哈希值时,就会产生哈希冲突。这种情况下,如果没有合适的处理方法,就会导致数据的覆盖或者查找数据时出现错误的结果。

哈希冲突的常见解决方法

  1. 链地址法(Chaining):将哈希表中的每个位置设置为一个链表或者其他数据结构,当发生哈希冲突时,将冲突的元素存储在同一位置的链表中。这是一种非常常见的方法,简单理解就是把存在hash冲突的key,以单向链表的方式来存储。
    将所有关键字为同义词的结点链接在同一个单链表中。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数 组T[0…m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。T中各分量的初值均应为空指针。
  2. 开放定址法(Open Addressing):在发生哈希冲突时,通过一定的规则寻找下一个可用的位置来存储冲突的元素,如线性探测、二次探测等。包含线性探测、平方探测等等,就是从发生冲突的那个位置开始,按照一定的次序从hash表中找到一个空闲的位置,然后把发生冲突的元素存入到这个空闲位置中。ThreadLocal就用到了线性探测法来解决hash冲突的。
    当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。沿此序列逐个单元地查找,直到找到给定的关键字,或者碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元)。查找时探查到开放的 地址则表明表中无待查的关键字,即查找失败。
    3.建立公共溢出区, 就是把hash表分为基本表和溢出表两个部分,凡事存在冲突的元素,一律放入到溢出表中
    4.再hash法,就是当通过某个hash函数计算的key存在冲突时,再用另外一个hash函数对这个key做hash,一直运算直到不再产生冲突。这种方式会增加计算时间,性能影响较大。
    选择合适的解决哈希冲突的方法对于设计高效的哈希表至关重要,不同的方法适合不同的应用场景和需求。

HashMap 如何解决 Hash 冲突的

通过引入单向链表来解决 Hash 冲突。当出现 Hash 冲突时,比较新老 key 值是否相等,
如果相等,新值覆盖旧值。如果不相等,新值会存入新的 Node 结点,指向老节点,形成链式结构,即链表。
当 Hash 冲突发生频繁的时候,会导致链表长度过长,以致检索效率低,所以 JDK1.8 之后引入了红黑树,当链表长度大于 8 时,链表会转换成红黑书,以此提高查询性能。
因为发生 hash 冲突的时候,会在链表上新增节点,但是链表过长的话会影响检索效率,引入红黑树可以提高插入和查询的效率。

HashMap就是通过链式寻址法来解决的,但是链式地址有个问题:当链表过长的时候,会影响查询性能,所以在HashMap里,当链表长度大于8的时候,会转为红黑树,提升查询性能。但是树在添加数据的时候也会有树的分裂合并,所以在树节点小于6的时候,又会转为链表这个 是我对HashMap哈希冲突的理解
首先,我们得知道下HashMap的存储方式,HashMap是k-v的数据结构, 底层是一个entry数组的数据结构, 并且根据key计算出一个hash值,取模entry数组长度-1,得到一个下标位置来存储数据。

简单总结一下 HashMap 是使用了哪些方法来有效解决哈希冲突的

  1. 使用链地址法(使用散列表)来链接拥有相同 hash 值的数据;
  2. 使用 2 次扰动函数(hash 函数)来降低哈希冲突的概率,使得数据分布更平均;
  3. 引入红黑树进一步降低遍历的时间复杂度,使得遍历更快

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

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

相关文章

ERC-7401:嵌套 NFT 标准的全新篇章

在数字资产和区块链技术迅速发展的今天,非同质化代币(NFT)已经成为了一种重要的资产形式,广泛应用于艺术、游戏、收藏品等多个领域。随着市场需求的多样化,传统的 NFT 标准如 ERC-721 和 ERC-1155 已经不能完全满足用户…

Keras深度学习框架实战(2):估计模型训练所需的样本量

1、模型训练样本量评估概述 1.1 样本量评估的意义 预估模型需要的样本量对于机器学习项目的成功至关重要,以下是几个主要原因: 防止过拟合与欠拟合: 过拟合:当模型在训练数据上表现极好,但在未见过的测试数据上表现糟…

5步3分钟0基础搭建,轻松搭建《雾锁王国》私人服务器

继《幻兽帕鲁》游戏爆火之后,与它同类型的《雾锁王国》也是强力刷屏,不分伯仲,在 Steam 上的评分一直稳定在“特别好评”,让小伙伴们很“上头”。就在两者游戏玩家反响爆火的同时,官方服务器人数爆满,卡顿频…

关闭数据库默认配置配置自定义数据库

在实际项目中使用了通过配置中心配了数据库,而我们改了application.yml并没有起作用,我们可以手动创建一个配置类来定义自定义的数据源,并在Spring容器中注册它 PrimaryBeanpublic DataSource customDataSource() {return DataSourceBuilder.…

C语言Linux进度条模拟

在Linux字符界面中,使用yum、apt下载东西时会有一个图形化的进度条,可以告诉我们任务的执行进度。 我们也可以通过C语言实现一个类似的进度条,并且可以做得更加美观。以后我们自己写的程序需要显示进度时就可以去调用我们自己实现的进度条。 …

【typescript/flatbuffer】在websocket中使用flatbuffer

目录 说在前面场景fbs服务器代码前端typescript代码问题 说在前面 操作系统:Windows11node版本:v18.19.0typescript flatbuffer版本:24.3.25 场景 服务器(本文为golanggin)与前端通信时使用flatbuffer进行序列化与反序列化通信协议为websock…

从0开始制作微信小程序

目录 前言 正文 需要事先准备的 需要事先掌握的 什么是uniapp 平台应用的分类方式 什么是TypeScript 创建项目 项目文件作用 源码地址 尾声 🔭 Hi,I’m Pleasure1234🌱 I’m currently learning Vue.js,SpringBoot,Computer Security and so on.&#x1…

有点混乱的普里姆算法求最小生成树

Graph.h #pragma once //邻接矩阵的创建 #include<stdio.h> #include <stdlib.h> #include<assert.h> #include<string.h> #include<stdbool.h> #include<limits.h> #define MAX 100 #define INF INT_MAX typedef struct Graph {int n;…

一周学会Django5 Python Web开发 - Django5内置Admin系统二次开发

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计56条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

System-Verilog 实现DE2-115倒车雷达模拟

System-Verilog 实现DE2-115倒车雷达模拟 引言&#xff1a; 随着科技的不断进步&#xff0c;汽车安全技术也日益成为人们关注的焦点。在众多汽车安全辅助系统中&#xff0c;倒车雷达以其实用性和高效性脱颖而出&#xff0c;成为现代汽车不可或缺的一部分。倒车雷达系统利用超声…

Laya:【音效BUG】在游戏失焦后再次返回游戏导致音效播放异常的问题与解决方案

PS&#xff1a;ios 上不支持 ogg格式音频, 全部使用MP3.或者 在只ios不使用ogg。 复现方法&#xff1a; 1.用Laya.SoundManager.playMusic()随意播放一个音效文件 2.在项目内开启Laya.SoundManager.autoStopMusic true; //通过窗口失焦静音键让音频自动跟随设备静音 3.使游戏失…

如何使用 Nginx 创建临时和永久重定向

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 简介 HTTP 重定向 是将一个域名或地址指向另一个的方法。有几种不同类型的重定向,每种对客户端浏览器意味着不同的事情。最常见的两种类型是临时重定向和永久重定向。…

idea中导入代码文件无法修改,显示File is read-only,怎么办?难办?那就别办了------看下面

File is read-only 文件属性只读&#xff0c;不可修改。。。。。 第一次遇到这种问题&#xff0c;去网上搜了一堆方法&#xff0c;都试了&#xff0c;没用&#xff0c;最后居然还建议我重装idea&#xff0c;我还差点信了&#xff0c;经9X9难后&#xff0c;取得真经。 问题解决…

STM32 | 方式1:手机发送指令,开发板向手机发送温湿度;方式2:手机发送指令,开发板定时向手机发送温湿度。

​01、知识回顾 STM32 | HC-SR04 超声波测距模块 | DHT11数字温湿度传感器(第七天)STM32 | 数字温湿度传感器DHT11STM32 | HC-SR04 超声波测距模块STM32 | DHT11数字温湿度传感器实战STM32 | 超声波实战02、作业1 1、通过手机的两方式获取温湿度. 方式1:手机发达指令,开发…

Spring Boot项目中,如何在yml配置文件中读取maven pom.xml文件中的properties标签下的属性值

一、前言 在最近的项目开发过程中&#xff0c;有一个需求&#xff0c;需要在Spring Boot项目的yml配置文件中读取到mave的 pom.xml文件中的properties标签下的属性值&#xff0c;这个要怎么实现呢&#xff1f; 二、技术实践 pom.xml文件中增加测试属性 <properties><…

汇舟问卷:兼职做国外问卷三小时挣200

在繁忙的都市生活中&#xff0c;许多人为了生计而日夜奔波。对于大多数人来说&#xff0c;白天的工作已经足够充实&#xff0c;但依然有很多人选择在下班时间&#xff0c;多做些什么&#xff0c;为自己带来一份额外​的收入。 目前下班做的兼职工作不是跑滴滴&#xff0c;就是…

7_2、C++程序设计进阶:数据共享

数据与函数 数据与函数局部变量全局变量类的数据成员 类的静态成员静态数据成员静态函数成员 友元友元函数友元类 函数之间实现数据共享有以下几种方式&#xff1a;局部变量、全局变量、类的数据成员、类的静态成员和友元。 如何共享局部变量呢&#xff1f; 在主调函数和被调…

YOLOV10:参数越少,速度越快,性能更高的新一代目标检测框架

摘要 在过去的几年中&#xff0c;YOLOs由于在计算成本和检测性能之间实现了有效的平衡&#xff0c;已经成为实时目标检测领域的主导范式。研究人员已经探索了YOLOs的架构设计、优化目标、数据增强策略等&#xff0c;取得了显著的进展。然而&#xff0c;对非极大值抑制&#xf…

Redis学习笔记【基础篇】

SQL vs NOSQL SQL&#xff08;Structured Query Language&#xff09;和NoSQL&#xff08;Not Only SQL&#xff09;是两种不同的数据库处理方式&#xff0c;它们在多个维度上有所差异&#xff0c;主要区别包括&#xff1a; 数据结构: SQL&#xff08;关系型数据库&#xff09;…

acm模式练习

1.A B问题 #include<iostream> using namespace std; int main() {int a, b;while (cin >> a >> b) cout << a b << endl; } while循环什么时候停止&#xff1f; 2.A B问题|| #include<iostream> using namespace std; int main() {…