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

数据结构---哈希表

基本概念

哈希函数(Hash Function)是一种将输入的数据(通常是任意大小的)映射到固定大小的输出(通常是一个固定长度的值)的函数。这个输出值通常称为“哈希值”(Hash Value)或“哈希码”(Hash Code)。

  • 基本特点
    • 确定性:同样的输入必须产生相同的输出。
    • 快速计算:哈希函数应该能够快速计算出来,特别是在处理大量数据时。
    • 输出固定大小:无论输入数据的大小如何,哈希函数的输出应该是固定长度的。
    • 均匀分布:哈希值应该尽量均匀地分布在输出空间中,以减少哈希冲突。
    • 哈希冲突(Hash Collision)是指不同的输入数据经过哈希函数处理后,映射到相同的哈希值或相同的哈希槽(桶)中。由于哈希表的槽位是有限的,而输入的可能性是无限的,因此哈希冲突是不可避免的。为了有效地管理哈希冲突,我们需要使用冲突解决策略。

选择冲突解决策略的考虑因素:

  • 负载因子:负载因子是指哈希表中元素个数与表的大小之比。如果负载因子过高,冲突会增多,性能也会下降。链式法在负载因子较高时性能依然较好,而开放地址法则可能出现性能瓶颈。
  • 存储需求:链式法需要额外的空间来存储链表或其他数据结构,而开放地址法则不需要额外的空间,但可能会在高负载因子时导致查找效率下降。
  • 查找和插入频率:如果哈希表中的查找操作多于插入操作,使用链式法可能更合适,因为在链式法中查找冲突的元素比较简单。对于插入和查找都频繁的场景,开放地址法或渐进式哈希可能表现得更好。

哈希冲突解决方法:

链式法(Chaining)

  • 在这种方法中,每个哈希桶不仅仅存储一个元素,而是存储一个元素链表(或其他数据结构,如链表、二叉树等)。当多个元素哈希到同一个桶时,它们就以链表的形式存储在该桶中。
  • 优点
    • 实现简单。
    • 不需要额外的空间重新哈希(如果槽位已满,只需动态扩展链表即可)。
    • 哈希表大小可以灵活扩展,不需要预先确定哈希表的大小。
  • 缺点
    • 在极端情况下(所有元素都哈希到同一个桶),查找的时间复杂度可能退化为 O(n)。
    • 链表的管理和扩展可能需要额外的空间开销。

开放地址法(Open Addressing)

在开放地址法中,所有元素都存储在哈希表的主数组中,而不使用额外的数据结构(如链表)。当发生冲突时,形成某个探测序列;按此序列逐个探测散列表中的其他地址,直到给定的关键字或一个空地址(开放的地址)为止,将发生冲突的记录放到该地址中。

散列地址的计算公式:Hi(key)=(H(key)+di) MOD m,i=1,2,…,k(k<=m-1)

  • H(key):哈希函数
  • m:散列表长度
  • di:第i次探测时的增量序列;
  • Hi(key):经过i次探测后得到的散列地址。
  • 常见的开放地址法有:

1.线性探测(Linear Probing)

将散列表T[0,…m-1]看成循环向量。当发生冲突时,从初次发生冲突的位置依次向后探测其他的地址。
增量序列:di=0,1,2,3,…m-1
设初次发生冲突的地址是h,则依次探测T[h+1],T[h+2]…,直到T[m-1]时又循环到表头,再次探测T[0],T[1]…,直到T[h-1]
探测终止的情况
1.表中对应位置,已经存在该元素
2.直到循环完成,仍为探测到空地址,散列表满。
- 优点:只要散列表未满,总能快速简单的找到一个不冲突的散列地址。
- 缺点:容易形成聚集(clustering),每个产生冲突的记录被散列到离冲突最近的空地址上,从而又增加了更多的冲突机会。

2.二次探测(Quadratic Probing)

增量序列:d= ±1^2±2^2±3^2±n^2 等。(具体增量序列根据题目要求来)
- 优点:探测序列跳跃式的散列到整个表中,比线性探测减少了聚集问题。
- 缺点:不能保证探测到散列表的所有地址。

3.伪随机探测法

增量序列使用一个伪随机函数来产生一个落在闭区间[1,m-1]的随机序列。

双重哈希(Double Hashing)

使用第二个哈希函数来计算冲突元素的探测间隔。具体来说,若一个元素哈希到的位置已被占用,则使用另一个哈希函数来决定下一个探测位置。
优点:冲突的概率较小,避免了聚集问题。
缺点:需要额外的哈希函数,且实现较为复杂。
再哈希法(Rehashing)

  • 再哈希法是解决哈希冲突的一种方法,它涉及使用多个哈希函数。当使用第一个哈希函数产生冲突时,再哈希法会尝试第二个哈希函数,如果仍然冲突,就继续使用第三个,以此类推,直到找到一个没有冲突的哈希值。
  • 优点
    • 能够降低冲突率,提高查找效率。
    • 适用于处理大量数据的场景。
  • 缺点
    • 再哈希会导致重新计算所有元素的哈希值,增加计算时间和空间开销。
    • 当哈希表扩展时,可能会出现性能问题(尤其是在元素非常多时)。

