散列表

查询速度非常快的数据结构,查询时间复杂度是O(1)。

#ifndef _COMMON_H_
#define _COMMON_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#endif
common.h
#ifndef _HASH_H_
#define _HASH_H_

typedef unsigned int u_int;

typedef struct hash_s hash_t;
typedef u_int (*hash_func_t)(u_int bucket_size, const void *key, u_int key_size);

hash_t * hash_table_create(u_int bucket_size, hash_func_t hash_func);
void *hash_lookup_entry(hash_t *hash_table, void* key, u_int key_size);

void hash_add_entry(hash_t *hash_table, void *key, u_int key_size, void* value, u_int value_size);
void hash_free_entry(hash_t *hash_table, void *key, u_int key_size);

void travel(hash_t * table);

#endif
hash.h
#include "hash.h"
#include "common.h"


typedef struct hash_node_s
{
    void *key;
    void *value;
    struct hash_node_s *next;
}hash_node_t;

struct hash_s
{
    u_int bucket_size;
    hash_func_t hash_func;
    hash_node_t **pnodes;
};


hash_t * hash_table_create(u_int bucket_size, hash_func_t hash_func)
{
    hash_t * hash_table;

    hash_table = (hash_t *)malloc(sizeof(hash_t));

    hash_table->bucket_size = bucket_size;
    hash_table->hash_func = hash_func;
    hash_table->pnodes = (hash_node_t **)malloc(bucket_size * sizeof(hash_node_t *));
    memset(hash_table->pnodes, 0, bucket_size * sizeof(hash_node_t *));

    return hash_table;
}


void *hash_lookup_entry(hash_t *hash_table, void* key, u_int key_size)
{
    u_int index = hash_table->hash_func(hash_table->bucket_size, key, key_size);
    assert(index < hash_table->bucket_size);

    hash_node_t *pnode = hash_table->pnodes[index];
    while (pnode)
    {
        if (0 == memcmp(pnode->key, key, key_size))
        {
            return pnode->value;
        }
        pnode = pnode->next;
    }

    return NULL;
}


void hash_add_entry(hash_t *hash_table, void *key, u_int key_size, void* value, u_int value_size)
{
    u_int index = hash_table->hash_func(hash_table->bucket_size, key, key_size);
    assert(index < hash_table->bucket_size);

    hash_node_t *newnode = (hash_node_t*)malloc(sizeof(hash_node_t));
    newnode->key = malloc(key_size);
    memcpy(newnode->key, key, key_size);
    newnode->value = malloc(value_size);
    memcpy(newnode->value, value, value_size);

    if (hash_table->pnodes[index] == NULL)
    {
        newnode->next = NULL;
        hash_table->pnodes[index] = newnode;
    }
    else
    {
        newnode->next = hash_table->pnodes[index]->next;
        hash_table->pnodes[index]->next = newnode;
    }
}


void hash_free_entry(hash_t *hash_table, void *key, u_int key_size)
{
    u_int index = hash_table->hash_func(hash_table->bucket_size, key, key_size);
    assert(index < hash_table->bucket_size);

    hash_node_t *pnode = hash_table->pnodes[index];
    if (pnode != NULL)
    {
        if (memcmp(pnode->key, key, key_size) == 0)
        {
            hash_node_t **tmp = &hash_table->pnodes[index];
            *tmp = pnode->next;
            free(pnode->key);
            free(pnode->value);
            free(pnode);
        }
        else
        {
            hash_node_t *tmp = pnode;
            while (pnode && memcmp(pnode->key, key, key_size) != 0)
            {
                tmp = pnode;
                pnode = pnode->next;
            }
            if (pnode)
            {
                tmp->next = pnode->next;
                free(pnode->key);
                free(pnode->value);
                free(pnode);
            }
        }
    }
}


void travel(hash_t * table)
{
    for (int i = 0; i < table->bucket_size; i++)
    {
        hash_node_t *pnode = table->pnodes[i];
        while (pnode)
        {
            printf("%s ", (char*)pnode->key);
            pnode = pnode->next;
        }
        printf("
");
    }
    printf("
");
}
hash.c
#include "hash.h"
#include "common.h"


u_int BKDRHash(u_int bucket_size, const void *key, u_int key_size)
{
    size_t hash = 0;
    const char* tmp = key;
    int index = 0;
    char ch = -1;

    while (index != key_size)
    {
        ch = tmp[index];
        hash = hash * 131 + ch;
        index++;
    }

    return hash % bucket_size;
}


int main()
{
    hash_t * table = hash_table_create(3, BKDRHash);

    char * arr[][2] = {{"baidu", "liyanhong"}, {"ali", "mayun"}, {"tencent", "mahuateng"}, {"toutiao", "zhangyiming"}, {"meituan","wangxing"}, {"didi","chengwei"}};

    for (int i = 0; i < 6; i++)
    {
        hash_add_entry(table, arr[i][0], strlen(arr[i][0]), arr[i][1], strlen(arr[i][1]));
    }

    travel(table);

    char* company = "ali";
    char* ret = hash_lookup_entry(table, company, strlen(company));
    if (ret)
    {
        printf("%s
", ret);
    }

    char* tc = "baidu";
    hash_free_entry(table, tc, strlen(tc));
    travel(table);
    hash_add_entry(table, arr[2][0], strlen(arr[2][0]), arr[2][1], strlen(arr[2][1]));
    travel(table);



    return 0;
}
main.c
table: main.o hash.o
    gcc -g -o table main.o hash.o

main.o: main.c
    gcc -c -g main.c

hash.o: hash.c
    gcc -c -g hash.c

.PHONY:clean

clean:
    rm -f table main.o hash.o
Makefile
原文地址:https://www.cnblogs.com/zuofaqi/p/9801312.html