学习于:https://www.bilibili.com/video/BV1sL4y1e7hU?p=2&share_source=copy_pc
#include<assert.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
//用于存放哈希表中各个元素的节点
//其中key是节点的键,data指向的是节点所持有的数据
//next指向该节点的下一个节点
typedef struct listnode
{
struct listnode* next;
int key;
void* data;
}listnode_t;
//用于存放哈希表各个哈希桶首元素的链表,list是一个指针类型
typedef listnode_t* list;
//用于存放各个哈希桶元素
typedef listnode_t* element;
//哈希表,包括该哈希表哈希桶的数目以及哈希桶链表的首节点
typedef struct hashtable {
unsigned int tablesize;
list* thelists; //注意这里是一个二维链表,listnode_t ** 第一维指向的是哈希桶链表,该链表无有效数据,只是为了索引和哈希分类,第二维指向的是哈希桶中所包含元素的链表
}hashtable_t;
//哈希函数,通过键值找到对应哈希桶的下标,也就是找到所属的哈希桶
int hashfunc(int key, int tablesize)
{
assert(key >= 0);
return (key % tablesize);
}
//哈希表初始化
hashtable_t* inithash(int size)
{
int i = 0;
hashtable_t* htable = NULL;
assert(size);
htable = (hashtable_t*)malloc(sizeof(hashtable_t));
if (NULL == htable)
{
printf("malloc fail \n");
return NULL;
}
htable->tablesize = size;
htable->thelists = (list*)malloc(sizeof(list) * size);
if (NULL == htable->tablesize)
{
printf("malloc fail2");
free(htable);
return NULL;
}
for (i = 0; i < size; i++)
{
htable->thelists[i] = (listnode_t*)malloc(sizeof(listnode_t));
if(NULL == htable->thelists){
free(htable->thelists);
free(htable);
return NULL;
}
else {
memset(htable->thelists[i],0,sizeof(listnode_t));
}
}
return htable;
}
//通过键值寻找其在哈希桶中的元素
element hash_find(hashtable_t* hashtable, int key)
{
int i = 0;
list L = NULL;
element e = NULL;
i = hashfunc(key, hashtable->tablesize);
L = hashtable->thelists[i];
e = L->next;
while (e != NULL && e->key != key)
{
e = e->next;
}
return e;
}
//通过键和值将该元素插入哈希表中
void hash_insert(hashtable_t* hashtable, int key, void* value)
{
element e = NULL, temp = NULL;
list L = NULL;
e = hash_find(hashtable, key);
if (NULL == e)
{
temp = (element)malloc(sizeof(listnode_t));
if (NULL == temp)
{
printf("malloc fail 3\n");
return;
}
L = hashtable->thelists[hashfunc(key, hashtable->tablesize)];
temp->data = value;
temp->key = key;
temp->next = L->next;
L->next = temp;
}
else {
printf("key already exist\n");
}
}
//删除某一键值对应的元素
void hash_delete(hashtable* hashtable, int key)
{
element e = NULL, last = NULL;
list L = NULL;
int i = hashfunc(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;
free(e);
}
}
//销毁整个哈希表,释放申请的内存
void hash_destory(hashtable_t* hashtable)
{
int i = 0;
list L = NULL;
element cur = NULL, next = NULL;
for (i = 0; i < hashtable->tablesize; i++)
{
L = hashtable->thelists[i];
cur = L->next;
while (cur != NULL)
{
next = cur->next;
free(cur);
cur = next;
}
free(L);
}
free(hashtable->thelists);
free(hashtable);
}
//获取哈希表中某元素对应的data
void* hash_get(element e)
{
return e ? e->data : NULL;
}
//定义了一个哈希元素所保存的data
typedef struct student{
int index;
const char* name;
int age;
bool isman;
}student_t;
//主函数实现
int main(void)
{
student_t p1 = {1, "bryan",19,true };
student_t p2 = {2, "jason",20,true };
student_t p3 = {3, "rose",19,true };
student_t* elems[] = {&p1,&p2,&p3};
hashtable_t* whash=NULL;
whash = inithash(31);
hash_insert(whash, elems[0]->index, elems[0]);
hash_insert(whash, elems[1]->index, elems[1]);
hash_insert(whash, elems[2]->index, elems[2]);
hash_delete(whash,1);
for (int i = 0; i < 4; i++)
{
element e = hash_find(whash,i);
if (e)
{
student_t* get = (student_t*)hash_get(e);
printf("find name:%s, age:%d, isman?:%d \n",get->name,get->age,get->isman);
}
else {
printf("not find\n");
}
}
system("pause");
}