hash表

本文深入探讨了哈希表的基本原理及其在redbase数据库源码中的应用,详细讲解了哈希函数的设计要点,并通过具体代码实例展示了哈希表的创建、插入、查找及删除等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    最近在读redbase数据库源码,涉及了hash表内容,重新温习了下hash表内容,在这里做下总结。

     hash表实现关键点:keyValue实现,结构体,链表,指针正确使用(在实现删除node代码时,由于出现链表已无node仍将node->data赋值给变量,出现core dump)

哈希函数

    哈希函数是一种计算方法,它可以把一个值A映射到一个特定的范围[begin, end]之内。对于一个值的集合{k1, k2, … , kN},哈希函数把他们均匀的映射到某个范围之中。这样,通过这些值就可以很快的找到与之对应的映射地址{index1, index2, … , indexN}。对于同一个值,哈希函数要能保证对这个值的运算结果总是相同的。

    哈希函数的实现是一个比较重要的点,其应该尽量保证让数据均匀分布而不是使hash(key)集中于某些数值。不管哈希函数如何实现,在大数据量的情况下,不可避免的是总会有不同的key得到相同的hash(key)即相同的哈希地址,称之为冲突(collision),具有相同函数值的关键字称之为同义词。针对出现相同hash(key)的情况,可以使用链表解决冲突。

    最简单的哈希函数就是一个求余运算:  hash(key) = key % N。这样就把key这个值映射到了[0~N-1]这样一个范围之中。

哈希表

    哈希函数的实现是哈希表的核心。

    哈希表是一中数据结构,它把KEY 和 VALUE用某种方式对应起来。使用hash()函数把一个KEY值映射到一个index上,即hash(KEY) = index。这样就可以把一个KEY值同某个index对应起来。然后把与这个KEY值对应的VALUE存储到index所标记的存储空间中。这样,每次想要查找KEY所对应的VALUE值时,只需要做一次hash()运算就可以找到了。

代码

不足之处:计算keyValue应该独立成1个函数形式,这样也便于更改实现不同的hash函数

 

/*
*  
*  2014.11.03
*/
#include <stdio.h>
#include <malloc.h>
#include <error.h>
#include <string.h>
#include <stdlib.h>

//数据类型
#define dataType int

#ifndef bool
typedef int bool;
#endif

#ifndef false
#define false 0
#endif

#ifndef true
#define true 1
#endif

#define mod 4

//定义节点
typedef struct NODE
{
    dataType data;
    struct NODE *next;
}node;

//定义hash表
typedef struct HASHTABLE
{
    node *modArray[mod];
}hashTable;

//创建哈希表
hashTable *initHashTable(void)
{
    hashTable *pHashTable = (hashTable *)malloc(sizeof(hashTable));
    if(NULL == pHashTable)
    {
        perror("malloc hashTable errror.\n");
        return NULL;
    }
    memset(pHashTable,0,sizeof(hashTable));
    return pHashTable;
}

//查找数据
node *searchDataInHashTable(hashTable *pHashTable, const dataType data)
{
        //判断pHashTable不为NULL,hash表已经初始化
         if(NULL == pHashTable)
	{
	    return NULL;
	}
	//
	node *pNode;
	if(NULL == (pNode=pHashTable->modArray[data%mod]))
	{
	    return NULL;
	}
	while(pNode)
	{
	    if(data==pNode->data)
		{  
		    return pNode;
                    
		}
	    pNode=pNode->next;
	}
        //pNode->next=NULL仍未查找到
	return NULL;

}


//hash表插入数据
bool insertDataIntoHashTable(hashTable *pHashTable, const dataType data)
{
        if(NULL == pHashTable)
	{
	    return false;
	}
	node *pNode;
	if(NULL == (pNode=pHashTable->modArray[data%mod]))
         {
	    if(NULL == (pNode=(node *)malloc(sizeof(node))))
		{
		    perror("malloc node error.\n");
			return false;
		}
		memset(pNode,0,sizeof(node));
		pNode->data=data;
		pHashTable->modArray[data%mod]=pNode;
		return true;
	}	
    
	//若要插入数据已经在hash表中存在
	if(NULL != searchDataInHashTable(pHashTable,data))
	{
	    fprintf(stderr,"the data has already in hash table.\n");
		return true;
	}
	//data在hash表中不存在且不为链表首部
	node *tempNode;
	tempNode=pHashTable->modArray[data%mod];
	while(tempNode->next)
	{
	    tempNode=tempNode->next;
	}
	pNode=(node *)malloc(sizeof(node));
	if(NULL == pNode)
	{
	    perror("malloc node error.");
		fprintf(stderr,"malloc node error at line : %d\n", __LINE__);
		return false;
	}
	memset(pNode,0,sizeof(node));
	pNode->data=data;
	pNode->next=NULL;
	tempNode->next=pNode;
	return true;
}