渐进式哈希(Cuckoo Hashing)

  • 渐进式哈希是一种更复杂的解决冲突的方法。在这种方法中,每个元素有两个哈希位置。如果一个位置已经被占用,新的元素会“逐出”原来的元素,原来的元素会被移动到它的备用位置(通过另一个哈希函数)。这样逐步交换直到没有冲突。
  • 优点
    • 查找操作时间复杂度始终保持在 O(1)。
    • 极低的冲突率,适合大规模数据。
  • 缺点
    • 插入操作较为复杂。
    • 需要较多的空间,且逐出和迁移元素的过程可能导致性能下降。

以人言善我,必以人言罪我。 —韩非

相关文章:

数据结构---哈希表

基本概念 哈希函数&#xff08;Hash Function&#xff09;是一种将输入的数据&#xff08;通常是任意大小的&#xff09;映射到固定大小的输出&#xff08;通常是一个固定长度的值&#xff09;的函数。这个输出值通常称为“哈希值”&#xff08;Hash Value&#xff09;或“哈希…...

DataWhale组队学习 leetCode task4

1. 滑动窗口算法介绍 想象你正在用一台望远镜观察一片星空。望远镜的镜头大小是固定的&#xff0c;你可以通过滑动镜头来观察不同的星区。滑动窗口算法就像这台望远镜&#xff0c;它通过一个固定或可变大小的“窗口”来观察数组或字符串中的连续区间。 滑动操作&#xff1a;就像…...

【ESP32】ESP-IDF开发 | WiFi开发 | UDP用户数据报协议 + UDP客户端和服务器例程

1. 简介 UDP协议&#xff08;User Datagram Protocol&#xff09;&#xff0c;全称用户数据报协议&#xff0c;它是一种面向非连接的协议&#xff0c;面向非连接指的是在正式通信前不必与对方先建立连接&#xff0c; 不管对方状态就直接发送。至于对方是否可以接收到这些数据内…...

【PyQt5】数据库连接失败: Driver not loaded Driver not loaded

报错内容如下&#xff1a; 可以看到目前所支持的数据库驱动仅有[‘QSQLITE’, ‘QMARIADB’, ‘QODBC’, ‘QODBC3’, ‘QPSQL’, ‘QPSQL7’] 我在网上查找半天解决方法未果&#xff0c;其中有一篇看评论反馈是可以使用的&#xff0c;但是PyQt5的版本有点低&#xff0c;5.12…...

Unity游戏(Assault空对地打击)开发(1) 创建项目和选择插件

目录 前言 创建项目 插件导入 地形插件 前言 这是游戏开发第一篇&#xff0c;进行开发准备。 创作不易&#xff0c;欢迎支持。 我的编辑器布局是【Tall】&#xff0c;建议调整为该布局&#xff0c;如下。 创建项目 首先创建一个项目&#xff0c;过程略&#xff0c;名字请勿…...

Rust:如何动态调用字符串定义的 Rhai 函数?

在 Rust 中使用 Rhai 脚本引擎时&#xff0c;你可以动态地调用传入的字符串表示的 Rhai 函数。Rhai 是一个嵌入式脚本语言&#xff0c;专为嵌入到 Rust 应用中而设计。以下是一个基本示例&#xff0c;展示了如何在 Rust 中调用用字符串传入的 Rhai 函数。 首先&#xff0c;确保…...

A星算法两元障碍物矩阵转化为rrt算法四元障碍物矩阵

对于a星算法obstacle所表示的障碍物障碍物信息&#xff0c;每行表示一个障碍物的坐标&#xff0c;例如2 , 3; % 第一个障碍物在第二行第三列&#xff0c;也就是边长为1的正方形障碍物右上角横坐标是2&#xff0c;纵坐标为3&#xff0c;障碍物的宽度和高度始终为1.在rrt路径规划…...

【C++】设计模式详解:单例模式

文章目录 Ⅰ. 设计一个类&#xff0c;不允许被拷贝Ⅱ. 请设计一个类&#xff0c;只能在堆上创建对象Ⅲ. 请设计一个类&#xff0c;只能在栈上创建对象Ⅳ. 请设计一个类&#xff0c;不能被继承Ⅴ. 请设计一个类&#xff0c;只能创建一个对象&#xff08;单例模式&#xff09;&am…...

单细胞分析基础-第一节 数据质控、降维聚类

