热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

哈希表的C语言链表实现

哈希表的C语言链表实现

哈希表的C语言链表实现

  • 1 哈希表的特点
  • 2 代码实现
    • 2.1 链表部分
      • 2.1.1 链表结点的结构
      • 2.1.2 创建链表
      • 2.1.3 销毁链表
      • 2.1.4 头插新结点
      • 2.1.5 根据id搜索链表
    • 2.2 Hash表部分
      • 2.2.1 创建Hash表
      • 2.2.2 清空表中元素
      • 2.2.3 摧毁整个Hash表
      • 2.2.4 Hash函数
      • 2.2.5 插入哈希表
      • 2.2.6 根据key搜索Hash表返回数据
  • 3 测试例程
    • 测试结果

1 哈希表的特点

结合了数组(索引快)和链表(可灵活增删结点)的优点。

在这里插入图片描述

2 代码实现

2.1 链表部分

2.1.1 链表结点的结构

typedef struct __tag_node{
int id;
struct __tag_node *pNext;
int satellite;
}Node;

2.1.2 创建链表

Node *LinkedList_Create(void)
{
Node *p = malloc(sizeof(Node));
if(p == NULL){
return NULL;
}
p->pNext = NULL;
p->id = 0; // The total quantity of nodes
return p;
}

2.1.3 销毁链表

void LinkedList_Destroy(Node *list)
{
Node *p = list->pNext; // Reserved header node
while(p){
Node *tmp = p;
p = p->pNext;
free(tmp);
}
list->pNext = NULL;
list->id = 0;
}

2.1.4 头插新结点

/**
* @brief Inserting a new node in the linked list
* @param list, The linked list will be inserted
* @param id, id number
* @param the satellite value of the id
**/

int LinkedList_InsertHead(Node *list, int id, int dat)
{
Node *p = malloc(sizeof(Node *));
if(p == NULL){
return -1;
}
p->id = id;
p->pNext = list->pNext;
list->pNext = p;
p->satellite = dat;
return 1;
}

2.1.5 根据id搜索链表

/**
* @brief search the id
* @param list, The hash table will be searched
* @param key, key
* @retval the satellite value of the id
**/

int LinkedList_Search(Node *list, int id)
{
Node *p = list->pNext;
for(Node *p = list->pNext; p; p = p->pNext){
if(id == p->id){
return p->satellite;
}
}
return 0;
}

2.2 Hash表部分

2.2.1 创建Hash表

Node **HashTable_Create(int len)
{
Node **p = malloc(len * sizeof(Node *));
for(int i = 0; i < len; i++){
p[i] = LinkedList_Create();
}
return p;
}

2.2.2 清空表中元素

void HashTable_Clear(Node **arr, int len)
{
for(int i = 0; i < len; i++){
LinkedList_Destroy(*(arr+i));
}
}

2.2.3 摧毁整个Hash表

void HashTable_Destroy(Node **arr, int len)
{
HashTable_Clear(arr, len);
for(int i = 0; i < len; i++){
free(arr[i]);
}
free(arr);
}

2.2.4 Hash函数

int HashTable_hashFunc(int key, int len)
{
return key % len;
}

2.2.5 插入哈希表

int HashTable_Insert(int key, int value, Node **table, int length)
{
if(LinkedList_InsertHead(table[HashTable_hashFunc(key, length)], key, value)){
return 1; // Success
}else{
return -1; // Failure
}
}

2.2.6 根据key搜索Hash表返回数据

/**
* @brief search the key
* @param table, The hash table will be searched
* @param length, The length of the hash table
* @retval the value of the key
**/

int HashTable_Search(int key, Node **table, int length)
{
return LinkedList_Search(table[HashTable_hashFunc(key, length)], key);
}
3 测试例程

#define __MAX_LEN_TABLE_ 10
int main(int argc, char *argv[])
{
Node **pHashTable;
pHashTable = HashTable_Create(__MAX_LEN_TABLE_);
if(HashTable_Insert(12, 125, pHashTable, __MAX_LEN_TABLE_)){
printf("Insert key = 12, value = 125 successful!\r\n");
}else{
printf("Insert key = 12 fail!\r\n");
}
if(HashTable_Insert(22, 255, pHashTable, __MAX_LEN_TABLE_)){
printf("Insert key = 22, value = 255 successful!\r\n");
}else{
printf("Insert key = 255 fail!\r\n");
}
int value = HashTable_Search(22, pHashTable, __MAX_LEN_TABLE_);
printf("value of key=22 is %d\r\n", value);
value = HashTable_Search(12, pHashTable, __MAX_LEN_TABLE_);
printf("value of key=12 is %d\r\n", value);
HashTable_Destroy(pHashTable, __MAX_LEN_TABLE_);

return 0;
}

测试结果

在这里插入图片描述


推荐阅读
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了基于c语言的mcs51单片机定时器计数器的应用教程,包括定时器的设置和计数方法,以及中断函数的使用。同时介绍了定时器应用的举例,包括定时器中断函数的编写和频率值的计算方法。主函数中设置了T0模式和T1计数的初值,并开启了T0和T1的中断,最后启动了CPU中断。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 这篇文章主要介绍了Python拼接字符串的七种方式,包括使用%、format()、join()、f-string等方法。每种方法都有其特点和限制,通过本文的介绍可以帮助读者更好地理解和运用字符串拼接的技巧。 ... [详细]
  • 本文介绍了在Windows系统上使用C语言命令行参数启动程序并传递参数的方法,包括接收参数程序的代码和bat文件的编写方法,同时给出了程序运行的结果。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
author-avatar
先进的山楂4l4_519
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有