#include <stdio.h>
#include <stdlib.h>
#include <string.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);
int main(int argc, const char *argv[])
{
hash * HT;
int data[] = {23, 34, 14, 38, 46, 16, 68, 15, 7, 31, 26};
int i;
int key;
linklist r;
printf("hash[15] = %ld\n", sizeof(hash));
printf("hash = %ld\n", sizeof(listnode));
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->value);
return 0;
}
hash * hash_create() {
hash * HT;
printf("HT = %ld\n", sizeof(HT));
if ((HT = (hash *)malloc(sizeof(hash))) == NULL) {
printf("malloc failed\n");
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;
}
}
运行结果:
嵌入式技术公开课的哈希查找(线性探测法),比较好理解
#include <stdio.h>
#define SIZE 12
#define M 15
int hash(int key);
int insert_hashtable(int HT[], int key);
int line_detect(int HT[], int H0, int key);
void show_hashtable(int HT[], int m);
int search_hashtable(int HT[], int key);
int main(void)
{
int num, result;
int arr[SIZE] = {14, 36, 42, 38, 40, 15, 19, 12, 51, 65, 34, 25};
int HT[M] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
for(int i = 0; i < SIZE; i++)
{
if(!insert_hashtable(HT, arr[i]))
{
printf("Failed to create Hash Table.\n");
return 0;
}
}
printf("Show Hash Table:\n");
show_hashtable(HT, M);
printf("Please enter a number you want to find in Hash Table:\n");
scanf("%d", &num);
result = search_hashtable(HT, num);
if(result != -1)
printf("Find %d int position %d.\n", num, result);
else
printf("Cannot find %d in Hash Table.\n", num);
return 0;
}
int insert_hashtable(int HT[], int key)
{
int index = hash(key);
int Hi = -1;
if(HT[index] == -1) /* 我们通过index找到里面的key, 如果等于-1,则里面没存,我们把key存进去 */
{
HT[index] = key;
return 1;
}
else /* 里面不是-1,则冲突了 */
{
Hi = line_detect(HT, index, key); /* 解决冲突问题 */
if(Hi != -1)
{
HT[Hi] = key;
return 1;
}
}
return 0;
}
/* 通过哈希函得到我们的存储数据的位置index */
int hash(int key)
{
return key % 13; /* 为啥是%13, 不大于M的最大质数,我们M为15,上面写了 */
}
/* 线性探测法解决冲突问题 */
int line_detect(int HT[], int H0, int key)
{
int Hi;
for(int di = 1; di <= M; di++)
{
/* (key + di) % M 除M取余,而不是除质数取余 */
Hi = (H0 + di) % M;
if(HT[Hi] == -1) /* 解决冲突问题 */
return Hi;
else if(HT[Hi] == key) /* 为了查找的时候找到位置 */
return Hi;
}
return -1;
}
void show_hashtable(int HT[], int m)
{
for(int i = 0; i < m; i++)
printf("%d\t", HT[i]);
printf("\n");
}
int search_hashtable(int HT[], int key)
{
int H0 = hash(key);
int Hi;
if(HT[H0] == -1)
return -1;
else if(HT[H0] == key)
return H0;
else
{
Hi = line_detect(HT, H0, key); /* 线性探测法,解决冲突问题 */
if(HT[Hi] == key)
return Hi;
else
return -1;
}
}
运行结果:
链式哈希的引入?
你们不是都喜欢同一个位置,那就把你们串起来,存在同一个位置。
#include <stdio.h>
#include <stdlib.h>
#define SIZE 12
#define M 15
struct node
{
unsigned int elem;
struct node *next;
};
void insert_hashtable(struct node *HT[], int key);
int hash(int key);
void show_hashtable(struct node *HT[], int m);
int search_hashtable(struct node *HT[], int key);
int main(void)
{
int num, result;
int arr[SIZE] = {14, 36, 42, 38, 40, 15, 19, 12, 51, 65, 34, 25};
struct node *HT[M] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
for(int i = 0; i < SIZE; i++)
{
insert_hashtable(HT, arr[i]);
}
printf("Show Hash Table:\n");
show_hashtable(HT, M);
printf("Please enter a number you want to find in Hash Table:\n");
scanf("%d", &num);
result = search_hashtable(HT, num);
if(result == 1)
printf("Find %d in Link Hash Table.\n", num);
else
printf("Cannot find %d in Link Hash Table.\n", num);
return 0;
}
void insert_hashtable(struct node *HT[], int key)
{
int index = hash(key);
struct node *p = (struct node *)malloc(sizeof(struct node));
p->elem = key;
p->next = HT[index];
HT[index] = p;
}
int hash(int key)
{
return key % 13;
}
void show_hashtable(struct node *HT[], int m)
{
struct node *p;
for(int i = 0; i < m; i++)
{
printf("Hash Table index %d has: ", i);
for(p = HT[i]; p != NULL; p = p->next)
printf("%d ", p->elem);
printf("\n");
}
}
int search_hashtable(struct node *HT[], int key)
{
struct node *p;
int index = hash(key);
for(p = HT[index]; p != NULL; p = p->next)
{
if(p->elem == key)
return 1;
}
return 0;
}
运行结果: