链式哈希表
来源:互联网 发布:中建六局 知乎 编辑:程序博客网 时间:2024/05/17 17:39
将数据存储在桶中-桶是链表。如果冲突,增大链表长度
需要用到我的链表
头文件
//// cntbl.h// hash//// Created by bikang on 16/9/22.// Copyright (c) 2016年 bikang. All rights reserved.//#ifndef __hash__cntbl__#define __hash__cntbl__#include "list.h"#include <stdlib.h>typedef struct CHTbl_{ int buckets;//桶的大小 unsigned int (*h)(const void *key);//哈希函数 int (*match)(const void *key1,const void *key2);//比较,匹配 void (*destroy)(void *data);//内存释放函数 int size;//数据的多少 List *table;}CHTbl;//初始化int chtbl_init(CHTbl *htbl,int buckets,int (*h)(const void *key),int(*match)(const void *k1,const void *k2),void(*destroy)(void*data));//销毁void chtbl_destroy(CHTbl *htbl);//插入int chtbl_insert(CHTbl *htbl,void *data);//删除int chtbl_remove(CHTbl *htbl,void **data);//查找int chtbl_lookup(CHTbl *htbl,void **data);//数据的多少#define chtbl_size(htbl) ((htbl)->size)#endif /* defined(__hash__cntbl__) */
实现
//// cntbl.c// hash//// Created by bikang on 16/9/22.// Copyright (c) 2016年 bikang. All rights reserved.//#include <stdio.h>#include <string.h>#include <stdlib.h>#include "cntbl.h"#include "list.h"//初始化int chtbl_init(CHTbl *htbl,int buckets,int (*h)(const void *key), int(*match)(const void *k1,const void *k2), void(*destroy)(void*data)){ int i; //初始化数据 if((htbl->table =(List*)malloc(sizeof(List)*buckets) ) == NULL) return -1; htbl->buckets = buckets; for(i=0;i<htbl->buckets;i++){ list_init(&htbl->table[i], destroy); } htbl->h = h; htbl->match = match; htbl->destroy = destroy; htbl->size = 0; return 0;}//释放数据void chtbl_destroy(CHTbl *htbl){ int i; for(i=0;i<htbl->buckets;i++){ list_destroy(&htbl->table[i]); } free(htbl->table); memset(htbl, 0, sizeof(CHTbl)); return;}//插入int chtbl_insert(CHTbl *htbl,void *data){ void *temp; int bucket,retval; temp = (void*)data; //是否存在,存在直接返回 if(chtbl_lookup(htbl, &temp) == 0) return 1; //找到hash key,我们采用除以余数的方法 bucket = htbl->h(data)%(htbl->buckets); //插入数据 if((retval= list_ins_next(&htbl->table[bucket], NULL, data)) == 0)htbl->size++; return 0;}//删除int chtbl_remove(CHTbl *htbl,void **data){ ListElmt *element=NULL,*prev=NULL; int bucket=0; bucket = htbl->h(*data)%htbl->buckets; for(element=list_head(&htbl->table[bucket]);element!= NULL;element=list_next(element)){ if (htbl->match(*data,list_data(element)) == 0) { //如果pre为空删除表头,否则删除pre的下一个元素 if(list_rem_next(&htbl->table[bucket], prev, data)==0){ htbl->size--; return 0; }else{ return -1; } } prev = element; } return -1;}//查找是否存在元素int chtbl_lookup(CHTbl *htbl,void **data){ ListElmt *element=NULL; int bucket=0; //printf("h->data=%d",htbl->h(*data)); //printf("data=%s",**(char**)data); bucket = htbl->h(*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;}
hash函数头文件及其实现
//// hashpjw.h// hash//// Created by bikang on 16/9/22.// Copyright (c) 2016年 bikang. All rights reserved.//#ifndef __hash__hashpjw__#define __hash__hashpjw__#define PRIME_TBLSIZ 4096unsigned int hashpjw(const void *key);#endif /* defined(__hash__hashpjw__) *///// hashpjw.c// hash//// Created by bikang on 16/9/22.// Copyright (c) 2016年 bikang. All rights reserved.//#include "hashpjw.h"unsigned int hashpjw(const void *key){ unsigned int val = 0; const char *ptr; ptr = (char*) key; while (*ptr != '\0') { unsigned int tmp; //往左移动4位,乘以16 val = (val << 4) + (*ptr); //printf("*ptr=%d,val=%d,",*ptr,val); //当val大于2^28位的时候,取前四位 if(tmp = (val & 0xf0000000)){ //printf("tmp=%d,",tmp); //val和val的前16位异或运算 val = val ^ (tmp >> 24); //val和val的28位异或运算 val = val ^ tmp; } //printf("new_val=%d,",val);printf("\n"); ptr++; } return val%PRIME_TBLSIZ;}
匹配函数及其头文件
//// match.h// hash//// Created by bikang on 16/9/22.// Copyright (c) 2016年 bikang. All rights reserved.//#ifndef __hash__match__#define __hash__match__#include <stdio.h>int match_int(const void *k1,const void *k2);int match_chars(const void *k1,const void *k2);#endif /* defined(__hash__match__) *///// match.c// hash//// Created by bikang on 16/9/22.// Copyright (c) 2016年 bikang. All rights reserved.//#include "match.h"#include <string.h>int match_int(const void *k1,const void *k2){ if(*(int*)k1 == *(int*)k2) { return 0; }else{ return -1; }}int match_chars(const void *k1,const void *k2){ if(strcmp((char*)k1,(char*)k2) == 0){ return 0; }else{ return -1; }}
测试代码
//// main.c// hash//// Created by bikang on 16/9/22.// Copyright (c) 2016年 bikang. All rights reserved.//#include <stdio.h>#include "hashpjw.h"#include "match.h"#include "cntbl.h"void thashpjw();void tres();void tcntble();int main(int argc, const char * argv[]) { printf("start\n"); //测试hash函数 thashpjw(); //tres(); tcntble(); return 0;}void tcntble(){ void **data; int findret; //新建一个hash表 CHTbl *t1 = malloc(sizeof(CHTbl)); chtbl_init(t1, 1024, hashpjw, match_chars, NULL); //插入几个数据 chtbl_insert(t1, "hello"); chtbl_insert(t1, "hello world"); chtbl_insert(t1, "struct"); chtbl_insert(t1, "cpp"); //删除一个数据 char str_test[4] = "cpp"; char *ptr = str_test; char **pptr = &ptr; //查找数据 findret = chtbl_lookup(t1,(void**)pptr); if(findret == 0){ puts("find ok\n"); }else{ puts("find faild\n"); } findret = chtbl_remove(t1, (void**)pptr); if(findret==0){ puts("delete sucess"); }else{ puts("delete faild"); } //查找数据 pptr = &ptr; findret = chtbl_lookup(t1,(void**)pptr); if(findret == 0){ puts("find ok\n"); }else{ puts("find faild\n"); } printf("chtbl_size=%d",chtbl_size(t1)); //销毁数据 chtbl_destroy(t1);}void tres(){ unsigned int res = 0; printf("res=%d,",(res << 4)& 0xf0000000); printf("\n");}void thashpjw(){ unsigned int res; res = hashpjw("adfasdd课啊"); char str_test[4] = "cpp"; char *ptr = str_test; res = hashpjw(ptr); printf("adfasdd convert to res=%d\n",res);}
0 0
- 链式哈希表
- 链式哈希表
- 哈希表的链式存储
- 链式哈希表的实现
- 9、链式哈希表
- PHP实现 拉链式哈希表
- 链式哈希表(Hash Table)--算法导论示例
- C++实现哈希表 HashMap冲突链式解决
- 10、链式哈希表的应用-符号表
- C 算法精介----哈希表->链式哈希表->分析与实现
- 小白书之移动小球哈希表的链式结构
- 线性表数据结构解读(六)链式哈希表结构-LinkedHashMap
- 链式队列
- 链式队列
- 链式队列
- 链式栈
- 链式栈
- 链式队列
- cordova创建第一个iOS程序实例
- 自定义scrollView实现顶部图片下拉放大
- java 字节流和字符流的区别 转载
- CSS overflow 属性
- uva 674(完全背包求方法数)@
- 链式哈希表
- jenkins 管理员密码重置
- JavaScript中undefined与null的区别
- spring mvc 实现网站登录与非登录的控制
- Fragment双层嵌套时,
- WIFI一键连接 iOS端 Configuration Profile 方式
- 欢迎使用CSDN-markdown编辑器
- setObject:ForKey:与setValue:ForKey:存值区别与联系
- 大数据可视化之矢量切片的生成及渲染