C语言哈希表

 

#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;
}

运行结果:

哈希表是一种高效的数据结构,它可以在常数时间内完成插入、删除和查找操作。下面是一个简单的C语言哈希表代码和讲解: 代码: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include "uthash.h" struct hashTable { int key; int val; UT_hash_handle hh; }; struct hashTable *hashTable = NULL; void insert(int key, int val) { struct hashTable *s; HASH_FIND_INT(hashTable, &key, s); if (s == NULL) { s = (struct hashTable*)malloc(sizeof(struct hashTable)); s->key = key; HASH_ADD_INT(hashTable, key, s); } s->val = val; } int find(int key) { struct hashTable *s; HASH_FIND_INT(hashTable, &key, s); if (s == NULL) { return -1; } return s->val; } void delete(int key) { struct hashTable *s; HASH_FIND_INT(hashTable, &key, s); if (s != NULL) { HASH_DEL(hashTable, s); free(s); } } void printHashTable() { struct hashTable *s; for (s = hashTable; s != NULL; s = (struct hashTable*)(s->hh.next)) { printf("key:%d, val:%d\n", s->key, s->val); } } int main() { insert(1, 10); insert(2, 20); insert(3, 30); insert(4, 40); printf("find key 1, val:%d\n", find(1)); printf("find key 5, val:%d\n", find(5)); delete(3); printHashTable(); return 0; } ``` 讲解: 1. 首先定义了一个结构体`struct hashTable`,它包含了键`key`和值`val`,以及一个`UT_hash_handle`类型的指针`hh`,这是一个用于哈希表操作的结构体。 2. 在`main`函数中,我们调用`insert`函数向哈希表中插入数据,调用`find`函数查找数据,调用`delete`函数删除数据,最后调用`printHashTable`函数打印哈希表中的所有数据。 3. `insert`函数首先调用`HASH_FIND_INT`宏查找哈希表中是否已经存在该键,如果不存在,则动态分配一个`struct hashTable`类型的结构体,并将键和结构体添加到哈希表中。 4. `find`函数同样调用`HASH_FIND_INT`宏查找哈希表中是否存在该键,如果存在,则返回对应的值,否则返回-1。 5. `delete`函数调用`HASH_FIND_INT`宏查找哈希表中是否存在该键,如果存在,则调用`HASH_DEL`宏删除该键和对应的结构体,并释放内存。 6. `printHashTable`函数遍历哈希表中的所有数据,并打印出键和值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值