数组实现哈希表只需要两个操作,一个是插入,一个是寻找。一般而言删除用的不多。
插入(O(1))
const int N=100010;
//这里用到了 用数组实现单链表,哈希表可以看做数组加上多个链表。 (邻接表)
int h[N]; // h[]是hash函数实现的一维数组,存的是[0,N)的范围,
int ne[N]; // 存储插入节点的下一个节点(头插法)
int e[N]; // 存储插入的节点的值
int idx; // 给每一个插入的节点编号
void insert(int x){
e[idx]=x; // Node*temp=new Node(x);
int k=(x%N+N)%N; // 找到哈希对应的下标
ne[idx]=h[k]; // temp->next=h[k]; h[k]当做个节点
h[k]=idx++; // h[k]=temp;
}
删除操作 (近似为O(1))
bool find(int x){
int k=(x%N+N)%N; // 找到hash对用的下标
// 从h[k]这个节点遍历,直到遍历到这个链表的末尾
for(int i=h[k];i!=-1;i=ne[i]){ // for(auto temp=h[k];temp;temp=temp->next){
if(x==e[i]){ // if(temp->val==x) return true;
return true; // }
// return false;
}
}
return false;
}
问题
-
为什么hash对用下标使用
k=(x%N+N)%N
?
x有正负,虽然在数学上x%N
为非负数,但是在C++中,x%N
是有正负的,若直接使用x%N在当做数组的下标会报错,因为需要把x%N+N
在对N
取模 -
为什么
h[]
数组需要初始化为-1
这里不初始化为0是因为有可能h[]
有可能取到0,这里h[]
可初始化为一个取不到的数,这里选用了-1