拉链法哈希表实现

转自:http://t.zoukankan.com/lizhanwu-p-4303410.html

1.拉链法代码实现

所想插入的类型:

    char* names[]={"First Name","Last Name","address","phone","k101","k110"};
    char* descs[]={"Kobe","Bryant","USA","26300788","Value1","Value2"};
    
    for(int i=0; i < 6; ++i)
        insert(names[i], descs[i]);

桶中节点类型定义:

typedef struct node{
    char *name;//字段名
    char *desc;//描述
    struct node *next;
}node;

插入函数:

static node* hashtable[HASHSIZE];//定义一个哈希数组,每个值表示存放的桶的头结点指针,每个桶都会形成一个链表
int insert(char* name, char* desc)
{
    unsigned int hashvalue;
    hashvalue = hash(name);//首先通过哈希函数获取到地址,即所在的桶
    //头插法,不管该hash位置有没有其他结点,直接插入结点
    node* np = malloc_node(name, desc);
    if (np == NULL) return 0;//分配结点没有成功,则直接返回
    np->next = hashtable[hashvalue];
    hashtable[hashvalue] = np;
    return 1;
}

node* malloc_node(char* name, char* desc)
{//在堆上为结点分配内存,并填充结点
    node *np=(node*)malloc(sizeof(node));
    if(np == NULL)
        return NULL;
    np->name = name;
    np->desc = desc;
    np->next = NULL;
    return np;
}

将字符串映射为整型地址的散列函数:

unsigned int hash(char *s)
{//哈希函数
    unsigned int h=0;
    for(;*s;s++)
        h=*s+h*31;//将整个字符串按照特定关系转化为一个整数,然后对hash长度取余
    return h%HASHSIZE;
}

查询特定的字符串对应的存储内容:

search("k110");

char* search(char* name)
{//对hash表查找特定元素(元素是字符串)
    node* np=lookup(name);
    if(np==NULL)
        return NULL;
    else
        return np->desc;
}

node* lookup(char *str)
{
    unsigned int hashvalue = hash(str);
    node* np = hashtable[hashvalue];
    for( ; np!=NULL; np = np->next)
    {//这里是链地址法解决的冲突,返回的是第一个链表结点
        if(!strcmp(np->name, str))//strcmp相等的时候才返回0
            return np;//它是通过比较关键字key在同一个桶内的链表中查找到所需节点的,并且返回value值
    }
    return NULL;
}
原文地址:https://www.cnblogs.com/BlueBlueSea/p/14887034.html