scRNA_pipeline\1.Seurat 生物技能树 可进官网查询 添加链接描述 分析流程 准备:R包安装 options("repos"="https://mirrors.ustc.edu.cn/CRAN/") if(!require("BiocManager")) install.packages("BiocManager",update = F,ask =…...

多项日常使用测试,带你了解如何选择AI工具 Deepseek VS ChatGpt VS Claude

多项日常使用测试&#xff0c;带你了解如何选择AI工具 Deepseek VS ChatGpt VS Claude 注&#xff1a;因为考虑到绝大部分人的使用&#xff0c;我这里所用的模型均为免费模型。官方可访问的。ChatGPT这里用的是4o Ai对话&#xff0c;编程一直以来都是人们所讨论的话题。Ai的出现…...

每日一题-判断是否是平衡二叉树

判断是否是平衡二叉树 题目描述数据范围题解解题思路递归算法代码实现代码解析时间和空间复杂度分析示例示例 1示例 2 总结 ) 题目描述 输入一棵节点数为 n 的二叉树&#xff0c;判断该二叉树是否是平衡二叉树。平衡二叉树定义为&#xff1a; 它是一棵空树。或者它的左右子树…...

FLTK - FLTK1.4.1 - 搭建模板,将FLTK自带的实现搬过来做实验

文章目录 FLTK - FLTK1.4.1 - 搭建模板&#xff0c;将FLTK自带的实现搬过来做实验概述笔记my_fltk_test.cppfltk_test.hfltk_test.cxx用adjuster工程试了一下&#xff0c;好使。END FLTK - FLTK1.4.1 - 搭建模板&#xff0c;将FLTK自带的实现搬过来做实验 概述 用fluid搭建UI…...

《多阶段渐进式图像修复》学习笔记

paper&#xff1a;2102.02808 GitHub&#xff1a;swz30/MPRNet: [CVPR 2021] Multi-Stage Progressive Image Restoration. SOTA results for Image deblurring, deraining, and denoising. 目录 摘要 1、介绍 2、相关工作 2.1 单阶段方法 2.2 多阶段方法 2.3 注意力机…...

AWScurl笔记

摘要 AWScurl是一款专为与AWS服务交互设计的命令行工具&#xff0c;它模拟了curl的功能并添加了AWS签名版本4的支持。这一特性使得用户能够安全有效地执行带有AWS签名的请求&#xff0c;极大地提升了与AWS服务交互时的安全性和有效性。 GitHub - okigan/awscurl: curl-like acc…...

QT使用eigen

QT使用eigen 1. 下载eigen https://eigen.tuxfamily.org/index.php?titleMain_Page#Download 下载后解压 2. QT引入eigen eigen源码好像只有头文件&#xff0c;因此只需要引入头文件就好了 qt新建项目后。修改pro文件. INCLUDEPATH E:\222078\qt\eigen-3.4.0\eigen-3.…...

揭示Baklib企业内容管理系统CMS的核心功能与应用价值

内容概要 企业内容管理系统&#xff08;CMS&#xff09;是指通过一系列工具和技术&#xff0c;帮助企业高效地创建、存储、管理和分发数字内容的系统。这些系统在现代企业运作中发挥着至关重要的作用&#xff0c;尤其是在信息量大、业务流程复杂的环境中。Baklib作为一个突出的…...

如何跨互联网adb连接到远程手机-蓝牙电话集中维护

如何跨互联网adb连接到远程手机-蓝牙电话集中维护 --ADB连接专题 一、前言 随便找一个手机&#xff0c;安装一个App并简单设置一下&#xff0c;就可以跨互联网的ADB连接到这个手机&#xff0c;从而远程操控这个手机做各种操作。你敢相信吗&#xff1f;而这正是本篇想要描述的…...

flume和kafka整合 flume和kafka为什么一起用?

‌Flume和Kafka一起使用的主要原因是为了实现高效、可靠的数据采集和实时处理。‌‌12 实时流式日志处理的需求 Flume和Kafka结合使用的主要目的是为了完成实时流式的日志处理。Flume负责数据的采集和传输,而Kafka则作为消息缓存队列,能够有效地缓冲数据,防止数据堆积或丢…...

java.util.Random类(详细案例拆解)(已完结)

前言&#xff1a; 小编打算近期更俩三期类的专栏&#xff0c;一些常用的专集类&#xff0c;给大家分好类别总结和详细的代码举例解释。 今天是除夕&#xff0c;小编先祝贺大家除夕快乐啦&#xff01;&#xff01; 今天是第六个 java.lang.Math 包中的 java.util.Random类 我…...

Java后端之AOP

AOP&#xff1a;面向切面编程&#xff0c;本质是面向特定方法编程 引入依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>示例&#xff1a;记录…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

Unity中的transform.up

2025年6月8日&#xff0c;周日下午 在Unity中&#xff0c;transform.up是Transform组件的一个属性&#xff0c;表示游戏对象在世界空间中的“上”方向&#xff08;Y轴正方向&#xff09;&#xff0c;且会随对象旋转动态变化。以下是关键点解析&#xff1a; 基本定义 transfor…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟

2025年4月29日&#xff0c;在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上&#xff0c;可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞&#xff0c;强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...

嵌入式面试常问问题

以下内容面向嵌入式/系统方向的初学者与面试备考者,全面梳理了以下几大板块,并在每个板块末尾列出常见的面试问答思路,帮助你既能夯实基础,又能应对面试挑战。 一、TCP/IP 协议 1.1 TCP/IP 五层模型概述 链路层(Link Layer) 包括网卡驱动、以太网、Wi‑Fi、PPP 等。负责…...