在HashTable中,用到了DList来解决冲突,我们不用重新实现其内部的DList,只需将已经实现的双向链表DList组合到HashTable中使用即可。下面给出工程的全部代码:


就不再解释其中每个文件干嘛的了,我懂的。 依次来看看:

1. Makefile

-D name: Predefine name as a macro. (man gcc可以看到)

2. typedef.h

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>#ifndef TYPEDEF_H
#define TYPEDEF_Htypedef enum _Ret
{RET_OK,RET_OOM,RET_STOP,RET_INVALID_PARAMS,RET_FAIL
}Ret;typedef void     (*DataDestroyFunc)(void* ctx, void* data);
typedef int      (*DataCompareFunc)(void* ctx, void* data);
typedef Ret      (*DataVisitFunc)(void* ctx, void* data);
typedef int       (*DataHashFunc)(void* data);#ifdef __cplusplus
#define DECLS_BEGIN extern "C" {
#define DECLS_END   }
#else
#define DECLS_BEGIN
#define DECLS_END
#endif/*__cplusplus*/#define return_if_fail(p) if(!(p)) \{printf("%s:%d Warning: "#p" failed.\n", \__func__, __LINE__); return;}
#define return_val_if_fail(p, ret) if(!(p)) \{printf("%s:%d Warning: "#p" failed.\n",\__func__, __LINE__); return (ret);}#define SAFE_FREE(p) if(p != NULL) {free(p); p = NULL;}typedef Ret (*SortFunc)(void** array, size_t nr, DataCompareFunc cmp);#endif/*TYPEDEF_H*/

3. hash_table.h

#include <stdio.h>
#include "typedef.h"#ifndef HASH_TABLE_H
#define HASH_TABLE_HDECLS_BEGINstruct _HashTable;
typedef struct _HashTable HashTable;HashTable* hash_table_create(DataDestroyFunc data_destroy, void* ctx, DataHashFunc hash, int slot_nr);size_t   hash_table_length(HashTable* thiz);
Ret      hash_table_insert(HashTable* thiz, void* data);
Ret      hash_table_delete(HashTable* thiz, DataCompareFunc cmp, void* data);
Ret      hash_table_find(HashTable* thiz, DataCompareFunc cmp, void* data, void** ret_data);
Ret      hash_table_foreach(HashTable* thiz, DataVisitFunc visit, void* ctx);void hash_table_destroy(HashTable* thiz);DECLS_END#endif/*HASH_TABLE*/

4.hash_table.c

#include "dlist.h"
#include "hash_table.h"struct _HashTable
{DataHashFunc    hash;DList**         slots;size_t          slot_nr;DataDestroyFunc data_destroy;void*           data_destroy_ctx;
};HashTable* hash_table_create(DataDestroyFunc data_destroy, void* ctx, DataHashFunc hash, int slot_nr)
{HashTable* thiz = NULL;return_val_if_fail(hash != NULL && slot_nr > 1, NULL);thiz = (HashTable*)malloc(sizeof(HashTable));if(thiz != NULL){thiz->hash = hash;thiz->slot_nr  = slot_nr;thiz->data_destroy_ctx = ctx;thiz->data_destroy = data_destroy;if((thiz->slots = (DList**)calloc(sizeof(DList*)*slot_nr, 1)) == NULL){free(thiz);thiz = NULL;}}return thiz;
}Ret      hash_table_insert(HashTable* thiz, void* data)
{size_t index = 0;return_val_if_fail(thiz != NULL, RET_INVALID_PARAMS);index = thiz->hash(data)%thiz->slot_nr;if(thiz->slots[index] == NULL){thiz->slots[index] = dlist_create(thiz->data_destroy, thiz->data_destroy_ctx);}return dlist_prepend(thiz->slots[index], data);
}Ret      hash_table_delete(HashTable* thiz, DataCompareFunc cmp, void* data)
{int index = 0;DList* dlist = NULL;return_val_if_fail(thiz != NULL && cmp != NULL, RET_INVALID_PARAMS);index = thiz->hash(data)%thiz->slot_nr;dlist = thiz->slots[index];if(dlist != NULL){index = dlist_find(dlist, cmp, data);return dlist_delete(dlist, index);}return RET_FAIL;
}size_t   hash_table_length(HashTable* thiz)
{size_t i = 0;size_t nr = 0;return_val_if_fail(thiz != NULL, 0);for(i = 0; i < thiz->slot_nr; i++){if(thiz->slots[i] != NULL){nr += dlist_length(thiz->slots[i]);}}return nr;
}Ret    hash_table_find(HashTable* thiz, DataCompareFunc cmp, void* data, void** ret_data)
{int index = 0;DList* dlist = NULL;return_val_if_fail(thiz != NULL && cmp != NULL && ret_data != NULL, RET_INVALID_PARAMS);index = thiz->hash(data)%thiz->slot_nr;dlist = thiz->slots[index];if(dlist != NULL){index = dlist_find(dlist, cmp, data);return dlist_get_by_index(dlist, index, ret_data);}return RET_FAIL;
}Ret      hash_table_foreach(HashTable* thiz, DataVisitFunc visit, void* ctx)
{size_t i = 0;return_val_if_fail(thiz != NULL && visit != NULL, RET_INVALID_PARAMS);for(i = 0; i < thiz->slot_nr; i++){if(thiz->slots[i] != NULL){dlist_foreach(thiz->slots[i], visit, ctx);}}return RET_OK;
}void hash_table_destroy(HashTable* thiz)
{size_t i = 0;if(thiz != NULL){for(i = 0; i < thiz->slot_nr; i++){if(thiz->slots[i] != NULL){dlist_destroy(thiz->slots[i]);thiz->slots[i] = NULL;}}free(thiz->slots);free(thiz);}return;
}#ifdef HASH_TABLE_TEST
#include "test_helper.c"int main(int argc, char* argv[])
{int i = 0;int n = 10000;int ret_data = 0;HashTable* hash_table = hash_table_create(NULL, NULL, hash_int, 31);for(i = 0; i < n; i++){assert(hash_table_length(hash_table) == i);assert(hash_table_insert(hash_table, (void*)i) == RET_OK);assert(hash_table_length(hash_table) == (i + 1));assert(hash_table_find(hash_table, cmp_int, (void*)i, (void**)&ret_data) == RET_OK);assert(ret_data == i);}for(i = 0; i < n; i++){assert(hash_table_delete(hash_table, cmp_int, (void*)i) == RET_OK);assert(hash_table_length(hash_table) == (n - i -1));assert(hash_table_find(hash_table, cmp_int, (void*)i, (void**)&ret_data) != RET_OK);}hash_table_destroy(hash_table);return 0;
}
#endif/*HASH_TABLE_TEST*/

