数据结构---哈希表

news/2025/1/30 20:42:37/

基本概念

哈希函数(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)。
    • 极低的冲突率,适合大规模数据。
  • 缺点
    • 插入操作较为复杂。
    • 需要较多的空间,且逐出和迁移元素的过程可能导致性能下降。

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


http://www.ppmy.cn/news/1567975.html

相关文章

CLion入门2.0(优雅进行STM32和ESP32开发)(船新版本)

CLion入门2.0(优雅进行STM32和ESP32开发)(船新版本) 文章目录 CLion入门2.0(优雅进行STM32和ESP32开发)(船新版本)0.前言1.准备工作1.1.安装CLion1.2.下载STM32环境依赖1.2.1.STM32CubeMX1.2.2.OpenOCD1.2.3.MinGW1.2.4.GNU Arm Embedded Toolchain 1.3.下载ESP32环境依赖1.3.1…

AI软件栈:LLVM分析(一)

文章目录 AI 软件栈后端编译LLVM IRLLVM的相关子项目AI 软件栈后端编译 AI软件栈的后端工作通常与硬件架构直接相关,为了实现一个既能适配现代编程语言、硬件架构发展的目标,所以提出了LLVM具备多阶段优化能力提供基础后端描述,便于进行编译器开发兼容标准编译器的行为LLVM …

Baklib引领数字化内容管理转型提升企业运营效率

内容概要 在数字化迅速发展的背景下&#xff0c;企业正面临着前所未有的内容管理挑战。传统的内容管理方式已难以适应如今的信息爆炸&#xff0c;企业需要更加高效、智能的解决方案以应对复杂的数据处理需求。Baklib作为行业的先锋&#xff0c;以其创新技术对数字化内容管理进…

软考信安27~Windows操作系统安全相关

1、Windows账户与组管理 1.1、用户账户查看 whoami #查看当前登录的用户名称 whoami /all #查看当前系统的用户名和组信息,以及SID whoami /user #查看当前用户的SID net user #查看系统中包含哪些用户 wmic useraccount get name,sid #查看…

定时任务Spring Task双向数据传输WebSocket

之前的代码已完成基础功能&#xff0c;但仍有一些逻辑未完善&#xff1a; 定时任务&#xff1a; 用户下单15分钟后仍未支付&#xff0c;订单判定为超时。status应修改为6(已取消)。管理端忘记点击"完成"&#xff0c;使订单长时间处于"派送中"状态。系统需…

2021 年 6 月大学英语四级考试真题(第 2 套)——纯享题目版

&#x1f3e0;个人主页&#xff1a;fo安方的博客✨ &#x1f482;个人简历&#xff1a;大家好&#xff0c;我是fo安方&#xff0c;目前中南大学MBA在读&#xff0c;也考取过HCIE Cloud Computing、CCIE Security、PMP、CISP、RHCE、CCNP RS、PEST 3等证书。&#x1f433; &…

前端UI组件库的打包与发布

UI组件库的打包是指“将开发完成的业务代码处理成可在生产环境中运行&#xff0c;并供用户在浏览器上使用”的过程。浏览器可以视为用户使用的生产环境&#xff0c;除浏览器外&#xff0c;常见的生产环境还有Node.js。Node.js通常是现代前端开发过程所运行的环境&#xff0c;例…

2024 CVPR Highlight Learning-Feedback

图像增强 Towards Robust Event-guided Low-Light Image Enhancement: A Large-Scale Real-World Event-Image Dataset and Novel Approach 解决的主要问题是低光照条件下的图像增强 通过多尺度整体融合分支提取事件和图像的结构和纹理信息&#xff0c;并引入信噪比&#xff0…