C语言实现哈希表

HashMap.h

#pragma once

#define N 10

typedef char* K;
typedef char* V;

typedef struct node {
	K key;
	V val;
	struct node* next;
} Node;

typedef struct {
	Node* table[N];
} HashMap;

HashMap* hashmap_create();
void hashmap_destroy(HashMap* map);

V hashmap_put(HashMap* map, K key, V val);
V hashmap_get(HashMap* map, K key);
void hashmap_delete(HashMap* map, K key);

HashMap.c

#include "HashMap.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

unsigned int hash(char* str) {
	unsigned int hash = 1315423911;
	while (*str) {
		hash ^= ((hash << 5) + (*str++) + (hash >> 2));
	}
	return (hash & 0x7FFFFFFF);
}

HashMap* hashmap_create() {
	return calloc(1, sizeof(HashMap));
}

void hashmap_destroy(HashMap* map) {
	// free所有结点
	for (int i = 0; i < N; i++) {
		// 遍历每条链表
		Node* curr = map->table[i];
		while (curr != NULL) {
			Node* next = curr->next;
			free(curr);
			curr = next;
		}
	}
	// free HashMap结点
	free(map);
}

// 如果key不存在,则添加(key, val); 
// 如果存在, 则更新键值对, 并返回原来关联的值
V hashmap_put(HashMap* map, K key, V val) {
	int idx = hash(key) % N;
	// 遍历链表
	Node* curr = map->table[idx];
	while (curr != NULL) {
		// 相等
		if (strcmp(curr->key, key) == 0) {
			V retValue = curr->val;
			curr->val = val;
			return retValue;
		}
		// 不相等
		curr = curr->next;
	}
	// 添加结点
	Node* newNode = malloc(sizeof(Node));
	if (newNode == NULL) {
		printf("malloc failed in hashmap_put\n");
		exit(1);
	}
	// 头插法
	newNode->key = key;
	newNode->val = val;
	newNode->next = map->table[idx];
	map->table[idx] = newNode;

	return NULL;
}

V hashmap_get(HashMap* map, K key) {
	int idx = hash(key) % N;
	// 遍历链表
	Node* curr = map->table[idx];
	while (curr != NULL) {
		if (strcmp(curr->key, key) == 0) {
			return curr->val;
		}
		curr = curr->next;
	}
	return NULL;
}

void hashmap_delete(HashMap* map, K key) {
	int idx = hash(key) % N;
	// 遍历链表
	Node* prev = NULL;
	Node* curr = map->table[idx];
	while (curr != NULL) {
		if (strcmp(curr->key, key) == 0) {
			// 删除curr指向的结点
			if (prev == NULL) {
				map->table[idx] = curr->next;
				free(curr);
			}
			else {
				prev->next = curr->next;
				free(curr);
			}
			return;
		}
		prev = curr;
		curr = curr->next;
	}
}

main.c

#include "HashMap.h"
#include <stdlib.h>

int main(void) {
	HashMap* map = hashmap_create(); // 空的HashMap

	hashmap_put(map, "liuqiangdong", "zhangzetian");
	hashmap_put(map, "wangbaoqiang", "marong");
	hashmap_put(map, "jianailiang", "lixiaolu");
	hashmap_put(map, "wenzhang", "mayili");

	// hashmap_put(map, "wangbaoqiang", NULL);
	// hashmap_put(map, "jianailiang", NULL);
	// hashmap_put(map, "wenzhang", NULL);

	// char* str = hashmap_get(map, "wenzhang");
	// puts(str);
	// str = hashmap_get(map, "peanut");
	// puts(str);

	hashmap_delete(map, "liuqiangdong");
	hashmap_delete(map, "peanut");

	hashmap_destroy(map);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
哈希表是一种利用哈希函数进行快速查找的数据结构C语言可以通过数组和指针实现哈希表。 首先需要定义一个哈希函数,将关键字转换成哈希表的位置。可以使用简单的取模运算,将关键字的值除以哈希表大小取余数得到哈希表位置。 例如,哈希表大小为10,关键字为20,则哈希表位置为20%10=2。 接下来,定义一个结构体来表示哈希表中的每个元素,包括关键字和值。 ```c struct hash_element { int key; int value; }; ``` 然后,定义一个哈希表数组,将每个元素插入到哈希表中。如果哈希表位置已经被占用,可以使用链表来解决冲突。 ```c #define HASH_SIZE 10 struct hash_element *hash_table[HASH_SIZE]; void insert(int key, int value) { int index = key % HASH_SIZE; struct hash_element *element = malloc(sizeof(struct hash_element)); element->key = key; element->value = value; if (hash_table[index] == NULL) { hash_table[index] = element; } else { struct hash_element *p = hash_table[index]; while (p->next != NULL) { p = p->next; } p->next = element; } } int search(int key) { int index = key % HASH_SIZE; struct hash_element *p = hash_table[index]; while (p != NULL) { if (p->key == key) { return p->value; } p = p->next; } return -1; } ``` 这里的insert函数将关键字和值封装成一个结构体,然后根据哈希函数计算出哈希表位置。如果该位置为空,直接插入元素;否则,遍历链表直到找到空位置插入。 search函数根据哈希函数计算出哈希表位置,然后遍历链表查找关键字。 以上是一个简单的哈希表实现,可以根据实际需求进行改进。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值