uthash哈希库使用详解(增删改查和遍历,示例代码)

C语言中,标准库并没有提供哈希表的实现,因此很多开发者需要自己实现哈希表,这通常是一个复杂且容易出错的过程。幸运的是,有像uthash这样的开源库可以帮助我们简化这一过程。本文将对uthash的使用进行详尽的讲解,包括增加、删除、查找、遍历、计算哈希元素个数以及哈希元素排序等操作。

哈希表是一种常用的数据结构,它提供了快速的插入、查找和删除操作,使得在大量数据中进行高效的检索成为可能。在C语言中,使用uthash库可以轻松地实现哈希表,本文将介绍uthash库的用法、原理和一些示例。

哈希库头文件下载

首先,如果你还没有uthash的头文件,可以通过以下链接下载:

  • 链接:夸克网盘分享
  • 私有仓库记录:https://gitee.com/kiss_plasma/mycode/tree/master/2.utHash(c%E8%AF%AD%E8%A8%80%E4%BE%8B%E7%A8%8B)

什么是uthash库?

uthash库是一个在C语言中实现的轻量级哈希表库,它提供了高效的哈希表数据结构和简单易用的API,能够快速地将对象插入到哈希表中,并支持快速的查找、删除等操作。uthash库的特点包括:

  • 简单易用:uthash库提供了简洁的API,使用方便。
  • 高效性能:底层实现采用了高效的哈希算法和数据结构,能够在大量数据中快速进行操作。
  • 灵活性:可以轻松地在任何C语言项目中使用,而无需额外的依赖。

原理

uthash库的原理是基于开放地址哈希表实现的。它采用了MurmurHash算法来生成哈希值,并使用线性探测法解决哈希冲突。在插入元素时,它会计算元素的哈希值,并根据哈希值找到对应的槽位,如果槽位已经被占用,就会线性探测直到找到空闲的槽位为止。在查找元素时,它会根据元素的哈希值找到对应的槽位,然后在该槽位以及之后的槽位中查找目标元素,直到找到或者遇到空槽为止。

示例应用

uthash库可以用于各种场景,例如:

  • 缓存:将数据存储在哈希表中,以快速访问。
  • 符号表:在编译器中用于存储变量、函数等符号信息。
  • 数据库索引:在数据库系统中用于加速查询操作。

哈希表基础 

哈希表结构体

在uthash中,哈希表的每个元素都是一个结构体,通常包含以下几个部分:

  • key:哈希表的键。

  • value:与键相关联的值。

  • UT_hash_handle hh:一个内部使用的句柄,用于uthash内部的内存管理,用户不需要手动赋值。

增加元素

uthash提供了多种增加元素的宏,根据键的类型不同,可以分为:

  1. HASH_ADD_INT:键为整数类型。

  2. HASH_ADD_STR:键为字符串类型。

  3. HASH_ADD_PTR:键为指针类型。

  4. HASH_ADD:键为任意类型。

HASH_ADD_INT为例,其使用方式如下:

HASH_ADD_INT(hash, key, item);
  • hash:哈希表。

  • key:键的字段名。

  • item:指向要添加元素的指针。

在添加之前,uthash会使用HASH_FIND_INT检查键是否已存在,以避免重复。

查找元素

查找操作与增加操作类似,也根据键的类型有不同的宏:

  • HASH_FIND_INT:查找整数键。

  • HASH_FIND_STR:查找字符串键。

  • HASH_FIND_PTR:查找指针键。

使用方式如下:

HASH_FIND_INT(hash, key, item);

如果找到,item将指向对应的元素;如果没有找到,item将为NULL

删除元素

删除操作需要传入要删除元素的地址:

HASH_DEL(hash, item);

这里的item是指向要删除元素的指针。

排序

uthash允许对哈希表中的元素进行排序,使用HASH_SORT宏:

HASH_SORT(hash, compare_function);

这里的compare_function是一个比较函数,其工作原理与qsort的标准比较函数类似。

遍历

使用普通的for循环可以遍历哈希表中的所有元素:

for (item = hash; item != NULL; item = item->hh.next) {// 处理item
}

循环删除

uthash提供了HASH_ITER宏,可以方便地在循环中删除元素:

HASH_ITER(hh, hash, item, tmp) {// 在这里处理item// 删除操作
}

这里的hh是一个句柄,hash是哈希表,itemtmp是用于遍历的指针。

计算哈希表元素个数

uthash还提供了一个简单的宏来计算哈希表中的元素个数:

size_t num_items = HASH_COUNT(hash);

使用uthash库

