哈希表

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表
给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。
 
哈希表用来处理key-value的,这个表用来存储key-value(键值对),通过散列函数f(key)可定位key-value在表中存贮的位置,从而更快的访问到key-value。
表中的key-value查找的速度是哈希表性能的一大依据,主要还是散列函数的构造。构造散列函数的方法很多。
不同key值通过f(key)可能得到相同的哈希值,这样两组或多组key-value就出现了冲突,这种现象称为碰撞(英语:Collision)。处理冲突的方法可为开放定址法、再哈希法、链表法、建立一个公共溢出区等。
 
uthash是C语言比较优秀的开源代码。它实现了常见的hash函数,例如插入、查找、删除等功能。它支持C语言的任意数据类型做为key值,无论是基本数据类型还是自定义的struct,但是不同类型的key其操作接口方式略有不同,而且它甚至可以采用多个值作为key。由于该代码采用宏的方式实现,所有的实现代码都在uthash.h文件中,因此只需要在自己的代码中包含"uthash.h"头文件即可。
uthash不仅实现了hash,还实现了utlist、utarray、utringbuffer、utstack、ustring等。
 
下面是一个哈希表方法访问字符串型key-value(uboot中使用的方法):

struct ram_tuple *ram_hash[256];

#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))

static unsigned int hash(const char *s)
{
    unsigned int hash = 0;

    while(*s)
    {
        hash = 31 * hash + *s++;
    }

    return hash;
}
char *_ram_get(const char *name)
{
    unsigned int i;
    struct ram_tuple *t;
    char *value;

    if(name == NULL)
        return NULL;

    i = hash(name) % ARRAYSIZE(ram_hash);

    for(t=ram_hash[i]; t && strcmp(t->name, name); t=t->next);
    value = t ? t->value : NULL;

    return value;
}
void _ram_free(void)
{
    unsigned int i;
    struct ram_tuple *t, *next;

    for(i = 0; i < ARRAYSIZE(ram_hash); i++)
    {
        for(t= ram_hash[i]; t; t=next)
        {   
            next = t->next;
            free(t->name);
            free(t->value);
            free(t);
        }   
        ram_hash[i] = NULL;
    }   
}
int _ram_set(const char *name, const char *value)
{
    unsigned int i;
    struct ram_tuple *t, *u, **prev;

    i = hash(name) % ARRAYSIZE(ram_hash);

    for(prev = &ram_hash[i], t = *prev;\
        t && strcmp(t->name, name); \
        prev = &(t->next), t = *prev);

    if( (u = _ram_realloc(t, name, value)) == NULL)
    {
        return -12; /* -ENOMEM*/
    }

    if(t && t == u)
    {
        return 0;
    }

    u->next = ram_hash[i];
    ram_hash[i] = u;

    return 0;
}

 

参考:
1. 百度百科 http://www.cnblogs.com/jiewei915/archive/2010/08/09/1796042.html
posted @ 2016-11-27 14:49  yuxi_o  阅读(353)  评论(0编辑  收藏  举报