C语言实现HashMap

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013799749/article/details/75674985

C语言实现HashMap

       在做算法题时,需要使用到HashMap这种数据结构,虽然高级语言中大都实现了这种数据结构,但是为了理解HashMap的底层原理,于是打算自己实现HashMap,使用C语言实现了HashMap的创建(CreateHashMap)、取键值对(Get)、插入键值对(Put)、输出(PrintHashMap)以及销毁(DestoryHashMap),具体程序如下:

1.结点类型定义:

typedef struct{
	int key;  //键
	int val;  //值
}DataType; //对基本数据类型进行封装,类似泛型
typedef struct{
	DataType data;
	struct HashNode *next;  //key冲突时,通过next指针进行连接
}HashNode;
typedef struct{
	int size;
	HashNode *table;
}HashMap,*hashmap;

2.HashMap基本操作:

①CreateHashMap

//f1_createHashMap
//将给定的整形数组构建为HashMap,size为数组长度
HashMap *CreateHashMap(int *nums,int size){
	//分配内存空间
	HashMap *hashmap=(HashMap*)malloc(sizeof(HashMap));
	hashmap->size=2*size;
	//hash表分配空间
	hashmap->table=(HashNode *)malloc(sizeof(HashNode)*hashmap->size);
	//初始化
	int j=0;
	for(j=0;j<hashmap->size;j++){
		hashmap->table[j].data.val=INT_MIN;
		hashmap->table[j].next=NULL;
	}
	int i=0;
	//建立HashMap
	while(i<size){
	    //根据数组元素的值计算其在hashMap中的位置
		int pos=abs(nums[i])%hashmap->size;
		//判断是否冲突
		if(hashmap->table[pos].data.val==INT_MIN){
		    //不冲突
		    //把元素在数组中的索引作为key
			hashmap->table[pos].data.key=i;
			//把元素值作为value
			hashmap->table[pos].data.val=nums[i];
		}
		//冲突
		else{
		    //给当前元素分配一个结点,并为结点复制
			HashNode *lnode=(HashNode*)malloc(sizeof(HashNode)),*hashnode;
			lnode->data.key=i;
			lnode->data.val=nums[i];
			lnode->next=NULL;
			//从冲突位置开始,遍历链表
			hashnode=&(hashmap->table[pos]);
			while(hashnode->next!=NULL){
				hashnode=hashnode->next;
			}
			//将当前结点连接到链表尾部
			hashnode->next=lnode;
		}
		//处理下一个元素
		i++; 	
	}
	//处理完成,返回HashMap
	return hashmap;
}

       对于hashmap->size=2*size; hashmap中table的长度为什么是给定数组长度的2倍?这涉及到hash表的装填因子,详细可以参考严蔚敏《数据结构》中第九章查找的哈希表章节,这里做简单介绍:

哈希的装填因子:

        其中n 为关键字个数,m为表长.

       装填因子是表示Hsah表中元素的填满的程度。加载因子越大,填满的元素越多,空间利用率提高,但冲突的机会加大了。反之,加载因子越小,填满的元素越少,冲突的机会减小了,但空间浪费多了。冲突的机会越大,则查找的成本越高。反之,查找的成本越小.因而,查找时间就越小.因此,必须在 "冲突的机会"与"空间利用率"之间寻找一种平衡。

②Get

//f2_GetHashNode
int Get(HashMap hashmap,int value){
    //根据元素值,计算其位置
	int pos=abs(key)%hashmap.size;
	HashNode *pointer=&(hashmap.table[pos]);
	//在当前链表遍历查找该结点
	while(pointer!=NULL){
			if(pointer->data.value==value) 
	            return pointer->data.key;
	        else
	        	pointer=pointer->next;
		} 
	//未找到,返回-1
	return -1;
}

③Put

//f3_Put,与建立HashMap时插入元素的方法相同
int Put(HashMap hashmap,int key,int value){
     int pos=abs(value)%hashmap.size;
     HashNode *pointer=&(hashmap.table[pos]);
     if(pointer->data.val==INT_MIN) 
        {
         pointer->data.val=value;
         pointer->data.key=key;
        }
	else{
        while(pointer->next!=NULL)
             pointer=pointer->next;
        HashNode *hnode=(HashNode *)malloc(sizeof(HashNode));
        hnode->data.key=key;
        hnode->data.val=value;
        hnode->next=NULL;
        pointer->next=hnode;
   } 
   return 1;
}	

④PrintHashMap

//f4_PrintHashMap 
void PrintHashMap(HashMap* hashmap){
    printf("%===========PrintHashMap==========\n");
	int i=0;
	HashNode *pointer;
	while(i<hashmap->size){
		pointer=&(hashmap->table[i]);
		while(pointer!=NULL){
            if(pointer->data.val!=INT_MIN)
              printf("%10d",pointer->data.val);
			else 
              printf("        [ ]");
			pointer=pointer->next;
		}
        printf("\n---------------------------------");
		i++;
		printf("\n");
	}
    printf("===============End===============\n");
}

⑤DestoryHashMap

//f5_DestoryHashMap
void DestoryHashMap(HashMap *hashmap){
    int i=0;
    HashNode *hpointer;
    while(i<hashmap->size){
        hpointer=hashmap->table[i].next;
        while(hpointer!=NULL){
            
            hashmap->table[i].next=hpointer->next;
            //逐个释放结点空间,防止内存溢出
            free(hpointer);
            hpointer=hashmap->table[i].next;
            }
        //换至下一个结点
        i++;
    }
    free(hashmap->table);
    free(hashmap);
    printf("Destory hashmap Success!");
}

3.运行示例

主函数如下:

int main(int argc, char **argv)
{
		int nums[]={34,54,32,32,56,78};
		//创建HashMap
   	    HashMap *hashmap=CreateHashMap(nums,6);
    	PrintHashMap(hashmap);
    	//查找元素
    	printf("%d\n",Get(*hashmap,78));

    	DestoryHashMap(hashmap);
    	getchar();
		return 0;
}

运行结果:

HashMap运行结果

猜你喜欢

转载自blog.csdn.net/u013799749/article/details/75674985