使用uthash库非常简单,只需要将uthash.h头文件包含到你的项目中,并定义一个结构体,其中包含一个UTHASH的宏。下面是一个简单的例子:

#include <stdio.h>
#include <stdlib.h>
#include "uthash.h"// 定义一个结构体
typedef struct {int id;char name[20];UT_hash_handle hh; // 用于指示哈希表中的链接字段
} User;User *users = NULL;int main() {// 创建并插入元素User *user = (User*)malloc(sizeof(User));user->id = 1;strcpy(user->name, "John");HASH_ADD_INT(users, id, user);// 查找元素User *found_user;int search_id = 1;HASH_FIND_INT(users, &search_id, found_user);if (found_user != NULL) {printf("Found user with ID %d: %s\n", found_user->id, found_user->name);} else {printf("User with ID %d not found\n", search_id);}// 删除元素HASH_DEL(users, found_user);free(found_user);return 0;
}

在这个示例中,我们定义了一个User结构体,并使用UTHASH的宏UT_hash_handle定义了哈希表中的链接字段。然后,我们可以使用HASH_ADD_INTHASH_FIND_INT等宏来插入和查找元素。 

结语

uthash是一个功能强大的哈希库,可以帮助C语言开发者轻松实现哈希表的各种操作。本文提供了uthash的基本使用教程,希望对你有所帮助。如果你有任何疑问或建议,欢迎提出。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/2210.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

国内首个48小时大模型极限挑战赛落幕,四位“天才程序员”共同夺冠

4月21日晚&#xff0c;第四届ATEC科技精英赛&#xff08;ATEC2023&#xff09;线下赛落幕。本届赛事以大模型为技术基座&#xff0c;围绕“科技助老”命题&#xff0c;是国内首个基于真实场景的大模型全链路应用竞赛。ATEC2023线下赛采用48小时极限挑战的形式&#xff0c;来自东…

【Linux开发 第十一篇】rpm和yum

rpm rpm用于互联网下载包的打包及安装工具&#xff0c;它包含在某些Linux分发版中&#xff0c;就是一种Linux中软件包的管理工具 rpm包指令 rpm -qa&#xff1a;查询所安装的所有的rpm软件包 rpm -qa | more rom -qa | grep X rpm -q 软件包名:查询软件包是否安装 rpm -qi 软…

2024年最新版云开发cms开通步骤,开始开发微信小程序前的准备工作,认真看完奥!

小程序官方有改版了&#xff0c;搞得石头哥不得不紧急的再新出一版&#xff0c;教大家开通最新版的cms网页管理后台 一&#xff0c;技术选型和技术点 1&#xff0c;小程序前端 wxml css JavaScript MINA原生小程序框架 2&#xff0c;数据库 云开发 云数据库 云…

一般转行嵌入式应该怎么做?

转行嵌入式可以考虑以下方向&#xff1a; 嵌入式软件开发&#xff1a;包括嵌入式操作系统的开发、应用软件开发等。 嵌入式硬件设计&#xff1a;涉及电路设计、微处理器应用等。 物联网应用开发&#xff1a;利用嵌入式技术实现物联网设备的连接、控制和数据处理。 华清远见的…

options表的service

目录 1、 * options表的service 1.1、 insertOption 1.2、 saveOptions 1.3、 getOptions package com.my.blog.website.service.impl; import com.my.blog.website.dao.OptionVoMapper;

Mysql优化之分区分表

为什么要分区分表 分区和分表是两种用于优化大型数据集查询性能的技术&#xff0c;它们有不同的应用场景和优势。随着数据库数据越来越大&#xff0c;单个表中数据太多。以至于查询速度变慢&#xff0c;而且由于表的锁机制导致应用操作也受到严重影响&#xff0c;就出现了数据…

springboot 批量下载文件, zip压缩下载

一、使用hutool 工具类 效果&#xff1a;下载速度可以 1、依赖&#xff1a;hutool <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.26</version> </dependency>2、调用方式 im…

Android Studio开发工具学习之Git分支操作

这里写目录标题 2.1 查看、创建本地分支2.1.1 命令行查看与创建2.1.2 Git窗口查看与创建 2.2 切换分支&#xff1a;Checkout2.3.1 通过命令行切换 2.3.2 通过Git窗口切换 2.3 合并分支&#xff1a;Merge2.3.1 操作command_new、gui-new分支2.3.1 通过命令行将gui-new分支合并至…

Day35代码随想录贪心part04:860.柠檬水找零、406.根据身高重建队列、452. 用最少数量的箭引爆气球

