哈希的了解

首先让我们来看看哈希的具体例子。

计数统计:开了一个足够大的数组,以统计每个数的出现次数,再输出从小到大每个有出现的数。

这个就是直接映射的哈希,只适用数据范围比较集中的整数。

cpp 复制代码
#include<iostream>
using namespace std;
const int MAXN = 1000010; 
int a[MAXN]; 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    if (!(cin >> n)) return 0;
    for(int i = 1; i <= n; i++){
        int x;
        cin >> x; // 简单的边界检查,防止数组越界(虽然题目保证了 0<x<1000010)
        if(x >= 0 && x < MAXN) {
            a[x]++;
        }
    }
    for(int i=1;i<MAXN;i++){
		if(a[i]!=0)
    	cout<<i<<":"<<a[i]<<endl; 
	}
    return 0;
}

哈希的本质就是建立一个**"键(Key)"到"值(Value)"**的映射关系。

哈希容器和普通容器的对比

|------|---------------|----------|
| 对比 | unordered_set | set |
| 底层 | 哈希桶 | 红黑树 |
| 迭代器 | 单向迭代器 | 双向迭代器 |
| 增删查 | O(1) | O(log n) |
| 存储顺序 | 无序 | 有序 |

哈希函数

对于比较大范围的数就要使用哈希函数来映射到对应的位置存放。

有以下比较常用的哈希函数:

方法 原理 适用场景
除留余数法 H(key)=key(modM)H(key)=key(modM) 最常用,适用于大多数整数键值。
平方取中法 先求 key2key2 ,再取中间几位 当不知道关键字的分布规律时,平方后的中间位受每一位影响较大,分布较均匀。
折叠法 将大数切分成几段相加 适用于关键字位数很多的情况(如身份证号、长数字串)。
乘法散列法 H(key)=⌊M×(key×A(mod1))⌋H(key)=⌊M×(key×A(mod1))⌋ 对 MM 没有特殊要求(可以是 2 的幂),利用常数 AA (如黄金分割率) 提取小数部分。

哈希冲突

只要是哈希的函数就会有哈希冲突

| 方法 | 问题 |
| 除留余数法 | 101%100=1,201%100=1 |
| 平方取中法 | 23*23=529取中间02,45*45=2025也是02; |
| 折叠法 | 123456和456123,截取相加相等 |

乘法散列法 4×0.25=1.00和8*0.25=2.00,小数位相同

有两种解决方法

1:开放定址法

|------|-----------|------------------------------------------------|-----------------------------|
| 方法 | 用法 | 优点 | 缺点 |
| 线性探测 | 往后找 | 最简单、最直观 | 一旦某个区域发生了冲突,这片区域就会被填满 |
| 二次探测 | 跳着找 | 减少了"一次聚集"现象,数据分布更散 | 可能会出现二次聚集,而且不能保证遍历到所有槽位 |
| 双重哈希 | 再使用哈希函数安放 | 步长是根据关键字本身计算出来的,不同的关键字会有不同的步长,极大地减少了聚集,分布非常均匀。 | 复杂 |

2:链地址法

把映射到相同位置的值,由特定的顺序链接起来。

对比

特性 开放定址法 链地址法
存储结构 纯数组,无指针 数组 + 链表/红黑树
内存占用 较省内存(无指针开销),但需预留空位 需要额外的指针空间
缓存性能 极好(数据连续,CPU 缓存命中率高) 一般(链表节点分散在堆内存中)
负载因子 必须小于 1(通常建议 < 0.7~0.8) 可以大于 1
适用场景 键值对较小、对性能极其敏感、内存紧凑的场景 通用场景(如 Java HashMap, C++ unordered_map)
相关推荐
UIU11411 小时前
P1233 [ICPC 2001 Taejon R] 木棍加工
数据结构·c++·算法·动态规划
论文复现现场12 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
ZhengEnCi12 小时前
用 AI 写代码为什么拼到最后还是拼人:算力瓶颈与领域专家提示词的本质差异
算法·架构
秋天的怀念_David13 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
碧海银沙音频科技研究院13 小时前
在PC电脑上用Whisper→Marian算法实现离线语音翻译功能
算法·whisper
niyongsheng14 小时前
3D 装箱算法工程化:数据结构、放置启发式与支撑规则
数据结构·算法·rust
j7~16 小时前
【穷举、深搜与回溯算法】一棵决策树讲透全排列与子集
数据结构·c++·算法·leetcode·回溯·递归
傅科摆 _ py17 小时前
DP,贪心,堆和栈,二分力扣复习
开发语言·python·算法
Shaoshing18 小时前
LeetCode100 42.接雨水
java·算法·leetcode
域限奇点访客18 小时前
用AI生成问卷的网站怎么选?看题目录入结构、题型映射和生成后的校验
算法