5. 最后来复习一下以前写的几个文件

typedef.h

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>#ifndef TYPEDEF_H
#define TYPEDEF_Htypedef enum _Ret
{RET_OK,RET_OOM,RET_STOP,RET_INVALID_PARAMS,RET_FAIL
}Ret;typedef void     (*DataDestroyFunc)(void* ctx, void* data);
typedef int      (*DataCompareFunc)(void* ctx, void* data);
typedef Ret      (*DataVisitFunc)(void* ctx, void* data);
typedef int       (*DataHashFunc)(void* data);#ifdef __cplusplus
#define DECLS_BEGIN extern "C" {
#define DECLS_END   }
#else
#define DECLS_BEGIN
#define DECLS_END
#endif/*__cplusplus*/#define return_if_fail(p) if(!(p)) \{printf("%s:%d Warning: "#p" failed.\n", \__func__, __LINE__); return;}
#define return_val_if_fail(p, ret) if(!(p)) \{printf("%s:%d Warning: "#p" failed.\n",\__func__, __LINE__); return (ret);}#define SAFE_FREE(p) if(p != NULL) {free(p); p = NULL;}typedef Ret (*SortFunc)(void** array, size_t nr, DataCompareFunc cmp);#endif/*TYPEDEF_H*/

dlist.h

#include <stdio.h>
#include "typedef.h"#ifndef DLIST_H
#define DLIST_HDECLS_BEGINstruct _DList;
typedef struct _DList DList;DList* dlist_create(DataDestroyFunc data_destroy, void* ctx);Ret dlist_insert(DList* thiz, size_t index, void* data);
Ret dlist_prepend(DList* thiz, void* data);
Ret dlist_append(DList* thiz, void* data);
Ret dlist_delete(DList* thiz, size_t index);
Ret dlist_get_by_index(DList* thiz, size_t index, void** data);
Ret dlist_set_by_index(DList* thiz, size_t index, void* data);
size_t   dlist_length(DList* thiz);
int      dlist_find(DList* thiz, DataCompareFunc cmp, void* ctx);
Ret      dlist_foreach(DList* thiz, DataVisitFunc visit, void* ctx);void dlist_destroy(DList* thiz);DECLS_END#endif/*DLIST*/