Day35 贪心part04 860.柠檬水找零 leetcode题目链接&#xff1a;860. 柠檬水找零 - 力扣&#xff08;LeetCode&#xff09; **复习一下dict的语法&#xff1a;**wallet[i] wallet.get(i, 0)1 本题一开始尝试用逐层判断去做&#xff0c;但这样好像并不合理 思路&#xff1…

深度学习网络训练,Loss出现Nan的解决办法

文章目录 前言 一、原因 二、典型实例 1. 梯度爆炸 2. 不当的损失函数 3. 不当的输入 前言 模型的训练不是单纯的调参&#xff0c;重要的是能针对出现的各种问题提出正确的解决方案。本文就训练网络loss出现Nan的原因做了具体分析&#xff0c;并给出了详细的解决方案&#xff…

LT8711UXD助力新款Swtich游戏机底座《4K/60HZ投屏方案》

Nintendo Switch&#xff08;OLED版&#xff09;正面搭载了一块分辨率为720P的7.0英寸OLED屏幕&#xff1b;具有白色和电光蓝电光红2种颜色&#xff1b;机身长度102毫米&#xff0c;宽度242毫米&#xff0c;厚度13.9毫米&#xff0c;重量约420克。 [2]Nintendo Switch&#xff…

举个栗子!Tableau 技巧(271):同时筛选不同年份的 TopN 数据

零售企业的销售数据分析中&#xff0c;经常用排序来查看过去一年或者几年的数据 TopN 情况。如果可以在同一视图中&#xff0c;呈现很多年的数据排名&#xff0c;且通过筛选能灵活调整 TopN 的 N 值&#xff0c;岂不是更方便&#xff1f; 如下示例&#xff1a;图表呈现了各品牌…

centos7上搭建mongodb数据库

1.添加MongoDB的YUM仓库&#xff1a; 打开终端&#xff0c;执行以下命令来添加MongoDB的YUM仓库&#xff1a; sudo vi /etc/yum.repos.d/mongodb-org-4.4.repo 在打开的文件中&#xff0c;输入以下内容&#xff1a; [mongodb-org-4.4] nameMongoDB Repository baseurlh…

【sping】在logback-spring.xml 获取项目名称

在日志文件中我们想根据spring.application.name 创建出的文件夹。 也不想死在XML文件中。 application.yml spring:application:name: my-demo logback-spring.xml <springProperty name"application_name" scope"context" source"spring.app…

如何用微信小程序实现远程控制无人售货柜

如何用微信小程序实现远程控制无人售货柜呢&#xff1f; 本文描述了使用微信小程序调用HTTP接口&#xff0c;实现控制无人售货柜&#xff0c;独立控制售货柜、格子柜的柜门。 可选用产品&#xff1a;可根据实际场景需求&#xff0c;选择对应的规格 序号设备名称厂商1智能WiFi…

Java基础:设计模式之简单工厂模式

简单工厂模式是一种创建型设计模式&#xff0c;它通过一个专门的类&#xff08;即工厂类&#xff09;负责创建对象&#xff0c;从而将对象的创建过程与客户端代码解耦。简单工厂模式的核心在于提供一个统一的入口&#xff0c;接收外界请求并根据请求参数返回相应的对象实例&…

Linux系统上C++使用alsa库播放声音文件

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、命令行1.ffmpeg2.aplay 二、代码实现总结 前言 平常读麦克风的场景居多&#xff0c;有时候也需要播放一个声音文件&#xff0c;这里就介绍怎么处理。 一、…

自动驾驶光学校准反射板

光学校准反射板是一种用于光学系统校准的重要工具。它以其高反射率和精确的几何特性&#xff0c;为光学仪器、光学系统和光学元件的校准提供了可靠的参考。在现代光学领域&#xff0c;光学校准反射板的应用已经深入到各个领域&#xff0c;从科学研究到工业生产&#xff0c;都离…

# IDEA2019 如何打开 Run Dashboard 运行仪表面板

IDEA2019 如何打开 Run Dashboard 运行仪表面板 段子手168 1、依次点击 IDEA 上面工具栏 —> 【View】 视图。 —> 【Tool Windows】 工具。 —> 【Run Dashboard】 运行仪表面板。 2、如果 【Tool Windows 】工具包 没有 【Run Dashboard】 运行仪表面板 项 依次…

慈航医疗“五进”实践活动第九场:范庄村爱心义诊,村民健康有“医”靠

为落实推进“健康中国”战略&#xff0c;提升居民健康意识和预防疾病能力&#xff0c;4月18日&#xff0c;慈航医疗健康前往范庄村开展健康义诊活动&#xff0c;为100余位村民送上了一份暖心的公益关爱。 义诊当天&#xff0c;在志愿服务队队员的引领下&#xff0c;慈航医疗健康…