Hash表(C++实现)

哈希表的几个概念:

映像:由哈希函数得到的哈希表是一个映像。

冲突:如果两个关键字的哈希函数值相等,这种现象称为冲突。

处理冲突的几个方法:

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"

  1. #include<iostream>  
  2. using namespace std;  
  3.   
  4. typedef int KeyType; //设关键字域为整形,需要修改类型时,只需修改这里就可以  
  5. const int NULLKEY=0; //NULLKEY表示该位置无值  
  6. int c=0; //用来统计冲突次数  
  7.   
  8. struct Elemtype //数据元素类型  
  9. {  
  10.     KeyType key;  
  11.     int ord;   
  12. };  
  13.   
  14. int hashsize[]={11,19,29,37,47}; //hash表容量递增表  
  15. int Hash_length=0;//hash表表长  
  16.   
  17. class HashTable  
  18. {  
  19. private:  
  20.     Elemtype *elem; //数据元素数组,动态申请  
  21.     int count;// 当前数据元素个数  
  22.     int size; //决定hash表的容量为第几个,hashsize[size]为当前hash容量  
  23. public:  
  24.   
  25.     int Init_HashTable() //构造一个空hash表  
  26.     {  
  27.         int i;  
  28.         count=0;  
  29.         size=0; //初始化容量为hashsize[0]=11  
  30.         Hash_length=hashsize[0];  
  31.         elem=new Elemtype[Hash_length];  
  32.         if(!elem)  
  33.         {  
  34.             cout<<"内存申请失败"<<endl;  
  35.             exit(0);  
  36.         }  
  37.         for(i=0;i<Hash_length;i++)  
  38.             elem[i].key=NULLKEY;  
  39.         return 1;  
  40.     }  
  41.   
  42.     void Destroy_HashTable()  
  43.     {  
  44.         delete[]elem;  
  45.         elem=NULL;  
  46.         count=0;  
  47.         size=0;  
  48.     }  
  49.   
  50.     unsigned Hash(KeyType k) //hash函数的一种(取模法)  
  51.     {  
  52.         return k%Hash_length;  
  53.     }  
  54.   
  55.     void Collision(int &p,int d) //解决冲突  
  56.     {  
  57.         p=(p+d)%Hash_length; //采用开放地址法里的线性探测  
  58.     }  
  59.   
  60.     bool Search_Hash(KeyType k,int &p) //查找  
  61.     {  
  62.         //在开放地址hash表中查找关键字等于k的元素  
  63.         //若找到用p表示待查数据,查找不成功时,p指向的是可插入地址  
  64.         c=0;  
  65.         p=Hash(k); //求hash地址  
  66.         while(elem[p].key!=NULLKEY && elem[p].key!=k)  
  67.         {  
  68.             c++;  
  69.             if(c<Hash_length)  
  70.                 Collision(p,c);  
  71.             else  
  72.                 return 0; //表示查找不成功  
  73.         }  
  74.         if(elem[p].key==k)  
  75.             return 1;  
  76.         else  
  77.             return 0;  
  78.   
  79.     }  
  80.   
  81.     int Insert_Hash(Elemtype e) //插入  
  82.     {  
  83.         //在查找不成功的情况下将k插入到hash表中  
  84.         int p;  
  85.         if(Search_Hash(e.key,p))  
  86.             return -1; //表示该元素已在hash表中  
  87.         else if(c<hashsize[size]/2) //冲突次数未达到上限  
  88.         {  
  89.             //插入e  
  90.             elem[p]=e;  
  91.             count++;  
  92.             return 1;  
  93.         }  
  94.         else  
  95.             ReCreate_HashTable(); // 重建hash表  
  96.         return 0; //插入失败  
  97.     }  
  98.   
  99.     void ReCreate_HashTable() //重建hash表  
  100.     {  
  101.         int i,count2=count;  
  102.         Elemtype *p,*elem2=new Elemtype[count];  
  103.         p=elem2;  
  104.         cout<<"____重建hash表_____"<<endl;  
  105.         for(i=0;i<Hash_length;i++) //将原有元素暂存到elem2中  
  106.             if(elem[i].key!=NULLKEY)  
  107.                 *p++=*(elem+i);  
  108.         count=0;  
  109.         size++; //hash容量增大  
  110.         Hash_length=hashsize[size];  
  111.         p=new Elemtype[Hash_length];  
  112.         if(!p)  
  113.         {  
  114.             cout<<"空间申请失败"<<endl;  
  115.             exit(0);  
  116.         }  
  117.         elem=p;  
  118.         for(i=0;i<Hash_length;i++)  
  119.             elem[i].key=NULLKEY;  
  120.         for(p=elem2;p<elem2+count2;p++) //将原有元素放回新表  
  121.             Insert_Hash(*p);  
  122.     }  
  123.   
  124.     void Traverse_HashTable()  
  125.     {  
  126.         cout<<"哈希地址0->"<<Hash_length-1<<endl;  
  127.         for(int i=0;i<Hash_length;i++)  
  128.             if(elem[i].key!=NULLKEY)  
  129.                 cout<<"元素的关键字值和它的标志分别是:"<<elem[i].key<<"  "<<elem[i].ord<<endl;  
  130.   
  131.     }  
  132.   
  133.     void Get_Data(int p)  
  134.     {  
  135.         cout<<"元素的关键字值和它的标志分别是:"<<elem[p].key<<"  "<<elem[p].ord<<endl;  
  136.     }  
  137.       
  138. };

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值