当前位置: 首页 > news >正文

C语言实现对哈希表的操作:创建哈希表与扩容哈希表

一. 简介

前面文章简单了解了哈希表 这种数据结构,文章如下:

什么是哈希表-CSDN博客

本文来学习一下哈希表,具体学习一下C语言实现对哈希表的简单实现。

二. C语言实现对哈希表的操作

1. 哈希表

哈希表(Hash Table,又称散列表)是一种高效的数据结构,用于实现键值对(Key-Value)的存储和快速查找。其核心思想是通过哈希函数将键(Key)映射到数组的特定位置(称为“桶”或“槽”),从而在平均情况下实现接近常数时间复杂度(O(1))的插入、删除和查找操作。

2. C语言实现哈希表操作

(1) 定义哈希表节点结构体与哈希表结构体
#define  HASH_TABLE_LENGTH  20   //链表容量
#define  LOAD_FACTOR        0.85 //负载因子//哈希表节点结构
typedef struct hash_node {char *key; //键int value; //值struct hash_node* next; //下一个节点指针(用于解决冲突)
} hash_node;//哈希表结构
typedef struct hash_table {hash_node** buckets; //桶数组size_t size; //当前元素数量size_t capacity; //哈希表长度
} hash_table;

hash_node结构体表示每个键值对,hash_table表示每个桶,每个桶中存放一个链表。

(2) 创建哈希表,扩容哈希表容量
//创建哈希表
hash_table* create_hash_table(void) {hash_table* hash_tables = (hash_table*)malloc(sizeof(hash_table));if(!hash_tables) {printf("hash_table malloc failed!\n");return NULL;}hash_tables->size = 0;hash_tables->capacity = HASH_TABLE_LENGTH;hash_tables->buckets = (hash_node**)calloc(hash_tables->capacity, sizeof(hash_node*));if(!hash_tables->buckets) {printf("hash_tables->buckets calloc failed!\n");return NULL;}return hash_tables;
}//哈希函数的实现(djb2哈希算法)
unsigned long hash_func(const char* str) {unsigned long hash = 5381;int c;while((c = *str++)) {hash = ((hash << 5)+hash)+c;}return hash;
}//调节哈希表长度(扩容)
int resize_hash_table(hash_table* hash_tables, size_t new_capacity) {//分配新桶数组hash_node** new_buckets = (hash_node**)calloc(new_capacity, sizeof(hash_node*));if(!new_buckets) {printf("new_buckets calloc failed!\n");return -1;}int i = 0;//遍历原有桶数组,并重新哈希for(i = 0; i < hash_tables->capacity; i++) {hash_node* node = hash_tables->buckets[i];while(node != NULL) {hash_node* tmp_node = node->next;unsigned long new_index = hash_func(node->key)/ new_capacity;//采用头插入法,插入到新桶中node->next = new_buckets[new_index];new_buckets[new_index] = node;//遍历下一个元素node = tmp_node;}}hash_tables->buckets = new_buckets;hash_tables->capacity = new_capacity;free(hash_tables->buckets);return 0;
}

创建哈希表比较简单,这里不做说明。

调整哈希表容量接口这里进行一下说明:

首先,分配新哈希表的容量。

其次,遍历原来哈希表中所有元素(键值对),将旧的哈希表中元素插入到哈希表新桶中。由于哈希表的容量发生了改变,原有的键值对需要重新计算哈希值并插入到新的哈希表中。

node->next = new_buckets[new_index]; 
new_buckets[new_index] = node;

这两行代码的作用是将当前处理的哈希表节点 node 插入到新哈希表的对应桶(bucket)中,采用的是头插法。

node->next = new_buckets[new_index];
  • 含义:将当前节点 nodenext 指针指向新哈希表中对应桶的头节点。
  • 作用:这一步是为了把当前节点插入到新桶的头部。若新桶原本为空,new_buckets[new_index] 会是 NULL,那么 node->next 就会被设为 NULL;若新桶已经有节点存在,new_buckets[new_index] 就会指向桶中的头节点,此时 node->next 就会指向这个头节点。
new_buckets[new_index] = node;
  • 含义:把新哈希表中对应桶的头节点更新为当前节点 node
  • 作用:经过这一步,当前节点 node 就成为了新桶的头节点。原本新桶中的节点(如果有的话)就变成了 node 的后继节点。

(3) 向哈希表中插入新的键值对


http://www.mrgr.cn/news/100253.html

相关文章:

  • Mysql日志undo redo binlog relaylog与更新一条数据的执行过程详解
  • 软考中级-软件设计师 知识点速过1(手写笔记)
  • 大模型应用开发之LLM入门
  • 计算机组成原理-408考点-数的表示
  • 正则表达式三剑客之——awk命令
  • 大内存生产环境tomcat-jvm配置实践
  • RocketMQ 主题与队列的协同作用解析(既然队列存储在不同的集群中,那要主题有什么用呢?)---管理命令、配置安装(主题、消息、队列与 Broker 的关系解析)
  • 张 LLM提示词拓展16中方式,提示词
  • 14-DevOps-快速部署Kubernetes
  • 【2025 最新前沿 MCP 教程 01】模型上下文协议:AI 领域的 USB-C
  • YOLO12架构优化——引入多维协作注意力机制(MCAM)抑制背景干扰,强化多尺度与小目标检测性能
  • 【数据可视化-25】时尚零售销售数据集的机器学习可视化分析
  • 【深度强化学习 DRL 快速实践】异步优势演员评论员算法 (A3C)
  • MySQL数据库(基础篇)
  • 【计算机视觉】CV实战项目 - 深入解析基于HOG+SVM的行人检测系统:Pedestrian Detection
  • VScode远程连接服务器(免密登录)
  • 【数据可视化-24】巧克力销售数据的多维度可视化分析
  • Mysql日志undo redo binlog与更新一条数据的执行过程详解
  • 【深度强化学习 DRL 快速实践】Value-based 方法总结
  • RefFormer论文精读