哈希表(散列)的实现方法

哈希表(散列)的实现方法


哈希表(散列)具有一种高效随机存取数据的特点。哈希表的主要思想是通过一个哈希函数,在所有可能的健与槽位之间建立一张映射表。哈希函数每次接受一个健将返回与健相对应的哈希编码或哈希值。健的数据类型可能多种多样,但哈希值的类型只能是整形。
本文主要讨论链式哈希表:

内村中结构图如下所示:

这里写图片描述

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

#define TABLESIZE 100

# ifndef _HashSep_H
struct _ListNode;
typedef struct _ListNode ListNode;
struct _HashTable;
typedef struct _HashTable HashTable;
struct _ELE_t;
typedef struct _ELE_t ELE_t;

int NextPrime( int );
int Hash( const char *, int );
HashTable *InitTable( int );
ListNode *Search( char *, HashTable * );
void Insert( char *, char *, HashTable * );
void Delete( char *, HashTable * );
# endif

struct _ELE_t {
    char words[32];
    char desc[60];
};

struct _ListNode {
    ELE_t     ele;
    ListNode  *next;
};

struct _HashTable {
    unsigned int TableSize;
    ListNode     *HashList;
};


int NextPrime( int TableSize )
{
    unsigned int flag = 1, tril = TableSize;

    while ( 1 ) {
        ++tril; flag = 1;
        for ( int i=2; i < tril; ++i ) {
            if ( tril % i == 0 ) {
                flag = 0; break;
            }
        }
        if ( flag ) return tril;
    }
}

int Hash( const char *key, int TableSize )
{
    unsigned int HashVal = 0;

    while ( *key != '\0' )
        HashVal = (HashVal << 5) + *key++;
    return HashVal % TableSize;
}

HashTable *InitTable( int TableSize )
{
    HashTable *H;

    H = (HashTable *)malloc(sizeof(HashTable));
    if ( !H )
        fprintf(stderr, "[Err::%s] Failed to allocate memory\n", __func__);
    H->TableSize = NextPrime(TableSize);

    H->HashList = (ListNode *)calloc(H->TableSize, sizeof(ListNode));
    if ( !H->HashList )
        fprintf(stderr, "[Err::%s] Failed to allocate memory\n", __func__);

    return H;
}


ListNode *Search( char *key, HashTable *H )
{
    ListNode *p;

    p = &H->HashList[Hash(key, H->TableSize)];
    while ( p && strcmp(key, p->ele.words) )
        p = p->next;

    return p;
}

void Insert( char *key, char *desc, HashTable *H )
{
    ListNode *node, *tmp, *new;

    node = &H->HashList[Hash(key, H->TableSize)];
    if ( !strlen(node->ele.words) ) { /* the first head node is empty */
        strcpy(node->ele.words, key); strcpy(node->ele.desc, desc);
        return ;
    }
    tmp = node->next;
    while ( tmp && strcmp(key, tmp->ele.words) ) {
        node = tmp; tmp = tmp->next;
    }
    if ( !tmp ) { /* the key is not found in the hashtable */
        new = (ListNode *)calloc(1, sizeof(ListNode));
        if ( !new ) {
            fprintf(stderr, "[Err::%s] Failed to allocate memory\n", __func__);
            exit(-1);
        }
        strcpy(new->ele.words, key); strcpy(new->ele.desc, desc);
        node->next = new;
    }
    else /* update the value for the existed key */
        strcpy(tmp->ele.desc, desc);
}

void Delete( char *key, HashTable *H )
{
    ListNode *node, *tmp;

    node = &H->HashList[Hash(key, H->TableSize)];
    if ( !strcmp(key, node->ele.words) ) {
        tmp = node->next; memset(node, 0, sizeof(ListNode));
        node->next = tmp;
        return ;
    }

    tmp = node->next;
    while ( tmp && strcmp(key, tmp->ele.words) ) {
        node = tmp; tmp = tmp->next;
    }
    if ( !tmp ) // Can't find the key
        fprintf(stderr, "[Err::%s] The key doesn't existed!\n", __func__);
    else if ( !tmp->next ) { // the node is the last one
        node->next = NULL; free(tmp);
    }
    else { // the node is within the linklist
        node->next = tmp->next; free(tmp);
    }
}

int main( void )
{
    ListNode *node;
    HashTable *table;
    char words[32], desc[60];

    /* Initinal the hashtable */
    table = InitTable(TABLESIZE);

    /* Input the data form keyeboard */
    for ( int i=0; i < 2; ++i ) {
        printf("Input key: "); fgets(words, 32, stdin);
        printf("Input descion: "); fgets(desc, 60, stdin);
        Insert(words, desc, table);
    }

    /* Delete a node from the hashtable */
    printf("Delete a node key: "); fgets(words, 32, stdin);
    Delete(words, table);

    /* Search the node from the hashtable */
    for ( int i=0; i < 2; ++i ) {
        printf("key: "); fgets(words, 32, stdin);
        node = Search(words, table);
        if ( !node )
            printf("Can't find the key!\n");
        else
            printf("Result: %s", node->ele.desc);
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值