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

蓝桥备赛(19)- 哈希表和 unordered_ set 与unordered_map(上)

一、哈希表的概念

1.1 哈希表的定义

哈希表(hash table),又称散列表 是根据  关键字直接  进行访问的数据结构。
哈希表建立了一种 关键字 存储地址 之间的 直接映射 关系,使每个关键字与结构中的 唯⼀存储位置相对应
理想情况下,在散列表中进行查找的时间复杂度为 O(1) 即与表中的元素数量无关。因此哈
希表是⼀种存储和查找非常快的结构。

举个例子:

1.2 哈希函数

关键字  映射   成对应的地址的函数就是哈希函数 ,也叫作散列函数,
记为 Hash(key) = Addr 
哈希函数的本质也是⼀个函数,它的作用是,你给它⼀个关键字,它给你一个该关键字对应的存储位置。

1.3 哈希冲突

哈希函数可能会把两个或两个以上的不同关键字映射到同一地址 ,这种情况称为哈希冲突,也称散列冲突。起冲突的不同关键字,称它们为同义词。

这里是 %7 出现了冲突, 那为什么不 %8 , %10 ?

二、常见的哈希函数

2.1 直接定址法

案例中,统计字符串中,小写字符出现的次数使用的方法,就是直接定址法
直接取关键字的某个线性函数值为散列地址 ,散列函数是 hash(key) = key 或 hash(key)= a× key + b 其中 a 与 b 为常数。这种方式计算比较简单,适合关键字的分布基本连续的情况,但是若关键字分布不连续,空位较多,则会造成存储空间的浪费。

 

2.2 除留余数法

哈希冲突那里的案例,所用的哈希函数就是除留余数法。
M 一般取质数(素数)

2.3 其他方法

上面的两种方法是《算法导论》书籍中讲解的方法,除此之外还有乘法散列法和全域散列法。
《殷人昆 数据结构:用面向对象方法与C++语言描述 (第⼆版)》和 《[数据结构(C语言版)].严蔚敏_ 吴伟民》等教材型书籍上面还给出了平方取中法、折叠法、随机数法、数学分析法等,这些方法相对更适用于⼀些局限的特定场景,有兴趣可以去看看这些书籍。

三、处理哈希函数

有时候哈希表无论选择什么哈希函数都无法避免冲突 ,那么插入数据时,如何解决冲突呢?
主要有两种方法,线性探测法  和  链地址法

3.1 线性探测法

线性探测是有弊端的 , 如果数据过于密集的话 ,则需要探测多次 , 例如在上面的数组的加个 8 ,那么需要探测多次才能找到存储地址。

那么在创建数组的时候 , 一般会创造  数组元素个数的两倍 的空间个数 , 为的是避免数据过于密集 , 但是依旧会存在一些弊端~

3.2 链地址法

这个也有一点弊端 , 如果所有的数据都冲突在 8 这个位置上 , 怎么办?

---> 把冲突的数据 , 构造成一个红黑树 , 挂在冲突地址上 , 此时查找的时间复杂度会变成logN级别的

相关文章:

  • 程序化广告行业(13/89):DSP的深入解析与运营要点
  • C++自学方法论:从零基础到工程实践的体系化路径研究
  • Leetcode:34(二分查找)
  • CNN 稠密任务经典结构
  • 【前端文件下载实现:多种表格导出方案的技术解析】
  • Linux系统下安装Gedit文本编辑器的完整指南
  • 基于YOLOv8深度学习的PCB缺陷检测识别系统【python源码+GUI界面+数据集+训练代码】
  • 跨平台直播美颜SDK开发指南:如何兼容iOS、Android与Web
  • 虚拟系统实验
  • 【redis】set 类型:基本命令
  • STM32与HAL库开发实战:深入探索ESP8266的多种工作模式
  • 《C++并发编程实战》精读总结:第四章 并发操作的同步
  • Webpack 和 Vite 的主要区别
  • JVM 的不同组成部分分别有什么作用?
  • Navicat SqlServer 设置自增主键
  • 堆的应用(堆排序TopK问题)
  • mysql存储引擎、索引、事务---java
  • 【工具】C#游戏防沉迷小工具
  • docker桌面版启动redis,解决无法连接
  • 大数据技术之Spark优化
  • 《远山淡影》改编电影入围戛纳关注单元,张怡微谈石黑一雄
  • 中沙深化多领域合作,达成60余项共识
  • 杭州3宗住宅用地收金42.49亿元,最高溢价率51.38%
  • 专访《风雪夜归人》导演闫锐:在舞台上表现什么是真正的活着
  • 人民日报:不能层层加码,要层层负责
  • 申伟强任上海申通地铁集团有限公司副总裁