标签:
对《大话数据结构》P365~P368—散列表查找实现,进行了自己的理解并完善了代码。
对于P353~P365,散列表概述,散列函数的构造,处理散列冲突的方法,书上讲得比较简单。深入学习还需要看算法导论。
代码和解释如下(VS2012测试通过):
1 #include <iostream> 2 using namespace std; 3 4 #define OK 1 5 #define ERROR 0 6 #define SUCCESS 1 7 #define UNSUCCESS 0 8 #define HASHSIZE 12 //定义散列表长为数组的长度 9 #define NULLKEY -32768 //代表某下标对应的关键字是空 10 typedef int Status; 11 12 int m=0;//散列表表长,全局变量 13 14 //哈希表(散列表)结构 15 typedef struct 16 { 17 int *elem;//elem是指向key的指针 18 int count;//当前数据元素个数 19 }HashTable; 20 21 //初始化哈希表(散列表) 22 Status InitHashTable(HashTable *H) 23 { 24 int i; 25 m=HASHSIZE; 26 H->count=m;//哈希表的长度 27 H->elem=new int[m];//为elem申请一片int[m]的长度的内存空间,这样通过elem[i]可以访问每个元素 28 for(i=0;i<m;i++) 29 H->elem[i]=NULLKEY;//初始化每个关键字都是空 30 return OK; 31 } 32 33 //散列函数 34 int Hash(int key) 35 { 36 return key % m;//除留余数法 37 } 38 39 //插入关键字进散列表 40 void InsertHash(HashTable *H,int key) 41 { 42 int addr = Hash(key);//求散列地址 43 while (H->elem[addr] != NULLKEY)//如果该位置已存有关键字,即不为空,则冲突 44 { 45 addr = (addr+1) % m;//开放定址法的线性探测 46 } 47 H->elem[addr] = key;//直到有空位后插入关键字 48 } 49 50 //散列表查找关键字 51 Status SearchHash(HashTable H,int key,int *i) 52 { 53 *i= Hash(key);//Hash(key)返回的是下标,即ele[*i],这个*i值 54 while(H.elem[*i] != key)//有可能这个key插入散列表的时候用的是开放定址法,所以ele[i]的值并不是这个key,而是本来和它产生冲突的值 55 { 56 *i = (*i+1) % m;//开放定址法的线性探测,当时插入时候也只用了这个公式,用该公式总能查找到 57 if (H.elem[*i] == NULLKEY || *i == Hash(key)) //查找不到,说明关键字不存在 58 return UNSUCCESS; 59 } 60 return SUCCESS; 61 } 62 63 int main() 64 { 65 int arr[HASHSIZE]={12,67,56,16,25,37,22,29,15,47,48,34}; 66 int i,p,key,result; 67 HashTable H;//H是个HashTable类的对象 68 69 InitHashTable(&H);//初始化哈希表 70 71 for(i=0;i<m;i++)//插入arr[0]~arr[m-1] 72 InsertHash(&H,arr[i]); 73 74 for(i=0;i<m;i++)//查找arr[0]~arr[m-1]的位置 75 { 76 key=arr[i]; 77 result=SearchHash(H,key,&p); 78 if (result) 79 cout<<key<<" adress is "<<p<<endl; 80 else 81 cout<<"research "<<key<<" is fail"<<endl; 82 } 83 return 0; 84 }
运行结果:
标签:
原文地址:http://www.cnblogs.com/hslzju/p/5442800.html