一、 uthash概述
uthash是一个用c语言编写的开源库,使用宏实现了哈希表的增删改查等功能 github地址https://github.com/troydhanson/uthash 官方文档http://troydhanson.github.io/uthash/userguide.html leetcode c编译器支持uthash —2019年4月8日更新----
二、 uthash使用
初始化
uthash需要用户定义自己的数据结构,一个包含UT_hash_handle hh的结构体 还需要定义键和值(可选),这里将id作为key, name作为value struct my_struct {
int id;
char name[ 10 ] ;
UT_hash_handle hh;
} ;
typedef struct my_struct HashNode;
typedef struct my_struct * HashHead;
添加
向hashtable中添加数据 key是int,可以使用 HASH_ADD_INT key是字符串,可以使用 HASH_ADD_STR key是指针,可以使用 HASH_ADD_PTR 其它,可以使用 HASH_ADD,上述实际都是调用这个方法,不过简化了参数 void hashTabel_add ( HashHead * head, HashNode * users) {
if ( ! find_user ( * head, users-> id) )
HASH_ADD_INT ( * head, id, users) ;
}
#define HASH_ADD_INT(head,intfield,add) \
HASH_ADD(hh,head,intfield,sizeof(int),add)
#define HASH_ADD(hh,head,fieldname,keylen_in,add) \
HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add)
替换
与添加差不多,会在添加前,删除key相同的节点,再添加新的节点 如果key是int,可以使用 HASH_REPLACE_INT void replace_user ( HashHead * head, HashNode * newNode) {
HashNode * oldNode = find_user ( * head, newNode-> id) ;
if ( oldNode)
HASH_REPLACE_INT ( * head, id, newNode, oldNode) ;
}
查找
根据key查找节点 如果key是int,可以使用 HASH_FIND_INT HashNode * find_user ( HashHead head, int user_id) {
HashNode * s;
HASH_FIND_INT ( head, & user_id, s) ;
return s;
}
删除
void delete_user ( HashHead * head, HashNode * user) {
if ( user) {
HASH_DEL ( * head, user) ;
free ( user) ;
}
}
计数
int count_user ( HashHead head) {
return HASH_COUNT ( head) ;
}
遍历
void print_user ( HashHead head) {
HashNode * s;
printf ( "size is %d\n" , count_user ( head) ) ;
for ( s = head; s != NULL ; s = s-> hh. next) {
printf ( "user id %d, name %s\n" , s-> id, s-> name) ;
}
}
void print_user_iterator ( HashHead head) {
HashNode * s, * tmp;
printf ( "size is %d\n" , count_user ( head) ) ;
HASH_ITER ( hh, head, s, tmp) {
printf ( "user id %d: name %s\n" , s-> id, s-> name) ;
}
}
排序
给节点排序,可以根据key或者value 使用 HASH_SORT int name_sort ( HashNode * a, HashNode * b) {
return strcmp ( a-> name, b-> name) ;
}
int id_sort ( HashNode * a, HashNode * b) {
return ( a-> id - b-> id) ;
}
void sort_by_name ( HashHead * head) {
HASH_SORT ( * head, name_sort) ;
}
void sort_by_id ( HashHead * head) {
HASH_SORT ( * head, id_sort) ;
}
三、完整代码
#include <stdio.h>
#include <stdlib.h>
#include "uthash.h"
typedef struct my_struct {
int id;
char name[ 10 ] ;
UT_hash_handle hh;
} HashNode;
typedef HashNode* HashHead;
int count_user ( HashHead head) ;
HashNode * find_user ( HashHead head, int user_id) {
HashNode * s;
HASH_FIND_INT ( head, & user_id, s) ;
return s;
}
void add_user ( HashHead * head, HashNode * users) {
if ( ! find_user ( * head, users-> id) )
HASH_ADD_INT ( * head, id, users) ;
}
void replace_user ( HashHead * head, HashNode * newNode) {
HashNode * oldNode = find_user ( * head, newNode-> id) ;
if ( oldNode)
HASH_REPLACE_INT ( * head, id, newNode, oldNode) ;
}
void delete_user ( HashHead * head, HashNode * user) {
if ( user) {
HASH_DEL ( * head, user) ;
free ( user) ;
}
}
void print_user ( HashHead head) {
HashNode * s;
printf ( "size is %d\n" , count_user ( head) ) ;
for ( s = head; s != NULL ; s = s-> hh. next) {
printf ( "user id %d, name %s\n" , s-> id, s-> name) ;
}
}
void print_user_iterator ( HashHead head) {
HashNode * s, * tmp;
printf ( "size is %d\n" , count_user ( head) ) ;
HASH_ITER ( hh, head, s, tmp) {
printf ( "user id %d: name %s\n" , s-> id, s-> name) ;
}
}
int count_user ( HashHead head) {
return HASH_COUNT ( head) ;
}
int name_sort ( HashNode * a, HashNode * b) {
return strcmp ( a-> name, b-> name) ;
}
int id_sort ( HashNode * a, HashNode * b) {
return ( a-> id - b-> id) ;
}
void sort_by_name ( HashHead * head) {
HASH_SORT ( * head, name_sort) ;
}
void sort_by_id ( HashHead * head) {
HASH_SORT ( * head, id_sort) ;
}
int main ( )
{
printf ( "--------------init---------------\n" ) ;
HashHead head = NULL ;
printf ( "--------------add---------------\n" ) ;
HashNode * node = malloc ( sizeof ( HashNode) ) ;
node-> id = 1 ;
strcpy ( node-> name, "tom" ) ;
add_user ( & head, node) ;
node = malloc ( sizeof ( HashNode) ) ;
node-> id = 2 ;
strcpy ( node-> name, "jerry" ) ;
add_user ( & head, node) ;
node = malloc ( sizeof ( HashNode) ) ;
node-> id = 3 ;
strcpy ( node-> name, "jack" ) ;
add_user ( & head, node) ;
node = malloc ( sizeof ( HashNode) ) ;
node-> id = 0 ;
strcpy ( node-> name, "zero" ) ;
add_user ( & head, node) ;
print_user ( head) ;
printf ( "--------------replace---------------\n" ) ;
HashNode * newNode = malloc ( sizeof ( HashNode) ) ;
newNode-> id = 3 ;
strcpy ( newNode-> name, "rose" ) ;
replace_user ( & head, newNode) ;
print_user ( head) ;
printf ( "--------------delete---------------\n" ) ;
delete_user ( & head, find_user ( head, 1 ) ) ;
print_user ( head) ;
printf ( "--------------sort-by-id---------------\n" ) ;
sort_by_id ( & head) ;
print_user ( head) ;
printf ( "--------------sort-by-name---------------\n" ) ;
sort_by_name ( & head) ;
print_user ( head) ;
return 0 ;
}