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

深入理解哈希结构及其应用

目录

前言

1. unordered系列关联式容器

1.1 unordered_map与unordered_set

2. 哈希的底层结构

2.1 哈希概念

2.2 哈希冲突

2.3 哈希函数设计

3. 哈希的应用

3.1 位图(Bitmap)

3.2 布隆过滤器(Bloom Filter)

4. 海量数据处理技巧

4.1 哈希切割

4.2 位图应用

4.3 精确与近似算法

总结


前言

哈希(Hash)是计算机科学中一种非常重要的数据结构,它通过将关键码映射到表中位置来实现高效的数据访问。本文将全面介绍哈希的概念、实现方式以及在实际中的应用。


1. unordered系列关联式容器

在C++中,STL提供了两种主要的关联式容器:基于红黑树的`map/set`和基于哈希表的`unordered_map/unordered_set`。

1.1 unordered_map与unordered_set

`unordered_map`是存储键值对的关联容器,允许通过key快速索引到对应的value。与`map`相比,`unordered_map`有以下特点:

- 内部元素无序存储
- 通过哈希表实现,平均访问时间为O(1)
- 遍历效率低于`map`
- 实现了直接访问操作符`operator[]`


 

// 使用示例:统计元素出现次数
unordered_map<int, int> m;
for(auto e : A) m[e]++;


 

`unordered_set`与`unordered_map`类似,但只存储key而不存储value。

2. 哈希的底层结构

2.1 哈希概念

哈希的基本思想是通过一个函数(哈希函数)将关键码映射到表中的位置。理想情况下,这个映射是一对一的,可以实现O(1)的查找效率。

2.2 哈希冲突

当不同关键码通过哈希函数计算出相同的哈希地址时,就发生了哈希冲突。解决冲突的常见方法有:

1. 闭散列(开放定址法):
   - 线性探测:从冲突位置开始,依次向后探测空位
   - 二次探测:使用二次方程计算下一个探测位置

2. 开散列(链地址法):
   - 每个哈希桶维护一个链表,冲突元素直接链接到链表后面

2.3 哈希函数设计

好的哈希函数应该满足:
- 计算简单
- 分布均匀
- 冲突概率低

常见哈希函数:
- 直接定址法:Hash(Key) = A*Key + B
- 除留余数法:Hash(key) = key % p(p为质数)
- 平方取中法、折叠法、随机数法等

3. 哈希的应用

3.1 位图(Bitmap)

位图是用每一位来表示某种状态的数据结构,非常适合海量数据的判重和统计。


 

class bitset {
public:void set(size_t which);  // 置位void reset(size_t which); // 复位bool test(size_t which); // 测试
};


 

应用场景:
- 快速查找数据是否存在
- 排序和去重
- 求集合交集、并集
- 操作系统磁盘块标记

3.2 布隆过滤器(Bloom Filter)

布隆过滤器是一种概率型数据结构,可以高效地判断元素"可能存在"或"一定不存在"。

特点:
- 空间效率极高
- 查询时间O(k),k为哈希函数个数
- 有一定误判率
- 不支持删除操作(除非使用计数布隆过滤器)


 

template<size_t N, size_t X = 5, class K = string, class HashFunc1 = BKDRHash, ...>
class BloomFilter {
public:void Set(const K& key);bool Test(const K& key);
};


 

应用场景:
- 网络爬虫URL去重
- 垃圾邮件过滤
- 缓存穿透防护
- 推荐系统内容去重

4. 海量数据处理技巧

4.1 哈希切割

问题:100G日志文件,找出出现次数最多的IP

解决方案:
1. 将大文件哈希分割成小文件
2. 对每个小文件统计IP频率
3. 合并结果找出最大值

4.2 位图应用

问题:100亿整数,找出只出现一次的整数

解决方案:
使用两个位图表示状态:
- 00:未出现
- 01:出现一次
- 10:出现多次

4.3 精确与近似算法

问题:两个100亿query文件,找交集

解决方案:
- 精确算法:哈希切割后归并
- 近似算法:布隆过滤器


总结

哈希结构是现代计算机系统中不可或缺的组成部分,从语言内置的关联容器到操作系统底层,再到各种分布式系统,哈希都发挥着重要作用。理解哈希的原理和各种变体(如位图、布隆过滤器)的实现,对于设计高效算法和解决实际问题至关重要。

在实际应用中,我们需要根据具体场景选择合适的数据结构:当需要精确结果且内存充足时使用哈希表;处理海量数据且允许一定误差时考虑布隆过滤器;对于整数相关操作,位图往往是最高效的选择。

http://www.lryc.cn/news/618518.html

相关文章:

  • secureCRT ymodem协议连续传输文件速率下降
  • 鸿蒙开发教程实战案例源码分享-好看的SwitchButton
  • [SC]SystemC中的SC_FORK和SC_JOIN用法详细介绍
  • 17、CryptoMamba论文笔记
  • 42.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--扩展功能--集成网关--网关集成认证(一)
  • UNet改进(32):结合CNN局部建模与Transformer全局感知
  • Day45--动态规划--115. 不同的子序列,583. 两个字符串的删除操作,72. 编辑距离
  • DeepSeek-R1-0528 推理模型完整指南:领先开源推理模型的运行平台与选择建议
  • XC7A15T-1FTG256C Xilinx AMD Artix-7 FPGA
  • Linux中Apache与Web之虚拟主机配置指南
  • git config的配置全局或局部仓库的参数: local, global, system
  • 【unity实战】使用Splines+DOTween制作弯曲手牌和抽牌动画效果
  • 有限元方法中的数值技术:行列式、求逆、矩阵方程
  • 【bug 解决】串口输出字符乱码的问题
  • 【Datawhale夏令营】多模态RAG学习
  • 【Bug经验分享】由jsonObject-TypeReference引发的序列化问题
  • 【昇腾】关于Atlas 200I A2加速模块macro0配置3路PCIE+1路SATA在hboot2中的一个bug_20250812
  • STM32_bug总结(TIM定时中断进不去和只进1次)
  • 高性能web服务器Nginx
  • 【Android】【bug】Json解析错误Expected BEGIN_OBJECT but was STRING...
  • linux 开机进入initramfs无法开机
  • 跨设备开发不再难:HarmonyOS 分布式任务管理应用全解析
  • 《Fast Automatic White Balancing Method by Color Histogram Stretching》论文笔记
  • 让齿轮与斑马线共舞:汽车文化驿站及安全教育基地的展陈实践
  • 农业智慧大屏系统 - Flask + Vue实现
  • 安全合规5--终端安全检测和防御技术
  • Python初学者笔记第二十二期 -- (JSON数据解析)
  • 【智慧城市】2025年湖北大学暑期实训优秀作品(3):基于WebGIS的南京市古遗迹旅游管理系统
  • 机器学习 [白板推导](十)[马尔可夫链蒙特卡洛法]
  • js高阶-总结精华版