题目
leetcode 705
不使用任何内建的哈希表库设计一个哈希集合(HashSet)。
实现 MyHashSet 类:
- void add(key) 向哈希集合中插入值 key 。
- bool contains(key) 返回哈希集合中是否存在这个值 key 。
- void remove(key) 将给定值 key 从哈希集合中删除。如果哈希集合中没有这个值,什么也不做。
思路
链地址法:我们开辟一个大小为base的数组,数组的每个位置是一个链表。当计算出哈希值之后,就插入到对应位置的链表当中。
base的选择:为了尽可能避免冲突取一个质数769。
代码
头文件 leetcode.h
#include <stdbool.h>
const int base = 769;
typedef struct tagListNode{
int val;
struct tagListNode *next;
} ListNode;
typedef struct {
ListNode *data;
} MyHashSet;
#ifdef __cplusplus
extern "C" {
#endif
MyHashSet* myHashSetCreate();
void myHashSetAdd(MyHashSet* obj, int key);
void myHashSetRemove(MyHashSet* obj, int key);
bool myHashSetContains(MyHashSet* obj, int key);
void myHashSetFree(MyHashSet* obj);
#ifdef __cplusplus
}
#endif
源文件 leetcode.c
#include <stdio.h>
#include "leetcode.h"
#include "string.h"
int hash(int key) {
return key % base;
}
void ListPush(ListNode *head, int x)
{
ListNode *tmp = malloc(sizeof(ListNode));
tmp->val = x;
tmp->next = head->next;
head->next = tmp;
}
void ListDelete(ListNode *head, int x)
{
for (ListNode *it = head; it->next; it = it->next) {
if (it->next->val == x) {
ListNode *tmp = it->next;
it->next = tmp->next;
free(tmp);
break;
}
}
}
bool ListContains(ListNode *head, int x)
{
for (ListNode *it = head; it->next; it = it->next) {
if (it->next->val == x) {
return true;
}
}
return false;
}
void ListFree(ListNode *head)
{
while (head->next) {
ListNode *tmp = head->next;
head->next = tmp->next;
free(tmp);
}
}
MyHashSet *myHashSetCreate()
{
MyHashSet *ret = malloc(sizeof(MyHashSet));
ret->data = malloc(sizeof(ListNode) * base);
for (int i = 0; i < base; i++) {
ret->data[i].val = 0;
ret->data[i].next = NULL;
}
return ret;
}
void myHashSetAdd(MyHashSet* obj, int key)
{
int h = hash(key);
if (!ListContains(&(obj->data[h]), key)) {
ListPush(&(obj->data[h]), key);
}
}
void myHashSetRemove(MyHashSet* obj, int key)
{
int h = hash(key);
ListDelete(&(obj->data[h]), key);
}
bool myHashSetContains(MyHashSet* obj, int key)
{
int h = hash(key);
return ListContains(&(obj->data[h]), key);
}
void myHashSetFree(MyHashSet* obj)
{
for (int i = 0; i < base; i++) {
ListFree(&(obj->data[i]));
}
free(obj->data);
}