哈希表的幾個概念: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