//hash表删除数据
bool deleteDataFromHashTable(hashTable *pHashTable, const dataType data)
{
        if(NULL == pHashTable || NULL == pHashTable->modArray[data%mod])
	{
	    return false;
	}
	//hash表中若查找不到该数据
	node *pNode;
	if(false == (pNode=searchDataInHashTable(pHashTable,data)))
	{
	    return false;
	}
	//若pNode在首部
	//if(pNode == pHashTable->modArray[data%mod])
	if(pNode == pHashTable->modArray[data%mod])
	{
	    pHashTable->modArray[data%mod]=pHashTable->modArray[data%mod]->next;
	    goto final;
	}
	
	//data在非首部
	node *tempNode=pHashTable->modArray[data%mod];
	while(pNode != tempNode->next)
	{
	    tempNode=tempNode->next;
	}
	tempNode->next=pNode->next;
	
final:
	free(pNode);
	pNode=NULL;
	return true;
}

//删除hash表
bool destoryHashTable(hashTable *pHashTable)
{

    if(NULL == pHashTable)
        return false;
    int i=0;
    for(i=0;i<mod;++i)
    {
        while(NULL != pHashTable->modArray[i])
        {  
            dataType temp=pHashTable->modArray[i]->data;
            deleteDataFromHashTable(pHashTable,temp);
        }

    }
 
    return true;
}

//显示hash table内容
bool showHashTable(hashTable *pHashTable)
{

    if(NULL == pHashTable)
        return false;
    int i=0;
    for(i=0;i<mod;++i)
    {
	    node *pNode;
		pNode=pHashTable->modArray[i];
        while(NULL != pNode)
        {  
            dataType temp=pNode->data;
            fprintf(stdout," %d ",temp);
			pNode=pNode->next;
        }
        fprintf(stdout,"\n");

    }
 
    return true;
}



int main()
{
    hashTable *pHashTable = initHashTable();
    if (NULL == pHashTable)
    {
	     fprintf(stderr,"create hashTable error.\n");
	     exit(1);
    }
    int intArray[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};
    int i=0;
	
    //test insert 
    for(i=0;i<sizeof(intArray)/sizeof(int);++i)
    {
	     if(false == (insertDataIntoHashTable(pHashTable,intArray[i])))
       {
          fprintf(stderr,"insert into hash table error.\n");
	        exit(1);
	      }
        else
        {
          fprintf(stdout,"insert %d\n",intArray[i]);
        }
    }
	
    //test search
    node *pNode;
    if(NULL == (pNode=searchDataInHashTable(pHashTable,12)))
    {
	      fprintf(stderr,"search from hash table error.\n");
        exit(1);
    }
    else
    {
	      printf("search : %d\n",pNode->data);
    }
	
    //test delete
    if(false == deleteDataFromHashTable(pHashTable,12))
    {
	      fprintf(stderr,"delete from hash table error.\n");
	      exit(1);
    }
    else
    {
        fprintf(stdout,"delete 12\n"); 
    }

    //show hash table
    if(false == showHashTable(pHashTable))
    {
        fprintf(stderr,"show hash table error.\n");
    }
    else
    {
       fprintf(stdout,"show hash table ok.\n");
    }

    //drop hash table
    if(false == destoryHashTable(pHashTable))
    {
	fprintf(stderr,"drop hash table error.\n");
      	exit(1);
    }
    else
    {
        fprintf(stdout,"drop hash table ok.\n");
    }
	
}

 

阅读篇

 阅读《数据结构》(严蔚敏p251)

 阅读《算法导论》(charpter 11.散列表) 


 

参考

一致性哈希算法  http://www.nowamagic.net/librarys/veda/detail/1336

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值