#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int const maxn=100003;
int h[maxn],e[maxn],ne[maxn],idx;
////h[]是哈希函数的一维数组//e[]是链表中存的值//ne[]是指针存的指向的地址//idx是当前指针
void insert(int x)
{
int k=(x%maxn + maxn)%maxn; ////对负数的处理,k是哈希值
e[idx]=x;ne[idx]=h[k];h[k]=idx++; //如果不同单链表的idx都是从0开始单独计数,
//那么不同链表之间可能会产生冲突。
//这里的模型是这样的:e[]和ne[]相当于一个大池子,里面是单链表中的节点,会被所有单点表共用,idx相当于挨个分配池子中的节点的指针。
//比如如果第0个节点被分配给了第一个单链表,那么所有单链表就只能从下一个节点开始分配,所以所有单链表需要共用一个idx。
}
bool find(int x)
{
int k= (x%maxn+ maxn) %maxn; ///为了让负数在整数有映射,负数的取模还是负数,加上maxn后为正,再%即可
for(int i=h[k];i!=-1;i=ne[i])
if(e[i]==x)
return true;
return false;
}
int main(void)
{
cin.tie(0);
int n;
cin>>n;
memset(h,-1,sizeof(h)); ///所有槽都清空,对应的是单链表的头(head)[注:head存的是地址,详见单链表的课]指针为-1
while(n--)
{
char op[2];
int x;
scanf("%s%d", op, &x);
if(op[0]=='I') insert(x);
else
{
if(find(x)) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}
return 0;
}
####
```
这个注释写的位置一言难尽
hhh
可以可以,就在找/h[]是哈希函数的一维数组//e[]是链表中存的值//ne[]是指针存的指向的地址//idx是当前指针这句话
哈希表本质上是指针数组?
这只是一种方法 还有开放寻址法
h[k]这个数组存的值代表啥含义啊
假如m哈希之后的值是k,那么h[k]存的就是m在数组e中的位置,然后再通过ne数组来找哈希值是k的数的位置
h[k]存的是指针, 你可以把它看成头节点, h[k]初始化为-1表示指向空
h[k]存的是 储存 哈希后映射到k的数 的链表 的头结点在e[ ]的下标
这个拉链法的实现方式与哈希表的定义似乎是冲突的 这样会添加重复元素 我觉得最好在添加之前也去判断一下是否存在
这里为什么N定义为100003啊?
不请自来,因为它是大于10万的第一个素数
刚开始的时候,有点不懂,现在懂了,谢谢百忙之中还给回复。
应该的,都是同学,互相帮助
也可以idx初始化为1吧,默认所有的链0为空,这样就不用使用memset了
@[高数],题解真好
请问,如果有重复元素插入了怎么办?
不请自来,这道题是只用查询数x是否出现过,不需要记录重复元素,所以这里就直接覆盖了。
(y总在他的题解下回答过这个问题)
(仔细往下翻)
好的,谢谢啦