哈希表:把你的数据藏进抽屉里,查找快得像开外挂

0 阅读3分钟

想象一下,你家有一大堆钥匙和信件,如果全堆在桌子上,每次找一把钥匙都得翻半天,这就是普通数组或列表的痛苦。 如果有个聪明的小伙伴帮你把每把钥匙分门别类,直接放到编号抽屉里,你想找哪把钥匙一眼就能找到,这就是 哈希表(Hash Table)的感觉。 今天我就带你体验这种“数据瞬间定位”的魔法工具——Java 的 HashMap 和 HashSet。

概念

哈希表就像一个智能抽屉系统:

  • 每个抽屉都有编号哈希函数 = 小伙伴帮你算出抽屉号,冲突怎么办?  → 多个人的信件放到同一个抽屉里,用小盒子装起来

哈希表的本质就是:用聪明的计算公式,把你要找的东西直接放到能最快找到的地方

哈希函数:抽屉定位器

想象你有 100 个抽屉,要存钥匙,钥匙上有数字 ID。

哈希函数就像一个公式:

把钥匙ID % 100 → 得到抽屉编号

这样不管钥匙有多少,查找都是一步到位

再也不用像找零件一样一格格翻了

哈希冲突:抽屉里塞满了怎么办? 哈希函数可能把两把钥匙算到同一个抽屉,解决办法:

链地址法:在这个抽屉里放一个小盒子,里面放所有钥匙

开放地址法:找下一个空抽屉存

Java 的 HashMap/HashSet 就用链地址法 + 红黑树优化(当盒子太满时自动变成小树)

 
HashMap 就像你家抽屉里的钥匙:
 
key = 钥匙
 
value = 钥匙扣上的标签(比如钥匙用途)
map.put("Java书房钥匙", "书架A");
map.put("家门钥匙", "门锁");
map.put("车钥匙", "车库");

想找车钥匙?map.get("车钥匙"),一眼就找到抽屉里的钥匙扣,不用翻半天

HashSet:只管唯一性

  • HashSet 就像你家抽屉只收独一无二的钥匙,重复的钥匙不收。实现上,HashSet 直接用 HashMap 存 key,value 用固定对象占位。
set.add("Java书房钥匙");
set.add("家门钥匙");
set.add("Java书房钥匙"); // 重复,没收

效果:

你看,“重复钥匙自动丢掉”,再也不用检查重复了

 
查找元素 → 哈希函数算出抽屉 → 一步拿到
 
删除元素 → 哈希函数算出抽屉 → 拿掉即可
 
这就是为什么 HashMap/HashSet 查找、插入、删除几乎都是 O(1)
你不再翻箱倒柜,直接开挂般找东西
 
抽屉 = 数组
 
哈希函数 = 算出抽屉编号的公式
 
链表/红黑树 = 抽屉里的小盒子
 
HashMap = 钥匙-钥匙扣对应关系
 
HashSet = 只收独一无二的钥匙

练习

1.

代码:

#include<iostream>
#include<string>
#include<unordered_set>
using namespace std;
int main()
{
int N;
cin>>N;
unordered_set<string>s;
    for(int i=0;i<N;i++)
    {
        string x;
        cin>>x;
        s.insert(x);
    }
    cout<<s.size();
     return 0;
}
解析:

unordered_set可以实现去重操作;

2.

代码:

#include<iostream>
#include<string>
#include<unordered_map>
using namespace std;
int main()
{
	int n;
	cin >> n;
	unordered_map<string,int>students;
	for (int i = 0; i < n; i++)
	{
		string name;
		cin >> name;
		students[name] = 0;
	}
	int m; cin >> m;
	for (int i = 0; i < m; i++)
	{
		string s;
		cin >> s;
		auto it = students.find(s);
		if (it == students.end())
		{
			cout << "WRONG" << endl;
		}
		else if (it->second == 0)
		{
			cout << "OK" << endl;
			it->second = 1;
		}
		else if (it->second == 1)
		{
			cout << "REPEAT" << endl;
		}
	}
	return 0;
}
解析:

这道题主要就是利用哈希表,哈希表时间复杂度小,O(1),非常快速,本题思路是首先利用迭代器it和find函数判断能不能找到所输入字符串,找到了的话就将it->second改为1(最开始初始化是0),这样下次找到的话,值变为1,就返回REAPEAT;