hash表/哈希表

https://blog.csdn.net/duan19920101/article/details/51579136

简单理解就是一个通过映射直接查找的表(散列表),用哈希函数将数据按照其存储特点进行存储。查询效率接近是O(1)的。

存储方式是结合了数组和链表的思想,用链表将存储的数据直接相连,便于查询和修改。

其实就是一个储存优化的方式。

缺点

它是基于数组的,数组创建后难于扩展,某些哈希表被基本填满时,性能下降得非常严重,所以程序员必须要清楚表中将要存储多少数据(或者准备好定期地把数据转移到更大的哈希表中,这是个费时的过程)。

构造

根据不同的数据特点有不同的构造方法:

https://blog.csdn.net/weixin_38169413/article/details/81612307

基本上就是解决冲突的方法不同。

开放地址法:

对于存储x,把他存到(x+i)%mod里。

i最开始等于零。如果冲突,就i++,重复直到找到空地址。mod大于数据大小并一般为质数。

eg:存名字和成绩按名字查询

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
struct stu{
    string to;
    int nxt,da;
}e[100];
int head[100000],cnt;
inline int hsh(string s)
{
    int ln,hash=0,seed=31,t;//seed is a prime
    int len=s.length();
    for(int i=0;i<=len;i++)
    {
        hash=hash*seed+s[i];
        hash%=99999;
    }
    t=head[hash];
    while(t!=-1)
    {
        if(e[t].to==s)return t;
        t==e[t].nxt;
    }
    if(t==-1)
    {
        e[++cnt]=(stu){s,head[hash],0};head[hash]=cnt;
        t=cnt;
    }
    return t;
}
inline int findhsh(string s)
{
    int ln,hash=0,seed=31,t;//seed is a prime
    int len=s.length();
    for(int i=0;i<=len;i++)
    {
        hash=hash*seed+s[i];
        hash%=99999;
    }
    t=head[hash];
    while(t!=-1)
    {
        if(e[t].to==s)return e[t].da;
        t=e[t].nxt;
    }
    return t;
}
int main()
{
    std::ios::sync_with_stdio(false);
    memset(head,-1,sizeof head);
    int n;
    cin>>n;
    string x;
    int y,m,nn;
    for(int i=1;i<=n;i++)
    {
        cin>>x>>y;
        m=hsh(x);//地址 
        e[m].da=y;
    }
    cin>>nn;
    for(int i=1;i<=nn;i++)
    {
        cin>>x;
        cout<<findhsh(x)<<endl;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/BrotherHood/p/13092343.html