Uthash

本文介绍了哈希表的概念及其在数据查找中的优势,重点讲解了C语言库uthash的使用方法,包括增删查改、计数、排序和迭代等操作。uthash通过宏定义实现,支持不同类型的键值对,适用于快速开发高效的数据结构。此外,还展示了如何通过uthash进行哈希表的排序和元素删除。
摘要由CSDN通过智能技术生成

一、哈希表的概念及作用

  在一般的线性表或者树中,我们所储存的值写它的存储位置的关系是随机的。因此,在查找过程中,需要一系列的与关键字的比较。线性表查找的时间复杂度为O(n)而平衡二叉树的查找的时间复杂度为O(log(n)),时间复杂度较大,而哈希表主要思想是通过将值与其存储位置相关联,来实现快速的随机存储。

二、uthash简介

  uthash是C语言的hash表实现,他以宏定义的方式实现哈希表,不仅加快了运行的速度,而且与关键类型无关的优点。
 包含头文件:uthash.h
uthash支持的操作有:

  • 增删查
  • 计数
  • 排序
  • 选择/查找
  • 迭代

三、uthash基本用法

第一步:包含头文件
#include "uthash.h"
第二步:自定义数据结构

  每个结构体代表一个键值对,并且,每个结构中要有一个UT_hash_handle成员。

struct my_struct {  
	int id; //key
	char name[10];  
	UT_hash_handle hh; /* makes this structure hashable */  
}; 
第三步:定义hash表指针

   定义自定义数据结构的指针,并初始化为NULL

struct my_struct *users = NULL; /* important! initialize to NULL */ 
第四步:进行一般操作
  1. 增加
      使用第三步定义的users指针添加:
 HASH_ADD_INT( users, id, s );//(hash表指针,,新增的结构体成员)
int add_user(int user_id, char *name) {  
	struct my_struct *s;  
	HASH_FIND_INT(users,&user_id,s);//重复性检查
	if(s==NULL){
		s = malloc(sizeof(struct my_struct));  
		s->id = user_id;  
		strcpy(s->name, name);  
		HASH_ADD_INT( users, id, s ); /* id: name of key field */  
	}
} 
  • HASH_ADD_INT表示添加的键值为int类型
  • HASH_ADD_STR表示添加的键值为字符串类型
  • HASH_ADD_PTR表示添加的键值为指针类型
  • HASH_ADD表示添加的键值可以是任意类型
  • HASH_FIND(hh, users, &user_id, sizeof(user_id), tmp); //tmp用于if(tmp!=NULL{}); user_id为键值
  1. 查找
struct my_struct *find_user(int user_id) {  
	struct my_struct *s;  
	HASH_FIND_INT( users, &user_id, s ); /* s: output pointer */  
	return s;  
} 
  1. 删除
void delete_user(struct my_struct *user) {  
	HASH_DEL( users, user); /* user: pointer to delete */  
	free(user); /* optional; it’s up to you! */  
}  

循环删除:

void delete_all() {
	struct my_struct *current_user, *tmp;
	HASH_ITER(hh, users, current_user, tmp) {
		HASH_DEL(users, current_user);
		free(current_user);
	}
}
  1. 计数
unsigned int num_users = HASH_COUNT(users);  
  1. 迭代
void print_users() {  
	struct my_struct *s;  
	for(s=users; s != NULL; s=s->hh.next) {  
		printf("user id %d: name %s/n", s->id, s->name  
	}  
} 
  1. 排序
int name_sort(struct my_struct *a, struct my_struct *b) {  
	return strcmp(a->name,b->name);  
}
int id_sort(struct my_struct *a, struct my_struct *b) {  
	return (a->id - b->id);  
}  
//按照值排序
void sort_by_name() {  
	HASH_SORT(users, name_sort);  //将name_sort函数传入
}  
//按照键排序
void sort_by_id() {  
	HASH_SORT(users, id_sort);  
}  
  1. 替换
      HASH_REPLACE宏等效于HASH_ADD宏,HASH_REPLACE会尝试查找和删除项目外。如果找到并删除了一个项目,它还将返回该项目的指针作为输出参数。
void replace_user(my_struct *head, my_struct *newNode) {
	HashNode *oldNode = find_user(*head, newNode->id);
	if (oldNode)//如果找到id
		HASH_REPLACE_INT(*head, id, newNode, oldNode);
}
  1. 删除哈希表所有元素
      如果只想删除所有项目,但不释放它们或进行每个元素的清理,则可以通过一次操作更有效地做到这一点:
HASH_CLEAR(hh, users);

之后,列表头(此处为users)将设置为NULL。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值