链式哈希表

来源:互联网 发布:中建六局 知乎 编辑:程序博客网 时间: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
原创粉丝点击