哈希表用来插入数据,查找数据
基本操作也就是插入和查找
空间复杂度O(n),时间复杂度可看为线性复杂度O(n)
std::map使用红黑树的结构,插入查找O(log(n))的时间复杂度
不知道acm让不让用hash_map头文件
我猜不行吧,不然为啥要手写哈希表呢
模板
这里为了方便,写成了结构的形式,一般就不用写结构了
const int hashSize=int(4e5), idxSize=int(1.6e7);
struct Node{
int value, next, data;
Node(int value=0, int next=0, int data=0):
value(value),next(next),data(data) {}
}node[idxSize];
int head[hashSize];
struct Hash{
int size;
Hash(void):size(0) {
memset(head, -1, sizeof(head));
}
int hash(int num){
return (num+hashSize)%hashSize;
}
int find(int num){
int key=hash(num);
for (int i=head[key]; i!=-1; i=node[i].next)
if (node[i].value==num) return node[i].data;
return 0;
}
int insert(int num){
int key=hash(num), exist=false;
for (int i=head[key]; i!=-1; i=node[i].next)
if (node[i].value==num) return ++node[i].data;
node[size].value=num; node[size].data=1;
node[size].next=head[key];
head[key]=size++;
return 1;
}
};
可以看到上面写的模版十分垃圾
常数大,不支持解引用,代码冗长
我们写下面的模版,注意有些对hash表要求高的问题会出现问题
struct HashMap{
static const int mask=0x7fffff;
int q[mask+1], p[mask+1];
void clear() {memset(q, 0, sizeof(q));}
int& operator [](int k){
int i;
for (i=k&mask; q[i]&&p[i]!=k; i=(i+1)&mask);
p[i]=k; return q[i];
}
}hash;
// hash.clear();
// hash[Key]=Value;
注意
- 需要初始化head[]为-1,size为0
- 下面的模版注意mask常数,这是用来映射负数的,同时规定了hash表的大小
例题
哈希表暂时没什么精彩的题目,就当作示例吧
POJ-2785 Values whose Sum is 0 Hash表
Update: 更新模版