链式哈希表
来源:互联网 发布:herry it 编辑:程序博客网 时间:2024/05/20 12:21
链式哈希表介绍
待补充
链式哈希表实现
// Chtbl.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <malloc.h>/*链表元素结构体定义*/typedef struct ListElmt_{void *pdata;struct ListElmt_ *pNext;}ListElmt;/*链表结构体定义*/typedef struct List_{int iSize;void (*destory)(void *data);ListElmt *ListElmtHead;ListElmt *ListElmtTail;}List;/*链表操作宏定义*/#define LIST_SIZE(list) ((list)->iSize)#define LIST_HEAD(list) ((list)->ListElmtHead)#define LIST_TAIL(list) ((list)->ListElmtTail)#define LIST_IS_HEAD(list, element) ((element == (list)->ListElmtHead) ? 1:0)#define LIST_IS_TAIL(list, element) ((element == (list)->ListElmtTail) ? 1:0)#define LIST_DATA(element) ((element)->pdata)#define LIST_NEXT(element) ((element)->pNext)/**函数名:List_Init*参数:list 链表* destory 释放链表节点内存的函数*功能:单链表初始化*返回值:无*作者:AlbertoNo1*日期:2016-04-14*/void List_Init(List *list, void (*destory)(void *data)){/*入参合法性由调用者保证*/list->iSize = 0;list->destory = destory;list->ListElmtHead = NULL;list->ListElmtTail = NULL;return ;}/**函数名:List_Ins_Next*参数:list 链表* Element 待插入元素的前一个节点元素* data 待插入元素数据*功能:单链表添加节点函数*返回值:0 成功 -1 失败*作者:AlbertoNo1*日期:2016-04-14*/int List_Ins_Next(List *list, ListElmt *Element, void *data){ListElmt *Lelmt = NULL;if ((NULL == list) || (NULL == data)){return -1;}/*申请链表节点内存*/Lelmt = (ListElmt*)malloc(sizeof(ListElmt));if (NULL == Lelmt){return -1;}Lelmt->pdata = data;if (NULL == Element){/*在链表头插入元素*/Lelmt->pNext = list->ListElmtHead;list->ListElmtHead = Lelmt;if (0 == LIST_SIZE(list)){list->ListElmtTail = Lelmt;}}else{/*在非链表头插入元素*/Lelmt->pNext = Element->pNext;Element->pNext = Lelmt;if (NULL == Lelmt->pNext){list->ListElmtTail = Lelmt;}}/*链表大小加1*/list->iSize++;return 0;}/**函数名:List_Rem_Next*参数:list 链表* Element 待删除元素的前一个节点元素* data 返回删除元素的数据域*功能:单链表删除节点函数*返回值:0 成功 -1 失败*作者:AlbertoNo1*日期:2016-04-14*/int List_Rem_Next(List *list, ListElmt *Element, void **data){ListElmt *Old_Lelmt = NULL;if ((NULL == list) || (NULL == data)){return -1;}if (0 == LIST_SIZE(list)){return -1;}if (NULL == Element){/*删除链表头元素*/*data = list->ListElmtHead->pdata;Old_Lelmt = list->ListElmtHead;list->ListElmtHead = list->ListElmtHead->pNext;if (1 == LIST_SIZE(list)){list->ListElmtTail = NULL;}}else{/*删除非链表头元素*/if (1 == LIST_SIZE(list)){return -1;}else{*data = Element->pNext->pdata;Old_Lelmt = Element->pNext;Element->pNext = Element->pNext->pNext;if (NULL == Element->pNext){list->ListElmtTail = Element;}}}/*释放删除节点的内存*/free(Old_Lelmt);/*链表大小减一*/list->iSize--;return 0;}/**函数名:List_Destory*参数:list 链表*功能:单链表销毁*返回值:无*作者:AlbertoNo1*日期:2016-04-14*/void List_Destory(List *list){void *data = NULL;/*入参合法性由调用者保证*/while (LIST_SIZE(list) > 0){if ((0 == List_Rem_Next(list, NULL, &data))&&(NULL != list->destory)){list->destory(data);}}memset(list, 0, sizeof(List));return ;}/**函数名:destory*参数:data 动态申请内存的地址*功能:释放动态申请内存函数*返回值:无*作者:AlbertoNo1*日期:2016-04-14*/void destory(void *data){free(data);}/*链式哈希表数据结构*/typedef struct CHTbl_{int buckets; /*桶的个数*/int (*hash_func)(const void *key);int (*match)(const void *key1, const void *key2);void (*destroy)(void *data);int size;List *table;}CHTbl;/*链式哈希表操作宏定义*/#define chtbl_size(htbl) ((htbl)->size)#define CHTBL_BUCKETS (100)/**函数名:chtbl_hash*参数:key 哈希键值*功能:哈希函数*返回值:哈希值*作者:AlbertoNo1*日期:2016-04-14*/int chtbl_hash(const void *key){int value = *((int*)key);return value%CHTBL_BUCKETS;}/**函数名:chtbl_match*参数:pKey1 指向第一个比较元素的地址* pKey2 指向第二个比较元素的地址*功能:比较两个元素的大小*返回值:1 表示Key1 大于 Key2* -1 表示Key1 小于 Key2* 0 表示Key1 等于 Key2*作者:AlbertoNo1*日期:2016-04-14*/int chtbl_match(const void *pKey1, const void *pKey2){/*对两个整型数进行比较*/if (*((int*)pKey1) > *((int*)pKey2)){return 1;}else if (*((int*)pKey1) < *((int*)pKey2)){return -1;}else{return 0;}}/**函数名:chtbl_init*参数:htbl 链式哈希表* buckets 哈希表桶个数* h_func 哈希函数* m_func 元素比较函数* d_func 元素动态申请内存释放函数*功能:链式哈希表初始化函数*返回值:0 成功 -1 失败*作者:AlbertoNo1*日期:2016-04-14*/int chtbl_init(CHTbl *htbl, int buckets, int (*h_func)(const void *key),int (*m_func)(const void *key1, const void *key2), void (*d_func)(void *data)){int i = 0;/*为哈希表申请内存空间*/htbl->table = (List*)malloc(buckets*sizeof(List));if (NULL == htbl->table){return -1;}/*初始化(链表)桶*/htbl->buckets = buckets;for (i = 0; i < buckets; i++){List_Init(&(htbl->table[i]), destory);}htbl->hash_func = h_func;htbl->match = m_func;htbl->destroy = d_func;htbl->size = 0;return 0;}/**函数名:chtbl_destory*参数:htbl 链式哈希表*功能:链式哈希表销毁函数*返回值:无*作者:AlbertoNo1*日期:2016-04-14*/void chtbl_destory(CHTbl *htbl){int i = 0;/*销毁(链表)桶*/for (i = 0; i < htbl->buckets; i++){List_Destory(&(htbl->table[i]));}/*释放哈希表内存*/free(htbl->table);memset(htbl, 0, sizeof(CHTbl));return ;}/**函数名:chtbl_lookup*参数:htbl 链式哈希表* data 待查找元素数据*功能:链式哈希表元素查找函数*返回值:0 哈希表中存在此元素 -1 哈希表中不存在此元素*作者:AlbertoNo1*日期:2016-04-14*/int chtbl_lookup(const CHTbl *htbl, void **data){ListElmt *element = NULL;int bucket = 0;/*获得哈希值*/bucket = htbl->hash_func(*data)%(htbl->buckets);/*在(链表)桶中查找元素*/for (element = LIST_HEAD(&(htbl->table[bucket])); element != NULL; element = LIST_NEXT(element)){if (htbl->match(*data, LIST_DATA(element)) == 0){/*找到该元素*/*data = LIST_DATA(element);return 0;}}/*该元素未找到*/return -1;}/**函数名:chtbl_insert*参数:htbl 链式哈希表* data 待插入桶中的元素*功能:链式哈希表添加元素函数*返回值:0 成功 1 失败*作者:AlbertoNo1*日期:2016-04-14*/int chtbl_insert(CHTbl *htbl, const void *data){void *temp = NULL;int bucket = 0;int retval = 0;/*如果哈希表中已经存在该元素,直接返回*/temp = (void*)data;if (chtbl_lookup(htbl, &temp) == 0){return 1;}/*获得哈希值*/bucket = htbl->hash_func(data)%(htbl->buckets);/*把元素插到对应的桶中*/retval = List_Ins_Next(&(htbl->table[bucket]), NULL, (void*)data);if (0 == retval){/*插入成功*/htbl->size++;}return retval;}/**函数名:chtbl_remove*参数:htbl 链式哈希表* data 待从桶中删除的元素*功能:链式哈希表删除元素函数*返回值:0 成功 -1 失败*作者:AlbertoNo1*日期:2016-04-14*/int chtbl_remove(CHTbl *htbl, const void **data){ListElmt *element = NULL; ListElmt *prev = NULL;int bucket = 0; /*获得哈希值*/bucket = htbl->hash_func(*data)%(htbl->buckets);/*在对应的链表桶中查找该元素*/for (element = LIST_HEAD(&(htbl->table[bucket])); element != NULL; element = LIST_NEXT(element)){if (htbl->match(*data, LIST_DATA(element)) == 0){/*找到该元素*//*从(链表)桶中移除该元素*/if (List_Rem_Next(&(htbl->table[bucket]), prev, (void**)data) == 0){htbl->size--;return 0;}else{return -1;}}prev = element;}/*哈希表中不存在想要删除的元素*/return -1;}int _tmain(int argc, _TCHAR* argv[]){int iRet = 0;int iLoop = 0;int *piData = NULL;CHTbl stCHtbl = {0};chtbl_init(&stCHtbl, CHTBL_BUCKETS, chtbl_hash, chtbl_match, destory);for (iLoop = 0; iLoop < 10; iLoop++){piData = (int*)malloc(sizeof(int));*piData = iLoop;iRet |= chtbl_insert(&stCHtbl,(void*)piData);}if (0 != iRet){return -1;}piData = (int*)malloc(sizeof(int));*piData = 9;iRet = chtbl_lookup(&stCHtbl, (void**)&piData);printf("%d \r\n", iRet);free(piData);piData = (int*)malloc(sizeof(int));*piData = 10;iRet = chtbl_lookup(&stCHtbl, (void**)&piData);printf("%d \r\n", iRet);free(piData);piData = (int*)malloc(sizeof(int));*piData = 9;iRet = chtbl_remove(&stCHtbl, (const void**)&piData);printf("%d \r\n", iRet);free(piData);piData = (int*)malloc(sizeof(int));*piData = 9;iRet = chtbl_lookup(&stCHtbl, (void**)&piData);printf("%d \r\n", iRet);free(piData);chtbl_destory(&stCHtbl);getchar();return 0;}
1 0
- 链式哈希表
- 链式哈希表
- 哈希表的链式存储
- 链式哈希表的实现
- 9、链式哈希表
- PHP实现 拉链式哈希表
- 链式哈希表(Hash Table)--算法导论示例
- C++实现哈希表 HashMap冲突链式解决
- 10、链式哈希表的应用-符号表
- C 算法精介----哈希表->链式哈希表->分析与实现
- 小白书之移动小球哈希表的链式结构
- 线性表数据结构解读(六)链式哈希表结构-LinkedHashMap
- 链式队列
- 链式队列
- 链式队列
- 链式栈
- 链式栈
- 链式队列
- LightOj 1298
- 最明白的JAVA——回调机制
- Android开发之java代码工具类。判断当前网络是否连接并请求下载图片
- 用AdoDataSet实现数据表的导入导出
- 拒绝别人是一种煎熬
- 链式哈希表
- 关于本blog
- 招聘需求系列之四
- 分布式文件系统:原理、问题与方法
- Hibernate 加载主配置文件的代码
- Android项目开发总结(二)-- 架构篇
- LintCode统计前面比自己小的数的个数(线段树)
- Git 设置不需要用户名、密码直接push的操作
- 初步理解MVC与MVP