Hash表(C++实现)
来源:互联网 发布:培训java费用 编辑:程序博客网 时间:2024/06/05 04:59
哈希表的几个概念:
映像:由哈希函数得到的哈希表是一个映像。
冲突:如果两个关键字的哈希函数值相等,这种现象称为冲突。
处理冲突的几个方法:
1、开放地址法:用开放地址处理冲突就是当冲突发生时,形成一个地址序列,沿着这个序列逐个深测,直到找到一个“空”的开放地址,将发生冲突的关键字值存放到该地址中去。
例如:hash(i)=(hash(key)+d(i)) MOD m (i=1,2,3,......,k(k<m-1)) d为增量函数,d(i)=d1,d2,d3,...,dn-1
根据增量序列的取法不同,可以得到不同的开放地址处理冲突探测方法。
有线性探测法、二次方探测法、伪随机探测法。
2、链地址法:把所有关键字为同义词的记录存储在一个线性链表中,这个链表成为同义词链表,即把具有相同哈希地址的关键字值存放在同义链表中。
3、再哈希表:费时间的一种方法
下面是代码:
文件"myhash.h"
#include<iostream>using namespace std;typedef int KeyType; //设关键字域为整形,需要修改类型时,只需修改这里就可以const int NULLKEY=0; //NULLKEY表示该位置无值int c=0; //用来统计冲突次数struct Elemtype //数据元素类型{KeyType key;int ord; };int hashsize[]={11,19,29,37,47}; //hash表容量递增表int Hash_length=0;//hash表表长class HashTable{private:Elemtype *elem; //数据元素数组,动态申请int count;// 当前数据元素个数int size; //决定hash表的容量为第几个,hashsize[size]为当前hash容量public:int Init_HashTable() //构造一个空hash表{int i;count=0;size=0; //初始化容量为hashsize[0]=11Hash_length=hashsize[0];elem=new Elemtype[Hash_length];if(!elem){cout<<"内存申请失败"<<endl;exit(0);}for(i=0;i<Hash_length;i++)elem[i].key=NULLKEY;return 1;}void Destroy_HashTable(){delete[]elem;elem=NULL;count=0;size=0;}unsigned Hash(KeyType k) //hash函数的一种(取模法){return k%Hash_length;}void Collision(int &p,int d) //解决冲突{p=(p+d)%Hash_length; //采用开放地址法里的线性探测}bool Search_Hash(KeyType k,int &p) //查找{//在开放地址hash表中查找关键字等于k的元素//若找到用p表示待查数据,查找不成功时,p指向的是可插入地址c=0;p=Hash(k); //求hash地址while(elem[p].key!=NULLKEY && elem[p].key!=k){c++;if(c<Hash_length)Collision(p,c);elsereturn 0; //表示查找不成功}if(elem[p].key==k)return 1;elsereturn 0;}int Insert_Hash(Elemtype e) //插入{//在查找不成功的情况下将k插入到hash表中int p;if(Search_Hash(e.key,p))return -1; //表示该元素已在hash表中else if(c<hashsize[size]/2) //冲突次数未达到上限{//插入eelem[p]=e;count++;return 1;}elseReCreate_HashTable(); // 重建hash表return 0; //插入失败}void ReCreate_HashTable() //重建hash表{int i,count2=count;Elemtype *p,*elem2=new Elemtype[count];p=elem2;cout<<"____重建hash表_____"<<endl;for(i=0;i<Hash_length;i++) //将原有元素暂存到elem2中if(elem[i].key!=NULLKEY)*p++=*(elem+i);count=0;delete []elem;size++; //hash容量增大Hash_length=hashsize[size];p=new Elemtype[Hash_length];if(!p){cout<<"空间申请失败"<<endl;exit(0);}elem=p;for(i=0;i<Hash_length;i++)elem[i].key=NULLKEY;for(p=elem2;p<elem2+count2;p++) //将原有元素放回新表Insert_Hash(*p);}void Traverse_HashTable(){cout<<"哈希地址0->"<<Hash_length-1<<endl;for(int i=0;i<Hash_length;i++)if(elem[i].key!=NULLKEY)cout<<"元素的关键字值和它的标志分别是:"<<elem[i].key<<" "<<elem[i].ord<<endl;}void Get_Data(int p){cout<<"元素的关键字值和它的标志分别是:"<<elem[p].key<<" "<<elem[p].ord<<endl;}};
测试函数"main.cpp"
#include"myhash.h"int main(){Elemtype r[12]={{17,1},{60,2},{29,3},{38,4},{1,5},{2,6},{3,7},{4,8},{5,9},{6,10},{7,11},{8,12}};HashTable H;int i,p,j;KeyType k;H.Init_HashTable();for(i=0;i<11;i++) //插入前11个记录{j=H.Insert_Hash(r[i]);if(j==-1)cout<<"表中已有关键字为"<<r[i].key<<" "<<r[i].ord<<"的记录"<<endl;}cout<<"按哈希地址顺序遍历哈希表"<<endl;H.Traverse_HashTable();cout<<endl;cout<<"输入要查找的记录的关键字:";cin>>k;j=H.Search_Hash(k,p);if(j==1)H.Get_Data(p);elsecout<<"无此记录"<<endl;j=H.Insert_Hash(r[11]); //插入最后一个元素if(j==0){cout<<"插入失败"<<endl;cout<<"需要重建哈希表才可以插入"<<endl;cout<<"____重建哈希表____"<<endl;H.Insert_Hash(r[i]); //重建后重新插入}cout<<"遍历重建后的哈希表"<<endl;H.Traverse_HashTable();cout<<endl;cout<<"输入要查找的记录的关键字:";cin>>k;j=H.Search_Hash(k,p);if(j==1)H.Get_Data(p);elsecout<<"该记录不存在"<<endl;cout<<"____销毁哈希表____"<<endl;H.Destroy_HashTable();return 0;}测试结果:
按哈希地址顺序遍历哈希表哈希地址0->10元素的关键字值和它的标志分别是:5 9元素的关键字值和它的标志分别是:1 5元素的关键字值和它的标志分别是:2 6元素的关键字值和它的标志分别是:3 7元素的关键字值和它的标志分别是:4 8元素的关键字值和它的标志分别是:60 2元素的关键字值和它的标志分别是:17 1元素的关键字值和它的标志分别是:29 3元素的关键字值和它的标志分别是:38 4元素的关键字值和它的标志分别是:6 10元素的关键字值和它的标志分别是:7 11输入要查找的记录的关键字:5元素的关键字值和它的标志分别是:5 9____重建hash表_____插入失败需要重建哈希表才可以插入____重建哈希表____遍历重建后的哈希表哈希地址0->18元素的关键字值和它的标志分别是:38 4元素的关键字值和它的标志分别是:1 5元素的关键字值和它的标志分别是:2 6元素的关键字值和它的标志分别是:3 7元素的关键字值和它的标志分别是:4 8元素的关键字值和它的标志分别是:5 9元素的关键字值和它的标志分别是:60 2元素的关键字值和它的标志分别是:6 10元素的关键字值和它的标志分别是:7 11元素的关键字值和它的标志分别是:8 12元素的关键字值和它的标志分别是:29 3元素的关键字值和它的标志分别是:17 1输入要查找的记录的关键字:7元素的关键字值和它的标志分别是:7 11____销毁哈希表____Press any key to continue
- hash表 c语言实现
- HASH表的实现(拉链法) - C/C++
- C/C++ 实现哈希表(hash table)
- Hash表(C++实现)
- Hash表(C++实现)
- Hash表(C++实现)
- Hash表(C++实现)
- Hash桶实现hash表
- Hash学习(4)-hash表的实现
- 用c实现HASH表创建、插入、查找、删除、打印(欢迎高手指点)
- 数据结构之---C语言实现散列表(哈希Hash表)
- 用c实现HASH表创建、插入、查找、删除、打印(欢迎高手指点)【转】
- C语言中的两种hash表的实现
- 配合Dijkstra算法的Hash表实现文件C语言
- hash表的openADDRESSing的c语言实现
- 用c实现HASH表创建、插入、查找、删除、打印
- 用c实现HASH表创建、插入、查找、删除、打印
- C语言 开放寻址法HASH表存储简单实现
- 自定义泛型总结
- java冒泡排序算法
- vc6.0中用GDIPlus实现加载动态gif图片(非MFC实现)
- silverlight 自定义控件基础篇(仿淘宝评论星级控件)
- linux神奇的系统请求----系统救命草
- Hash表(C++实现)
- linux系统调用的基本原理和技巧
- VB update
- C++0x新特性
- 动态编程简单示例
- linux文件include/asm/unisted.h为每个系统调用规定了唯一的编号
- 今日,ORACLE 11gR2 RAC大功告成
- 关于gentoo 报EAPI问题
- 用Erlang验证中华人民共和国公民身份号码