所谓的哈希表-散列方法

所谓的哈希表-散列方法就是一个结构体数组,一般的数组下表是012345,要找数据只能通过遍历;
    哈希的数组也是012345,但是这个下标号是通过key值换算得来的(这个映射函数叫做散列函数,存放记录的数组叫做散列表。)。
   通过key值换算成数组下标号,不需要遍历,直接找到数据;

下面是网上的一个c语言实现,比较简单,容易理解。

#ifndef _HASH_TABLE_H
#define _HASH_TABLE_H
#include <stdlib.h>
#include <memory.h>
#include <stdio.h>
#include <string.h>
#define HASH_TABLE_CAPACITY 20

typedef unsigned int uint;

/** hash table element*/
typedef struct _htItem{
    struct _htItem  *next;// 指向下一个的指针
    char *key_string;// key
    uint fid;// 记录值

} htItem;

/** init the hashTable 构造函数,申请哈希表的空间*/
void htInit(htItem **ht, uint length);

/** set hashTable element 哈希表中插入一个值*/
uint htSet(char *key, uint val, htItem **ht);

/** get element from hashtable 从哈希表中获得一个对应的key*/
htItem* htGet(char *key, htItem **ht);

/** Delete element from hashTable 从哈希表中删除一个key*/
int htDel(char *key, htItem **ht);

/** BKDR hash function 对string进行散列得到一个整数值*/
uint bkdrHash(char *key);

/** get the index of hash table 根据key计算一个整数值,然后获得对应的槽位*/
uint htIndex(char *key, htItem **ht);

/** get hashTable elements */
uint htLen(htItem **ht);

/*打印哈希表*/
void print_hashTable(htItem **ht);
#endif

 

#include <stdlib.h>
#include <stdio.h>
#include "hash.h"

/**************************************************************************************************
**	哈希表的类型是对一个string进行散列。
**	本哈希表使用的是开散列的办法,首先是一个指针数组,数组第一个位置中保存着哈希表的大小。
**	首先对string散列获得一个整数值,然后根据哈希表的大小计算所属的槽位,
**	然后再该槽位的链表上进行查找,如果找到则更新哈希值,如果未找到则在尾端插入。
**************************************************************************************************/

/*初始化HashTable*/
void htInit(htItem **ht, uint length){
    int i;
    for (i = 0; i<length; i++){
        ht[i] = (htItem*)malloc(sizeof(htItem));
        memset(ht[i], 0, sizeof(htItem));
    }
    ht[0]->fid = length;/*数组第一个位置中保存着哈希表的大小*/
}

/** get hashTable elements 进行对应的hash值的搜索,如果找到则返回该节点*/
htItem* htGet(char *key, htItem **ht){
    uint i = htIndex(key, ht);
    htItem *item = ht[i]->next;
    htItem *tmp = (htItem*)malloc(sizeof(htItem));
    memset(tmp, 0, sizeof(htItem));
	printf("htGet key = %s, index = %d\n",key,i);
    while (item)
    {
        if (strcmp(key, item->key_string) == 0){
            return item;
        }
        item = item->next;
    }
    return NULL;
}


/** set hashTable element 插入新的hash值*/
uint htSet(char *key, uint fid, htItem **ht){
    uint i = htIndex(key, ht);
    htItem *item = ht[i];
	printf("htSet key = %s, index = %d\n",key,i);
    while (item->next)
    {
		/*已经存在的话则直接更新值*/
        if (strcmp(key, item->next->key_string) == 0){
            item->next->fid = fid;
            return 0;
        }
        else{
            item = item->next;
        }
    }
    item->next = (htItem*)malloc(sizeof(htItem));
    item->next->fid = fid;
    item->next->key_string = key;
    item->next->next = NULL;
    return 0;
}

/** delete one element of hashtable  删除hash值*/
int htDel(char *key, htItem **ht){
    uint i = htIndex(key, ht);
    htItem *item = ht[i];
	printf("htDel key = %s, index = %d\n",key,i);
    while (item->next){
        if (strcmp(key, item->next->key_string) == 0){
            htItem *tmp = item->next;
            item->next = tmp->next;
            free(tmp);
            return 0;
        }
        item = item->next;
    }
    return -1;
}

/** BKDR hash function  对字符串进行散列,得到一个整数的hash值*/
uint bkdrHash(char *key)
{
    uint seed = 131;
    uint hash = 0;
	int iRet = 0;
    while (*key != '\n' && *key != 0)
    {
        hash = hash * seed + (*key++);
		printf("bkdrHash:while key %s,tmp hash %d\n",key,hash);
    }
	iRet = (hash & 0x7FFFFFFF);
	printf("bkdrHash:key %s,hash %d,iRet %d\n",key,hash,iRet);
    return iRet;
}
/** get the index of hash table  根据得到的hash值选择一个槽位置*/
uint htIndex(char *key, htItem **ht){
	int iRet = 0;
    uint hashedKey = bkdrHash(key);
    uint length = (ht[0]->fid - 1);
	iRet = (uint)hashedKey % length + 1;
	printf("htIndex:key %s,iRet %d\n",key,iRet);
    return iRet;
}

/** get element number in the hashtable */
uint htLen(htItem **ht){
    uint alength = ht[0]->fid;
    uint i, length = 0;
    for (i = 1; i < alength; i++){
        if (ht[i]->next) {
            length++;
        }
    }
    return length;
}

/** get capacity of hashtable */
uint htCapacity(htItem **ht)
{
    return ht[0]->fid;
}

void print_hashTable(htItem **ht)
{
    uint length = ht[0]->fid;
    uint i;
    htItem *item;
	
	printf("\n============ Printf all table =============\n");
	
    for (i = 1; i < length; i++)
    {
        item = ht[i]->next;
        while (item)
        {
            printf("all %s => fid = %d, index = %d\n", item->key_string, item->fid, i);
            item = item->next;
        }
    }
	printf("================= End ==================\n\n");
}



int main()
{
    htItem *item[101];
    htInit(item, 101);

    htSet("aaa", 100, item);
    htSet("bbb", 1000, item);
    htSet("ccc", 99, item);
    htSet("ddd1", 199, item);
    htSet("ddd2", 299, item);
    htSet("ddd3", 399, item);
    htSet("ddd4", 499, item);
    htSet("ddd5", 599, item);
    htSet("ddd6", 699, item);
    htSet("ddd7", 799, item);
    htSet("ddd8", 899, item);
    htSet("ddd9", 999, item);
    htSet("ddd10", 1099, item);
    htSet("ddd11", 1199, item);
    htSet("ddd12", 1299, item);
    htSet("ddd13", 1399, item);

	print_hashTable(item);

    htItem *tmp = htGet("aaa", item);
    htItem *tmp1 = htGet("bbb", item);
    htItem *tmp2 = htGet("ccc", item);
	printf("\nGeting aaa,bbb,ccc...\n");
	printf("tmp1: Key %s => %d\n", tmp->key_string, tmp->fid);
    printf("tmp2: Key %s => %d\n", tmp1->key_string, tmp1->fid);
    printf("tmp3: Key %s => %d\n", tmp2->key_string, tmp2->fid);

    printf("\nDelete bbb ...\n");
    htDel("bbb", item);


    print_hashTable(item);

    htItem *tmp3 = htGet("bbb", item);

    printf("tmp3 pointer:%u\n", tmp3);

    if (tmp3) {
        printf("Key %s => %d\n", tmp3->key_string, tmp3->fid);
    }
}




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值