hashmap c
问题提出:
假如一个结构体,记录有学号,姓名。现在内存块中存在着一批此类结构体。如果已知一个学号,要从这些结构体中找出对应的姓名。
问题解决方法:
如果使用链表保存这些结构体,就要遍历这个链表中的结构体,比较每个结构体的学号成员,如果相等就返回这个结构体,从而得到结构体的姓名成员。
但是遍历效率太低,浪费cpu,有点费电。不如使用hash表直接定位到对应的结构体,而不必遍历。
具体做法见代码。说明如下
1.hash表的构建:除留余数法。
2,冲突处理:开放定址法。如果把hash表大小和元素个数定成一样大小,则一点也不浪费空间。
3.如果预先不知道数组的大小,那几个全局数组可以使用vector代替。
4.这是手工实现的hash表创建,冲突处理。也可以使用boost库的hashmap.待续
the code refer to c/c++ 函数与算法速查手册 陈锐
假如一个结构体,记录有学号,姓名。现在内存块中存在着一批此类结构体。如果已知一个学号,要从这些结构体中找出对应的姓名。
问题解决方法:
如果使用链表保存这些结构体,就要遍历这个链表中的结构体,比较每个结构体的学号成员,如果相等就返回这个结构体,从而得到结构体的姓名成员。
但是遍历效率太低,浪费cpu,有点费电。不如使用hash表直接定位到对应的结构体,而不必遍历。
具体做法见代码。说明如下
1.hash表的构建:除留余数法。
2,冲突处理:开放定址法。如果把hash表大小和元素个数定成一样大小,则一点也不浪费空间。
3.如果预先不知道数组的大小,那几个全局数组可以使用vector代替。
4.这是手工实现的hash表创建,冲突处理。也可以使用boost库的hashmap.待续
the code refer to c/c++ 函数与算法速查手册 陈锐
// hash1.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include<stdio.h> #include<malloc.h> #include<stdlib.h> #include <string> typedef struct /*元素类型定义*/ { int value; /*元素值,学号*/ int hi; /*冲突次数*/ char name[20]; char sex; }DataType; typedef struct /*哈希表类型定义*/ { DataType *data; int length; /*哈希表的长度*/ int num; /*表中元素个数*/ }HashTable; void CreateHashTable(HashTable *H,int m,int n); int SearchHash(HashTable H,int k); void HashASL(HashTable H,int m); void DisplayHash(HashTable H,int m); int num[]= {8923, 90, 66, 70, 155, 2456, 123, 987}; char* name[]={"song","rui","lili","mme","feng","ann","tom","min"}; char sex[]={1,2,3,4,5,6,7,8}; int m_TotalLen=99999; int m_CurLen=8; int _tmain(int argc, _TCHAR* argv[]) { HashTable H; int pos,v; CreateHashTable(&H,m_TotalLen,m_CurLen); DisplayHash(H,m_TotalLen); while (1) { printf("请输入待查找学生的学号:"); scanf("%d",&v); pos=SearchHash(H,v); if (pos==-1) continue; printf("学号%d在哈希表中的位置:%d,姓名:%s \n",v,pos,H.data[pos].name); HashASL(H,m_TotalLen); } } void CreateHashTable(HashTable *H,int m,int n) /*构造哈希表,并处理冲突*/ { int i,sum,addr,di; /*为哈希表分配存储空间*/ (*H).data=(DataType*)malloc(m*sizeof(DataType)); if(!(*H).data) exit(-1); (*H).num=n; /*初始化哈希表的元素个数*/ (*H).length=m; /*初始化哈希表的长度*/ for(i=0;i<m;i++) /*初始化哈希表*/ { (*H).data[i].value=-1; (*H).data[i].hi=0; (*H).data[i].sex=0; } /*构造哈希表并处理冲突*/ for(i=0;i<n;i++) { sum=0; /*sum记录冲突次数*/ addr=num[i]%m; /*利用除留余数法求哈希函数地址*/ di=addr; if((*H).data[addr].value==-1) /*如果不冲突则将元素存储在表中*/ { (*H).data[addr].value=num[i]; (*H).data[addr].hi=1; strcpy((*H).data[addr].name,name[i]); (*H).data[addr].sex=sex[i]; } else /*用线性探测再散列法处理冲突*/ { do { di=(di+1)%m; sum+=1; } while((*H).data[di].value!=-1); (*H).data[di].value=num[i]; (*H).data[di].hi=sum+1; strcpy((*H).data[di].name,name[i]); (*H).data[di].sex=sex[i]; } } } int SearchHash(HashTable H,int v) /*在哈希表H中查找值为v的元素*/ { int d,d1,m; m=H.length; d=d1=v%m; /*求v的哈希地址*/ while(H.data[d].value!=-1) { if(H.data[d].value==v) /*如果找到要查找的元素v,则返回v的位置*/ return d; else /*如果不是要找的元素,则继续向后查找*/ d=(d+1)%m; if(d==d1) /*如果找遍了哈希表中的所有位置还没有找到v,则返回0*/ return -1; } return -1; /*该位置不存在元素v*/ } void HashASL(HashTable H,int m) /*求哈希表的平均查找长度*/ { float average=0; int i; for(i=0;i<m;i++) average=average+H.data[i].hi; average=average/H.num; printf("平均查找长度ASL:%.2f",average); printf("\n"); } void DisplayHash(HashTable H,int m) /*输出哈希表*/ { int i; printf("哈希表地址: "); for(i=0;i<m;i++) /*输出哈希表的地址*/ printf("%-5d",i); printf("\n"); printf("元素值value: "); for(i=0;i<m;i++) /*输出哈希表的元素值*/ printf("%-5d",H.data[i].value); printf("\n"); printf("冲突次数: "); for(i=0;i<m;i++) /*冲突次数*/ printf("%-5d",H.data[i].hi); printf("\n"); printf("性别: "); for(i=0;i<m;i++) printf("%-5d",H.data[i].sex); printf("\n"); printf("name: "); for(i=0;i<m;i++) printf("%s ",H.data[i].name); printf("\n"); }