开发地址哈希

头文件

//
//  ohash.h
//  ohash
//
//  Created by bikang on 16/9/23.
//  Copyright (c) 2016年 bikang. All rights reserved.
//

#ifndef __ohash__ohash__
#define __ohash__ohash__

#include <stdlib.h>

typedef struct OHTbl_{
    int positions;//数据个数
    void *vacated;//哨兵--指向不可用的元素

    int (*h1)(const void *key);//哈希函数
    int (*h2)(const void *key);//哈希函数
    int (*match)(const void *key1,const void *key2);//比较,匹配
    void (*destroy)(void *data);//内存释放函数

    int size;//数据的多少
    void **table;//数据

}OHTbl;


int ohtbl_init(OHTbl *htbl,int positions,int (*h1)(const void *key),int (*h2)(const void *key),
               int(*match)(const void *k1,const void *k2),
               void(*destroy)(void*data));

//销毁
void ohtbl_destroy(OHTbl *htbl);
//插入
int ohtbl_insert(OHTbl *htbl,const void *data);
//删除
int ohtbl_remove(OHTbl *htbl,void **data);
//查找
int ohtbl_lookup(OHTbl *htbl,void **data);

#define ohtbl_size(htbl) ((htbl)->size)
#endif /* defined(__ohash__ohash__) */

实现代码

//
//  ohash.c
//  ohash
//
//  Created by bikang on 16/9/23.
//  Copyright (c) 2016年 bikang. All rights reserved.
//

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "ohash.h"


static char vacated;

int ohtbl_init(OHTbl *htbl,int positions,int (*h1)(const void *key),int (*h2)(const void *key),
               int(*match)(const void *k1,const void *k2),
               void(*destroy)(void*data)){

    int i;
    if((htbl->table = (void**)malloc(positions*sizeof(void*))) == NULL) return -1;

    htbl->positions = positions;

    for (i=0; i<htbl->positions; i++) {
        htbl->table[i] = NULL;
    }
    htbl->vacated = &vacated;

    htbl->h1 = h1;
    htbl->h2 = h2;
    htbl->match = match;
    htbl->destroy = destroy;
    htbl->size = 0;
    return 0;
}

//销毁
void ohtbl_destroy(OHTbl *htbl){
    int i ;
    if(htbl->destroy != NULL){
        for (i = 0;i< htbl->positions ; i++) {
            if(htbl->table[i] != NULL && htbl->vacated != htbl->table[i])htbl->destroy(htbl->table[i]);
        }
    }
    free(htbl->table);
    memset(htbl, 0, sizeof(OHTbl));
    return;
}

//插入,
int ohtbl_insert(OHTbl *htbl,const void *data){
    void *temp;
    int position,i;

    if(htbl->size == htbl->positions) return -1;

    temp = (void*) data;
    if(ohtbl_lookup(htbl, &temp) == 0) return 1;
    for(i = 0;i<htbl->positions;i++){
        position = (htbl->h1(data)+(i*htbl->h2(data)))%htbl->positions;
        if(htbl->table[position] == NULL || htbl->table[position] == htbl->vacated){
            //puts("add");
            htbl->table[position] = (void*)data;
            //printf("htbl->table[%d]=%s\n",position,data);
            htbl->size++;
            return 0;
        }
    }
    return -1;
}

//删除
int ohtbl_remove(OHTbl *htbl,void **data){
    int position,i;

    for(i = 0;i<htbl->positions;i++){
        position = (htbl->h1(*data)+(i*htbl->h2(*data)))%htbl->positions;
        if(htbl->table[position] == NULL){
            return 0;
        }else if(htbl->table[position] == htbl->vacated){
            continue;
        }else if(htbl->match(htbl->table[position],*data) == 0){
            *data = htbl->table[position];
            htbl->table[position] = htbl->vacated;
            htbl->size--;
            return 0;
        }
    }

    return 0;
}

//查找
int ohtbl_lookup(OHTbl *htbl,void **data){
    int position,i;
    for(i = 0;i<htbl->positions;i++){
        position = (htbl->h1(*data)+(i*htbl->h2(*data)))%htbl->positions;
        //printf("positions=%d, ",position);

        if(htbl->table[position] == NULL){
            return -1;
        }else if(htbl->match((char*)htbl->table[position],*data) == 0){
            *data = htbl->table[position];
            return 0;
        }
    }
    return -1;
}




测试代码

//
//  main.c
//  ohash
//
//  Created by bikang on 16/9/23.
//  Copyright (c) 2016年 bikang. All rights reserved.
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ohash.h"

#define PRIME_TBLSIZ 1024

int match_chars(const void *k1,const void *k2){
    if(strcmp((char*)k1,(char*)k2) == 0){
        return 0;
    }else{
        return -1;
    }
}
unsigned int hashpjw(const void *key){

    unsigned int val = 0;
    const char *ptr;
    ptr = (char*) key;

    while (*ptr != '\0') {
        unsigned int tmp;
        val = (val << 4) + (*ptr);
        if(tmp = (val & 0xf0000000)){
            val = val ^ (tmp >> 24);
            val = val ^ tmp;
        }
        ptr++;
    }
    return val%PRIME_TBLSIZ;
}


int h1(const void*key){
    unsigned int  key1 = hashpjw(key);
    return key1%4096;
}

int h2(const void*key){
    unsigned int key1 =hashpjw(key)%4096;

    if(key1 %2 == 0){
        return key1+1;
    }
    return key1;
}

void print_table(OHTbl *t){
    int i;
    for(i = 0; i< t->positions;i++){
        printf("t->positions[%d]=%s\n",i,t->table[i]);
    }
    return;
}

// m 必须 是 2 次幂, 让 h2 返回 一个 奇 数值
int main(int argc, const char * argv[]) {

    int findret;

    OHTbl *t1 = (OHTbl *)malloc(sizeof(OHTbl));
    //初始化
    ohtbl_init(t1, 64, h1, h2, match_chars, NULL);
    //插入几个数据
    char *s1 = "hello";
    char *s2 = "hello world";
    char *s3 = "struct";
    char *s4 = "cpp";
    ohtbl_insert(t1, s1);
    ohtbl_insert(t1, s2);
    ohtbl_insert(t1, s3);
    ohtbl_insert(t1, s4);
    printf("chtbl_size=%d\n",ohtbl_size(t1));
    //删除一个数据
    //print_table(t1);

    //return 1;
    //查找数据
    findret = ohtbl_lookup(t1,(void**)&s4);
    if(findret == 0){
        puts("find ok\n");
    }else{
        puts("find faild\n");
    }
    //return 1;
    char str_test[4] = "cpp";
    char *ptr = str_test;
    char **pptr = &ptr;
    findret = ohtbl_remove(t1, (void**)pptr);
    if(findret==0){
        puts("delete sucess");
    }else{
        puts("delete faild");
    }
    //查找数据
    pptr = &ptr;
    findret = ohtbl_lookup(t1,(void**)pptr);
    if(findret == 0){
        puts("find ok\n");
    }else{
        puts("find faild\n");
    }
    printf("chtbl_size=%d",ohtbl_size(t1));
    //销毁数据
    ohtbl_destroy(t1);

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值