双端链表实现hash(哈希)

来源:互联网 发布:js中数组的indexof 编辑:程序博客网 时间:2024/05/29 00:34

     hash表又称为散列表,很多的地方都用到了这个东西,js中的对象,java中的键值对,python中的字典,hash结合了数组和链表的优点,在查找,存储有很大的优势。以我的理解来说,通过相应的键,找到相对应的值,数组的优点快啊,存储采用链表,节省空间,插入删除方便,这次我用整数模拟一下,简单的hash函数,仅仅对数字进行取余,把取余相同的放在一个区域里面,也就是说,一个键可以对应多个值

   hash.h文件的声明

#ifndef _HASH_H_#define _HASH_H_#include "dlist.h"#include "tools.h"typedef int (*Hash_func)(const void *key);//hash表的控制信息typedef struct Hash{    int   bucket_size;    //1.需要桶(链表)的数量    int element_count;    //2.hash表内元素的数量    Dlist     **table;    //3.hash表的实际存储区域        //free、match、hash_func(散列元素的具体操作)    void (*hash_free)(const void *ptr);          Boolean (*hash_match)(const void *value1,                           const void *value2);    int (*hash_func)(const void *key);}Hash;//暴雪hash算法//生成随机数表进行hash//hash表的接口Hash    *init_hash(int b_size, Hash_func h_func)  ;    //hash表的初始化void    destroy_hash(Hash **hash)                 ;    //hash表的销毁Boolean hash_insert(Hash *hash, const void *value);    //hash表的插入Boolean hash_search(Hash *hash, const void *value);    //hash表的查找Boolean hash_remove(Hash *hash, const void *value);    //hash表的删除int     get_element_count(const Hash *hash)       ;    //得到hash表的元素数量void    show_hash_table(const Hash *hash,                        Print_func print)         ;    //显示hash表的元素信息#endif

hash.c文件的实现

#include "hash.h"//hash表的接口Hash    *init_hash(int b_size, Hash_func h_func)      //hash表的初始化{    Hash *hash = (Hash *)Malloc(sizeof(Hash));    hash->bucket_size = b_size;    hash->element_count = 0;    hash->hash_free = NULL;    hash->hash_match = NULL;    hash->hash_func = h_func;    //申请桶的个数由b_size决定    hash->table = (Dlist **)Malloc(sizeof(Dlist *) * b_size);    bzero(hash->table, sizeof(Dlist *) * b_size);    //关于双端链表的初始化在被使用的时候进行,这样做是为了节省效率    return hash;}void    destroy_hash(Hash **hash)                     //hash表的销毁{    int i = 0;    int bucket_size = 0;    Hash *p_hash = NULL;    if(hash == NULL || *hash == NULL){        return ;    }    //销毁操作:    //  1.销毁每一个双端链表    p_hash = *hash;    bucket_size = p_hash->bucket_size;    for(i = 0; i < bucket_size; ++i){        destroy_dlist(&(p_hash->table[i]));    }    //   2.销毁hash->table    free(p_hash->table);    //   3.销毁hash控制信息    free(p_hash);    *hash = NULL;}Boolean hash_insert(Hash *hash, const void *value)    //hash表的插入{    int b_index = 0;    if(hash == NULL || value == NULL    || hash_search(hash, value)){            //不得对重复元素进行插入,如果该元素已经存在于hash表,则直接退出        return FALSE;    }    //通过hash函数确定value插入的链表    b_index = hash->hash_func(value) % hash->bucket_size;    if(hash->table[b_index] == NULL){        hash->table[b_index] = init_dlist();    }    //对value进行插入操作(尾插)    push_back(hash->table[b_index], (void *)value);    hash->element_count++;    return TRUE;}Boolean hash_search(Hash *hash, const void *value)    //hash表的查找{    int        b_index = 0   ;    Dlist_node *p_node = NULL;    if(hash == NULL || value == NULL){        return FALSE;    }     b_index = hash->hash_func(value) % hash->bucket_size;        //如果该链表不存在,则需要进行初始化    if(hash->table[b_index] == NULL){        return FALSE;    }    //在该链表中进行查找,从头到尾遍历    if(hash->hash_match != NULL){        for(p_node = hash->table[b_index]->head;        p_node ;        p_node = p_node->next){            if(hash->hash_match(p_node->data, value)){                return TRUE;            }            }    }else{        for(p_node = hash->table[b_index]->head;        p_node ;        p_node = p_node->next){            if(p_node->data == value){                return TRUE;            }            }    }       return FALSE;}Boolean hash_remove(Hash *hash, const void *value)    //hash表的删除{    int b_index = 0;    Dlist_node *p_node = NULL;    if(hash == NULL || value == NULL || hash->element_count == ZERO){        return FALSE;    }    b_index = hash->hash_func(value) % hash->bucket_size;        if(hash->hash_match != NULL){        for(p_node = hash->table[b_index]->head;        p_node ;        p_node = p_node->next){            if(hash->hash_match(p_node->data, value)){                remove_dlist_node(hash->table[b_index], p_node, NULL);                hash->element_count--;                return TRUE;            }            }    }else{        for(p_node = hash->table[b_index]->head;        p_node ;        p_node = p_node->next){            if(p_node->data == value){                remove_dlist_node(hash->table[b_index], p_node, NULL);                hash->element_count--;                return TRUE;            }            }    }    return TRUE;    }int     get_element_count(const Hash *hash)           //得到hash表的元素数量{    if(hash == NULL){         return -1;    }    return hash->element_count;}void    show_hash_table(const Hash *hash, Print_func print)             //显示hash表的元素信息{    int i = 0;    int bucket_size = 0;    if(hash == NULL || hash->element_count == ZERO){         return ;    }    //从hash表的第一个链表打印到最后一个链表    bucket_size = hash->bucket_size;    for(i = 0; i < bucket_size; ++i){         printf("bucket[%d]:", i);         show_dlist(hash->table[i], print);    }}


0 0
原创粉丝点击