模拟散列表(哈希表)

哈希表

哈希表是把一个比较大的值域映射到一个比较小的空间

哈希表的存储结构:

1.开放寻址法:当出现冲突时,按照顺序将数据存放到数组的下一个位置。
2.拉链法:当出现冲突时,在这个位置拉一个链,链上是所有满足这一冲突的元素

image

 哈希表的时间复杂度可以看作O( 1 ),一般只会有添加和查找操作。

字符串的哈希方式:

例题:

image

输入样例:

5
I 1
I 2
I 3
Q 2
Q 5

期望输出:

Yes
No

代码实现:
1.拉链法,需要多开两个数组用来存放数据值和下一个指向地址

#include<bits/stdc++.h>
using namespace std;

const int N = 1e5+3; //取大于1e5的一个质数

int h[N];//哈希表
int e[N],ne[N],idx;//存放拉链

void insert(int a)
{
    int k = (a % N + N)%N;//因为负数取模还是负数,为了让数变成正数,先取模再加N再取模
    e[idx] = k; //新建一个结点并赋值
    ne[idx] = h[k];//让新节点的next指针指向原先h[k]指向的结点
    h[k]=idx++;//让h[k]指向新结点
}

bool query(int a)
{
     int k = (a % N + N)%N;
     for(int i=h[k];i!=-1;i=ne[i])
     {
         if(e[i]==a) return true;
     }
     return false;
}

int main()
{
    memset(h,-1,sizeof(h));
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        char op[2];
        int a;
        scanf("%s%d",op,&a);
        if(*op=='I') insert(a);
        else
        {
            if(query(a)) cout<<"Yes"<<endl;
            else cout<<"No"<<endl;
        }
    }
}

 2.开放寻址法,需要将数组多开两到三倍

#include<bits/stdc++.h>
using namespace std;

const int N = 3e5+7,null = 0x3f3f3f3f;

int h[N];

//与拉链法不同的是,find操作会返回元素所在的值或者元素应该在的值
int find(int u)
{
    int k=(u%N+N)%N;

    while(h[k]!=null && h[k]!=u)
    {
        cout<<h[k]<<endl;
        k++;
        if(k=N) k=0;
    }
    return k;
}

int main()
{
    int n;
    cin>>n;
    memset(h,0x3f,sizeof(h));//memset是按字节填充的,int有4个字节,也就是每个数是0x3f3f3f3f
    while(n--)
    {
        char op[2];
        int a;
        scanf("%s%d",op,&a);
        int k =find(a);
        if(*op=='I') h[k]=a;
        else
        {
            if(h[k]==a) cout<<"Yes"<<endl;
            else cout<<"No"<<endl;
        }
    }
}

  

posted @ 2025-09-13 11:34  小花护符  阅读(20)  评论(0)    收藏  举报