C语言中提供的第三方库之哈希表实现

一. 简介

前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下:

C语言中提供的第三方库uthash常用接口-CSDN博客

本文简单学习一下第三方库 uthash库对哈希表的操作。

二. uthash库哈希表操作示例

uthash库提供了对不同类型数据类型的键值时的操作接口,这里举例key键值为 char* 类型,虽然是指针类型,但是进行比较时是对key键值的比较,而不是比较指针地址是否相等。所以,使用的是 uthash库中对字符串类型键的接口。

1. 定义哈希表结构体

首先需要定义哈希表结构体,该结构体包括要存储的数据和 UT_hash_handle句柄。例如如下:

复制代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "uthash.h"

//定义哈希表的结构体
typedef struct hash_node{
    char* key; //键
    char*  value; //值
    UT_hash_handle hh; //hthash库的哈希表句柄
} hash_node;

hash_node* hash_table = NULL; //定义一个哈希表指针

可以看出,哈希表的结构体包括键值与实际数据。可以通过哈希函数将键值映射到哈希表中的某个位置。

2. 向哈希表插入新数据

将新的数据插入到哈希表中:

复制代码
//将新数据插入到哈希表中
void insert_hash_table(const* char key, char* value) {
    if(!key) {
        return;
    }
    hash_node* out_node;
   
    //检查键是否已存在
    HASH_FIND_STR(hash_table, key, out_node);
    if(out_node) { //键已存在哈希表中,更新值(先释放旧值内存)
        free(out_node->value);
        out_node->value = strdup(value);
        if(!out_node->value) {
            fprintf(stderr, "内存分配失败!\n");
        }
    }

    //键不存在哈希表中
    hash_node* new_node = (hash_node*)malloc(sizeof(hash_node));
    new_node->key = strdup(key);
    new_node->value = strdup(value);
    if((!new_node->key) || (!new_node->value)) {
        free(new_node->key);
        free(new_node->value);
        free(new_node);
        return;
    }

    //将新键值对插入哈希表中
    HASH_ADD_KEYPTR(hash_handle, hash_table, new_node->key, strlen(new_node->key), new_node);
}

向哈希表中插入新元素时,首先检查新元素的键是否已存在哈希表中,已存在则更新key键对应的数据,否则,创建新的节点值并插入哈希表中。

2. 根据键查找对应的值

在哈希表中根据键查找对应的值,实现如下:

复制代码
//根据键查找值
const char* find_by_key(const char* key) {
    hash_node* out_node = NULL;

    //根据键查找对应的值
    HASH_FIND_STR(hash_table, key, out_node);
    return out_node ? out_node->value : NULL;
}

3. 根据键值删除对应的数据

在哈希表查找某个键对应的数据,实现如下:

复制代码
delete_data_by_key(const char* key) {
    hash_node * out_node = NULL;
    
    //根据键查找对应的值
    HASH_FIND_STR(hash_table, key, out_node);
    if(!out_node) {
        printf("not value by key!\n");
        return;
    }

    //删除key对应的值
    HASH_DEL(hash_table, out_node);
    free(out_node->key); //释放键内存
    free(out_node->value); //释放值内存
    free(out_node);  //释放节点内存
}

注意,当删除哈希表中键对应的值后,需要释放该键内存,值内存,以及该节点内存资源。

4. 遍历哈希表

遍历哈希表实现如下:

复制代码
//遍历哈希表
void traverse_hash_table(hash_node* hash_table) {
    hash_node* hash_current, *hash_next;

    HASH_ITER(hash_handle, hash_table, hash_current, hash_next) {
        printf("current key: %s, current value: %s\n", hash_current->key, hash_current->value);
    }
}

5. 清空哈希表

清空哈希表使用 HASH_DEL(head, delptr) 宏定义,但是,内存释放还需要手动进行释放。

复制代码
//清空哈希表
void clear_hash_table(void) {
    hash_node* hash_current, *hash_next;

    HASH_ITER(hash_handle, hash_table, hash_current, hash_next) {
        HASH_DEL(hash_table, hash_current);
        //需要手动释放内存
        free(hash_current->key);
        free(hash_current->value);
        free(hash_current);
    }
相关推荐
黑听人14 分钟前
【力扣 简单 C】141. 环形链表
c语言·开发语言·数据结构·算法·leetcode
谷雨不太卷33 分钟前
AVL树的实现
数据结构·c++·算法
别来无恙1493 小时前
岛屿周长问题的三种解法:直接计数法、数学计算法与深度优先搜索
java·c++·算法·深度优先·dfs
UP_Continue4 小时前
排序--计数排序
数据结构·算法
牵手夏日7 小时前
题目类型——左右逢源
算法
愚润求学7 小时前
【递归、搜索与回溯】FloodFill算法(一)
c++·算法·leetcode
sunny-ll9 小时前
【C++】详解vector二维数组的全部操作(超细图例解析!!!)
c语言·开发语言·c++·算法·面试
嵌入式@秋刀鱼10 小时前
《第四章-筋骨淬炼》 C++修炼生涯笔记(基础篇)数组与函数
开发语言·数据结构·c++·笔记·算法·链表·visual studio code
嵌入式@秋刀鱼10 小时前
《第五章-心法进阶》 C++修炼生涯笔记(基础篇)指针与结构体⭐⭐⭐⭐⭐
c语言·开发语言·数据结构·c++·笔记·算法·visual studio code
简简单单做算法10 小时前
基于PSO粒子群优化的VMD-LSTM时间序列预测算法matlab仿真
算法·matlab·lstm·时间序列预测·pso·vmd-lstm·pso-vmd-lstm