哈希表的几个概念:ios
映像:由哈希函数获得的哈希表是一个映像。c++
冲突:若是两个关键字的哈希函数值相等,这种现象称为冲突。数组
处理冲突的几个方法:函数
一、开放地址法:用开放地址处理冲突就是当冲突发生时,造成一个地址序列,沿着这个序列逐个深测,直到找到一个“空”的开放地址,将发生冲突的关键字值存放到该地址中去。测试
例如:hash(i)=(hash(key)+d(i)) MOD m (i=1,2,3,......,k(k<m-1)) d为增量函数,d(i)=d1,d2,d3,...,dn-1spa
根据增量序列的取法不一样,能够获得不一样的开放地址处理冲突探测方法。内存
有线性探测法、二次方探测法、伪随机探测法。ci
二、链地址法:把全部关键字为同义词的记录存储在一个线性链表中,这个链表成为同义词链表,即把具备相同哈希地址的关键字值存放在同义链表中。string
三、再哈希表:费时间的一种方法hash
下面是代码:
文件"myhash.h"
- #include<iostream>
- using namespace std;
-
- typedef int KeyType;
- const int NULLKEY=0;
- int c=0;
-
- struct Elemtype
- {
- KeyType key;
- int ord;
- };
-
- int hashsize[]={11,19,29,37,47};
- int Hash_length=0;
-
- class HashTable
- {
- private:
- Elemtype *elem;
- int count;
- int size;
- public:
-
- int Init_HashTable()
- {
- int i;
- count=0;
- size=0;
- Hash_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)
- {
- return k%Hash_length;
- }
-
- void Collision(int &p,int d)
- {
- p=(p+d)%Hash_length;
- }
-
- bool Search_Hash(KeyType k,int &p)
- {
-
-
- c=0;
- p=Hash(k);
- while(elem[p].key!=NULLKEY && elem[p].key!=k)
- {
- c++;
- if(c<Hash_length)
- Collision(p,c);
- else
- return 0;
- }
- if(elem[p].key==k)
- return 1;
- else
- return 0;
-
- }
-
- int Insert_Hash(Elemtype e)
- {
-
- int p;
- if(Search_Hash(e.key,p))
- return -1;
- else if(c<hashsize[size]/2)
- {
-
- elem[p]=e;
- count++;
- return 1;
- }
- else
- ReCreate_HashTable();
- return 0;
- }
-
- void ReCreate_HashTable()
- {
- int i,count2=count;
- Elemtype *p,*elem2=new Elemtype[count];
- p=elem2;
- cout<<"____重建hash表_____"<<endl;
- for(i=0;i<Hash_length;i++)
- if(elem[i].key!=NULLKEY)
- *p++=*(elem+i);
- count=0;
- size++;
- 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++)
- {
- 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);
- else
- cout<<"无此记录"<<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);
- else
- cout<<"该记录不存在"<<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