c语言哈希表电子辞典_C语言哈希表uthash的使用方法详解(附下载链接)

本文介绍了C语言中的哈希表库uthash,包括其安装、使用方法以及如何添加、查找和删除元素。uthash通过宏实现,提供常数时间的操作,还支持链表、动态数组和字符串处理。文章提供了详细的示例代码,展示如何在项目中应用uthash创建和管理哈希表。
摘要由CSDN通过智能技术生成

uthash简介

由于C语言本身不存在哈希,但是当需要使用哈希表的时候自己构建哈希会异常复杂。因此,我们可以调用开源的第三方头文件,这只是一个头文件:uthash.h。我们需要做的就是将头文件复制到您的项目中,然后:#include "uthash.h"。由于uthash仅是头文件,因此没有可链接的库代码。

使用uthash添加,查找和删除通常是常数时间的操作,此哈希的目标是简约高效。它大约有1000行C。它会自动内联,因为它是作为宏实现的。

uthash还包括三个额外的头文件,主要提供链表,动态数组和字符串。utlist.h为C结构提供了链接列表宏。utarray.h使用宏实现动态数组。utstring.h实现基本的动态字符串。

github下载链接:https://github.com/troydhanso...

uthash的使用

定义结构体

这里我们将id作为一个索引值,也就是键值,将name作为value。#include "uthash.h"

struct my_struct {

int id; /* key */

char name[10];

UT_hash_handle hh; /* makes this structure hashable */

};

/*声明哈希为NULL指针*/

struct my_struct *users = NULL; /* important! initialize to NULL */

注意:一定要包含UT_hash_handle hh;hh不需要初始化。它可以命名为任何名称,但是我们一般都命名为hh。

添加

HASH_ADD_INT表示添加的键值为int类型

HASH_ADD_STR表示添加的键值为字符串类型

HASH_ADD_PTR表示添加的键值为指针类型

HASH_ADD表示添加的键值可以是任意类型void add_user(int user_id, char *name) {

struct my_struct *s;

/*重复性检查,当把两个相同key值的结构体添加到哈希表中时会报错*/

HASH_FIND_INT(users, &user_id, s); /* id already in the hash? */

/*只有在哈希中不存在ID的情况下,我们才创建该项目并将其添加。否则,我们只修改已经存在的结构。*/

if (s==NULL) {

s = (struct my_struct *)malloc(sizeof *s);

s->id = user_id;

HASH_ADD_INT( users, id, s ); /* id: name of key field */

}

strcpy(s->name, name);

}

HASH_ADD_INT函数中,第一个参数users是哈希表,第二个参数id是键字段的名称。最后一个参数s是指向要添加的结构的指针。

查找struct my_struct *find_user(int user_id) {

struct my_struct *s;

HASH_FIND_INT( users, &user_id, s ); /* s: output pointer */

return s;

}

在上述代码中,第一个参数users是哈希表,第二个参数是user_id的地址(一定要传递地址)。最后s是输出变量。当可以在哈希表中找到相应键值时,s返回给定键的结构,当找不到时s返回NULL。

替换

HASH_REPLACE宏等效于HASH_ADD宏,HASH_REPLACE会尝试查找和删除项目外。如果找到并删除了一个项目,它还将返回该项目的指针作为输出参数。void replace_user(HashHead *head, HashNode *newNode) {

HashNode *oldNode = find_user(*head, newNode->id);

if (oldNode)

HASH_REPLACE_INT(*head, id, newNode, oldNode);

}

删除

要从哈希表中删除结构,必须具有指向它的指针。(如果只有键,请先执行HASH_FIND以获取结构指针)。void delete_user(struct my_struct *user) {

HASH_DEL(users, user); /* user: pointer to deletee */

free(user); /* optional; it's up to you! */

}

同样,这里users是哈希表,user是指向我们要从哈希中删除的结构的指针。

删除结构只是将其从哈希表中删除,并非free 。何时释放结构的选择完全取决于自己;uthash永远不会释放您的结构

循环删除

HASH_ITER是一个宏定义,程序执行时被替换为一个循环。void delete_all() {

struct my_struct *current_user, *tmp;

HASH_ITER(hh, users, current_user, tmp) {

HASH_DEL(users,current_user); /* delete; users advances to next */

free(current_user); /* optional- if you want to free */

}

}

删除哈希表所有元素

如果您只想删除所有项目,但不释放它们或进行每个元素的清理,则可以通过一次操作更有效地做到这一点:HASH_CLEAR(hh,users);

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值