理想的查找方法是:对给定的k,不经任何比较便能获取所需的记录,其查找的时间复杂度为常数级O(C)。
这就要求在建立记录表的时候,确定记录的key与其存储地址之间的关系f,即使key与记录的存放地址H相对应:
当要查找key=k的记录时,通过关系f就可得到相应记录的地址而获取记录,从而免去了key的比较过程。
这个关系f就是所谓的Hash函数(或称散列函数、杂凑函数),记为H(key)。
它实际上是一个地址映象函数,其自变量为记录的key,函数值为记录的存储地址(或称Hash地址)。
说人话就是key经过一个运算算出来它的存放位置H。这个key到H的运算或者过程就是哈希函数。
哈希表的查找有很多很多种方法,其中最常用的就是保留除数法,为了避免冲突也就两个数据算完地址是一样的,所以这个Hi=H(key)%m中的m最好是一个质数并且要大一些,但是这也导致了空间的浪费。所以一个差不多的数组就势必会导致有冲突,Hi=(H(key)+di)%m遇到冲突时地址往后加直到遇到空的位置把数据放进去。但是这样会影响查找速度。所以链地址法出现了,把冲突地址用链表放一起,下面用这个方法写程序。
test.c
#include
//#include
#include "hash.h"
int main()
{
hash *HT;
int i,key;
linklist r;
int data[] = {23, 34, 14, 38, 46, 16, 68, 15, 7, 31, 26};
if ((HT = hash_create()) == NULL) {
return -1;
}
for (i = 0; i < sizeof(data)/sizeof(int); i++) {
hash_insert(HT, data[i]);
}
printf("input:");
scanf("%d", &key);
r = hash_search(HT, key);
if (r == NULL)
printf("not found\n");
else
printf("found:%d %d\n", key, r->key);
return 0;
}
hash.c
#include
#include
#include
#include "hash.h"
hash * hash_create()
{
hash *HT;
HT = (hash*)malloc(sizeof(hash));
if(HT == NULL)
{
printf("malloc HT is default");
return NULL;
}
memset(HT, 0, sizeof(hash));
return HT;
}
int hash_insert(hash *HT, datatype key)
{
linklist p, q;
if (HT == NULL) {
printf("HT is NULL\n");
return -1;
}
if ((p = (linklist)malloc(sizeof(listnode))) == NULL) {
printf("malloc failed\n");
return -1;
}
p->key = key;
p->value = key % N;
p->next = NULL;
q = &(HT->data[key % N]);
while (q->next && q->next->key < p->key ) {
q = q->next;
}
p->next = q->next;
q->next = p;
return 0;
}
linklist hash_search(hash *HT, datatype key)
{
linklist p;
if (HT == NULL) {
printf("HT is NULL\n");
return NULL;
}
p = &(HT->data[key % N]);
while (p->next && p->next->key != key) {
p = p->next;
}
if (p->next == NULL) {
return NULL;
} else {
printf("found\n");
return p->next;
}
}
hash.h
#ifndef _HASH_H_
#define _HASH_H_
#define N 15
typedef int datatype;
typedef struct node{
datatype key;
datatype value;
struct node *next;
}listnode,*linklist;
typedef struct {
listnode data[N];
}hash;
hash * hash_create();
int hash_insert(hash *HT,datatype key);
linklist hash_search(hash *HT, datatype key);
#endif