学习笔记 哈希表
最近开始把之前欠的NOIP基础知识点刷一下
2333其实我的作业还没有写完
做到哈希表的时候,我有点懵,显然前几次讲课的时候我没有听
于是Lbmttw_lx就开始在网上学习了
(啊啊啊 沙雕橘猫真心可爱,爱了爱了)
发现其实Hash表是个比较有趣的东西
(一种典型的空间换时间的数据结构,也叫散列表)
时间复杂度O(1)查询
哈希表之所以能过做到O(1)查询,是因为它的查询是直接按照关键字Key Value来的
也就是说,它将关键字通过某种规则映射到数组中的某个位置,以加快查找的速度。
哈希表中的每一个元素,都应该有且只有一个地址。
如果两个元素都拥有一个地址,就产生了哈希冲突,发生冲突的不同关键字被称之为同义词。
处理哈希冲突有很多方法,但是都是基于处理关键字而来的,尽可能让关键字都不相同。
那么,关键字是如何来的呢?其实就是哈希函数处理得到的。
首先是哈希函数H,H就是赋予特定元素特定的地址的函数,哈希表则是基于哈希函数而建立起来的查找表
那么问题来了,既然哈希函数这么好,我们如何构造它呢??
有好几种构造哈希函数的方法,分别是
1.直接定址法
2.数学分析法
3.平方取中法
4.折叠法
5.除留余数法
由于第一种 和第五种方法可能用到的比较广泛,主要说一下这两种吧
我是不会告诉你们剩下几种我也不会的!
1.直接定址法
取元素的关键字或关键字的线性函数值为散列地址
如H(x)=x或H(x)=a*x+b(a,b都为常数)
2.除留余数法
取关键字被某个不大于散列表长度 m 的数 p 求余,得到的作为散列地址。
即 H(key) = key % p, p < m。
还有很多构造哈希函数的方法,无论是什么方法,原则都应该是
尽可能避免或减少哈希冲突
23333上那道模板题
问题描述
给定两个集合A、B,集合内的任一元素x满足1 ≤ x ≤ 10^9,并且每个集合的元素个数不大于10000 个。我们希望求出A、B之间的关系。只需确定在B 中但是不在 A 中的元素的个数即可。
输入文件
第一行两个数m和n分别表示集合A和集合B元素的个数。 以下两个分别是集合A和集合B的元素。
输出文件
一个数,表示在B中但是不在 A 中的元素的个数。
输入样例
5 6
1 3 8 4 9
4 8 9 10 12 13
输出样例
3
限制和约定
时间限制:1s
空间限制:128MB
是不是看完博客介绍之后觉得这道题很简单了呢??
1 #include <bits/stdc++.h> 2 #define mo 100005 3 #define MAXN 2000000 4 using namespace std; 5 int m,n,a[MAXN],b,ans,ha[MAXN],now[MAXN]; 6 bool Hash(int i) 7 { 8 int pos=a[i]%mo+1; //除留余数法赋予地址 9 ha[i]=now[pos]; 10 now[pos]=i; 11 } 12 bool judge(int x) 13 { 14 int pos=x%mo+1; 15 bool ju=0; 16 for(int i=now[pos];i;i=ha[i]) //类不类似于 图论中的链表 17 { 18 if(a[i]==x) 19 { 20 ju=1; 21 break; 22 } 23 } 24 return ju; 25 } 26 int main() 27 { 28 cin>>m>>n; 29 for(int i=1;i<=m;i++) 30 { 31 scanf("%d",&a[i]); 32 Hash(i); 33 } 34 for(int i=1;i<=n;i++) 35 { 36 scanf("%d",&b); 37 if(!judge(b)) 38 ans++; 39 } 40 cout<<ans<<endl; 41 return 0; 42 }
View Code
大概就这么多吧!!!有错误麻烦及时留言,谢谢!!~~~