(第五章 1)组合——从DList到HashTable相关推荐

  1. 第五章 SQL聚合函数 %DLIST

    文章目录 第五章 SQL聚合函数 %DLIST 大纲 参数 描述 %DLIST 和 %SelectMode %DLIST和ORDER BY 相关的聚合函数 示例 第五章 SQL聚合函数 %DLIST ...

  2. 《吕鑫:VC++6.0就业培训宝典之MFC视频教程》学习笔记 -- 第五章对话框组合

    章节内容: 5.1 模式对话框和非模式对话框 5.2 账户登录权限管理 5.3 录入对话框和员工信息管理 5.4 完善员工信息管理对话框 5.5 系统对话框的使用 5.6 完成所有系统对话框的使用方法 ...

  3. 王道考研 计算机网络笔记 第五章:传输层

    本文基于2019 王道考研 计算机网络: 2019 王道考研 计算机网络 个人笔记总结 第一章:王道考研 计算机网络笔记 第一章:概述&计算机网络体系结构 第二章:王道考研 计算机网络笔记 第 ...

  4. 第五章 RNA-seq分析

    第五章 RNA-seq分析 主要为RNA-seq相关知识,部分内容作笔记自查使用.如有错误或遗漏还请海涵,可评论或邮箱联系. 最后修改时间:2020-09-01 16:11:38 星期二 转录组研究方 ...

  5. Python金融大数据分析——第五章数据可视化(1)二维绘图

    目录 第五章 数据可视化 5.1 二维绘图 5.1.1 一维数据集 5.1.2 二维数据集 5.1.3绘制其他图表 5.1.3.1绘制散点图 5.1.3.2 直方图 5.1.3.3 箱型图 第五章 数 ...

  6. Visual C++ 2008入门经典 第十五章 在窗口中绘图

    /*第十五章 在窗口中绘图 主要内容: 1 Windows为窗口绘图提供的坐标系统 2 设置环境及其必要性 3 程序如何以及在窗口中绘图 4 如何定义鼠标消息的处理程序 5 如何定义自己的形状类 6 ...

  7. 第五章:条件、循环以及其他语句(上)

    第五章 条件.循环以及其他语句 5.1 再谈print和import 随着我们对于Python的认知越来越多,很多我们以前不清楚的东西慢慢都需要了解,下面在谈谈print和import等我们所不知道的 ...

  8. 第五章 Python数据结构

    第五章 Python数据结构 本章更详细地讨论一些已经讲过的数据类型的使用,并引入一些新的类型. 5.1 列表 列表数据类型还有其它一些方法.下面是列表对象的所有方法: insert(i, x) -- ...

  9. 鸟哥的Linux私房菜(服务器)- 第五章、 Linux 常用网络指令

    第五章. Linux 常用网络指令 最近更新日期:2011/07/18 Linux 的网络功能相当的强悍,一时之间我们也无法完全的介绍所有的网络指令,这个章节主要的目的在介绍一些常见的网络指令而已. ...

最新文章

  1. entity framework 使用Mysql配置文件
  2. c语言指针编程易错点,C语言中指针的一些易错点!
  3. win10解决Mysql net start mysql启动,提示发生系统错误 5 拒绝访问
  4. 历经3年的打磨,数据构建及管理平台Dataphin增加了什么新功能?
  5. java反射 初始化bean_通用javabean初始化(反射机制)
  6. MTFBWU的完整形式是什么?
  7. php 获取两个日期相隔几周,怎么样计算2个日期之间相差几周
  8. Windows server2008 搭建ASP接口訪问连接oracle数据库全过程记录
  9. mongo-java-driver 的简单使用(1)
  10. 双足机器人Maltab腿部建模,正运动学分析
  11. 西安电子科技大学计算智能导论公茂果老师课程所有PPT
  12. win7桌面计算机图标去掉,Win7去掉快捷方式箭头_Win7去掉桌面图标箭头软件-192路由网...
  13. C语言编程题:平方数
  14. Excel条件格式使用小总结
  15. 排序函数qsort和sort那点事
  16. 英文论文中常见拉丁语/英语缩写整理
  17. Helm及其它功能性组件
  18. linux自带的二进制查看器
  19. 欧尼酱讲JVM(01)——整体概览(导航)
  20. 数字化助力生产制造管理:家具行业管理系统

热门文章

  1. 关于位图数据和标记位-P3
  2. 使用supermap实现轨迹动态回放功能
  3. free java movies_Java Programming: Build a Recommendation System
  4. CSS 三大特性与盒子模型
  5. GraphViz 使用教程-用代码生成有向图。并介绍流程图、时序图等绘图工具
  6. Android飞书红包插件
  7. 鸿蒙系统专业就业前景,10大热门工科专业盘点,毕业后就业率不错,薪资待遇方面也比较高...
  8. 身份云平台 Authing 完成 2300 万美元 A 轮融资
  9. 信息技术c语言试题及答案,试卷|信息技术试卷下载_21试卷_21世纪教育网
  10. 解决Chrome 本地调试React,Sources下找不到源代码的问题