哈希表
哈希表有点像我们上学的时候按学号分小组,通过这种方式老师可以很轻松的下达任务,或者很快的发现谁没交作业(一个班的作业很难一眼看出少了几本,但是一个组就那么几本作业,少了一两本一眼就看出来了)。
如图将24人分成6组
这种编号的方式就是高效的散列,我们俗称“哈希”!
以上过程是通过把关键码值 key(编号)映射到表中一个位置(数组的下标)来访问记录,以加 快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
哈希链表的算法实现
哈希链表数据结构的定义
#define DEFAULT_SIZE 16
typedef struct _ListNode {
struct _ListNode *next;
int key;
void *data;
}ListNode;
typedef ListNode *List;
typedef ListNode *Element;
typedef struct _HashTable {
int TableSize;
List *Thelists;
}HashTable;
哈希函数
/*根据 key 计算索引,定位 Hash 桶的位置*/
int Hash(int key, int TableSize) {
return (key%TableSize);
}
哈希链表初始化
/*初始化哈希表*/
HashTable *InitHash(int TableSize) {
int i = 0;
HashTable *hTable = NULL;
if (TableSize <= 0) {
TableSize = DEFAULT_SIZE;
}
hTable = (HashTable *)malloc(sizeof(HashTable));
if (NULL == hTable) {
printf("HashTable malloc error.\n");
return NULL;
}
hTable->TableSize = TableSize;
//为 Hash 桶分配内存空间,其为一个指针数组
hTable->Thelists = (List *)malloc(sizeof(List)*TableSize);
if (NULL == hTable->Thelists) {
printf("HashTable malloc error\n");
free(hTable);
return NULL;
}
//为 Hash 桶对应的指针数组初始化链表节点
for (i = 0; i < TableSize; i++) {
hTable->Thelists[i] = (ListNode *)malloc(sizeof(ListNode));
if (NULL == hTable->Thelists[i]) {
printf("HashTable malloc error\n");
free(hTable->Thelists);
free(hTable);
return NULL;
}else {
memset(hTable->Thelists[i], 0, sizeof(ListNode));
}
}
return hTable;
}
哈希链表查找元素
/*从哈希表中根据键值查找元素*/
Element Find(HashTable *HashTable, int key) {
int i = 0;
List L = NULL;
Element e = NULL;
i = Hash(key, HashTable->TableSize);
L = HashTable->Thelists[i];
e = L->next;
while (e != NULL && e->key != key)
e = e->next;
return e;
}
哈希链表插入元素
/*哈希表插入元素,元素为键值对*/
void Insert(HashTable *HashTable, int key, void *value ){
Element e=NULL, tmp=NULL;
List L=NULL;
e = Find(HashTable, key);
if (NULL == e) {
tmp = (Element)malloc(sizeof(ListNode));
if (NULL == tmp) {
printf("malloc error\n");
return;
}
L = HashTable->Thelists[Hash(key, HashTable->TableSize)];
tmp->data = value;
tmp->key = key;
tmp->next = L->next;
L->next = tmp;
}else
printf("the key already exist\n");
}
哈希链表删除元素
/*哈希表删除元素,元素为键值对*/
void Delete(HashTable *HashTable, int key ) {
Element e=NULL, last=NULL;
List L=NULL;
int i = Hash(key, HashTable->TableSize);
L = HashTable->Thelists[i];
last = L;
e = L->next;
while (e != NULL && e->key != key){
last = e;
e = e->next;
}
if(e){//如果键值对存在
last->next = e->next;
delete(e);
}
}