1145 Hashing - Average Search Time (25 分)
原题链接
- 大致题意
- 思路
- AC代码
- Hash笔记
1.大致题意
将数字插入到hash表中,
(1)hash映射规则如下:
H(key)=key%Tsize
Tsize:是hash表的最大长度
(2)哈希表的最大尺寸x是素数,如果给定的最大尺寸不是素数的话,
自己需要重新找到比x大的最小素数。
注意:Quadratic probing (with positive increments only) is used to solve the collisions.(用平方探测法,正增量去解决冲突)
2.思路
(1)检测MSize是否符合要求
(2)先找到⼤于tsize的最⼩的素数为真正的tsize,然后建⽴⼀个tsize⻓度的数组。⾸先⽤平⽅探测法插⼊数字a,每次pos = (a + j * j) % tsize,j是从0~tsize-1的数字,如果当前位置可以插⼊就将a赋值,给v[pos],如果⼀次都没有能够插⼊成功就输出”X cannot be inserted.”。
(3)其次计算平均查找时间,每次计算pos = (a + j * j) % tsize,其中j <= tsize,如果v[pos]处正是a则查找到了,则退出循环,如果v[pos]处不存在数字表示没查找到,那么也要退出循环。每次查找的时候,退出循环之前的j就是这个数字的查找⻓度。最后ans除以m得到平均查找时间然后输出~
来源:《大话数据结构》第八章
链接: https://pan.baidu.com/s/1S9lZPNA_qydJKHn21ydThA 提取码: 8i5k
pdf解压密码:johngo_tec
3.AC代码
#include<bits/stdc++.h>
using namespace std;
bool isprime(int n)//判断素数
{
if(n==0||n==1)return false;
for(int i=2;i*i<=n;i++)
if(n%i==0)return false;
return true;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
{
freopen("2.txt","r",stdin);
}
#endif
int tsize,n,m,a;
cin>>tsize>>n>>m;
//找到满足的tsize
while(!isprime(tsize))tsize++;
//###########################
vector<int>v(tsize);//Hash Table
//输入n个数字,判断能否插入Hash Table
for(int i=0;i<n;i++)
{
cin>>a;
int flag=0;//flag=0表示不能插入
//平方探测法
for(int j=0;j<tsize;j++)//平方探测法的j值
{
int pos=(a+j*j)%tsize;
if(v[pos]==0)//如果当前这个位置是空的,说明可以插入
{
v[pos]=a;
flag=1;//flag=1表示这个数字可以插入Hash Table
break;
}
}
//如果flag=0,说明当前元素不能插入hash table
if(flag==0) printf("%d cannot be inserted.\n",a);
}
int ans=0;
/**
求平均查找时间:对于m个元素,先求出每个元素查找的时间,
然后最后除以m即可
**/
for(int i=0;i<m;i++)
{
cin>>a;//输入元素a
for(int j=0;j<=tsize;j++)
{
ans++;//时间+1
int pos=(a+j*j)%tsize;//将元素a映射为key,平方探测法
if(v[pos]==a||v[pos]==0)break;//找到了或者为空
}
}
printf("%.1f\n",ans*1.0/m);//平均查找时间
return 0;
}
Hash笔记
来源:《大话数据结构》第八章
链接: https://pan.baidu.com/s/1S9lZPNA_qydJKHn21ydThA 提取码: 8i5k
pdf解压密码:johngo_tec
Hashmap哈希散列笔记:
1、存储位置=f(关键字)
通过查找关键字不需要比较就可以获得需要的记录的存储位置,这就是一种存储技术——散列技术。
2、散列技术是在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key)。查找时,根据这个确定的对应关系找到给定值key的映射f(key),若查找集合中存在这个记录,则必定在f(key)的位置上。
我们把这种对应关系f称为散列函数,又称为哈希(Hash)函数。
采用散列技术将记录存储在一块连续的存储空间中,这块连续存储空间称为散列表或哈希表(Hash table),那么关键字对应的记录存储位置我们称为散列地址。
3、整个散列过程其实就是两步:
(1)在存储时,通过散列函数计算记录的散列地址,并按此散列地址存储该记录。就像张三丰我们就让他在体育馆,那如果是“爱因斯坦”我们就让他在图书馆,如果是“居里夫人”那就让她在化学实验室,如果是巴顿将军,这个打仗的将军就让他在网吧。总之,不管什么记录,我们都需要用同一个散列函数计算出地址在存储。
(2)当查找记录时,我们通过同样的散列函数计算记录的散列地址,按此散列地址访问该记录。说起来很简单,在哪存的,上哪找,由于存取用的是同一个散列函数,因此结果当然也是相同的。
所以说,散列技术既是一种存储方法,也是一种查找方法。
散列技术的记录之间不存在什么逻辑关系,它只与关键字有关联。因此,散列主要是面向查找的存储结构。
4.散列技术最适合的求解问题是查找和定值相等的记录。对于查找来说,简化了比较过程,效率就会大大提高。
但也有弊端,比如那种同样的关键字,它能对应很多记录的情况,却不适用散列技术。
5.另外一个问题是 冲突。在理想的情况下,每一个关键字,通过散列函数计算出来的地址都是不一样的,可现实中,这只是一个理想。我们时常会碰到两个关键字key1≠key2,但是却又f(key1)=f(key2),这种现象我们称为冲突,并把key1和key2称为这个散列函数的同义词。
我们要尽可能得使冲突最少。
…
妈耶打到一半,发现后面好多东西~
客官自己看叭o(TヘTo)
喵!~