數據結構(哈希表查找)

散列表查詢數組

  • 散列表技術是在記錄的存儲位置和它關鍵字之間創建一個肯定的關係F,使得每一個關鍵字KEY對應一個存儲位置F(KEY)
  • 這裏把這種對應關係F稱爲散列散列函數,又稱爲哈希函數
  • 採用散列技術將記錄存儲在一塊連續的存儲空間中,這塊存儲空間稱爲散列表或哈希表。

散列表的查找步驟:dom

  • 當存儲記錄時,經過散列函數計算出記錄的散列地址
  • 當查找記錄時,一樣經過散列函數計算記錄的散列地址,並按此散列地址訪問該記錄
  • 散列表其實就是用值投影一個地址;直接可經過值查找到記錄

構造散列函數的兩個基本原則:函數

  計算簡單;分佈均勻spa

方法:指針

  • 直接定址法:可取關鍵字某個線性函數的值爲散列地址。即 F(key)=a*key+b;(表中數據小且連續)
  • 數分析法:適合處理關鍵字位數比較大的狀況;關鍵字位數較大,經過數字分析,找出表中每一個數據的不可能重複位做爲散列地址(通常爲關鍵字中用來爲數據編號的位置)
  • 平方取中法:將關鍵字平方以後取中間若干位數字做爲散列地址(適用於不知道關鍵字分佈,且關鍵字位數不大的狀況)
  • 摺疊法:將關鍵字從左到右分割成位數相等的幾個部分,而後將這幾部分疊加求和,並按散列表表長取後幾位做爲散列地址(適用於不知道關鍵字分佈,但知道關鍵字位數)
  • 除留餘數法:對散列表長m的散列函數計算公式:F(key)=key%p(p<=m);p的選擇狠關鍵:最好【接近/等於】m或m的最大質數
  • 隨機數法:去關鍵字的隨機數值爲他的散列地址。即:F(key)=random(key);(適用於關鍵字長度不等的狀況)

選取方法時可參照的方向:code

  • 計算散列地址所用的時間
  • 關鍵字長度
  • 散列表大小
  • 關鍵字分佈狀況
  • 記錄查找的評率

處理散列衝突的方法:blog

  • 開放定址法:一旦發生了衝突,就去尋找下一個空的散列表地址【Fi(key)=(F(key)+Di)%m(Di=1,2,3,...,m-1)】
  • 再散列函數法:一旦發生了衝突,RHi表示多個散列函數,衝突以後就換一個散列函數從新定址【Fi(key)=RHi(key)  (i=1,2,3,...,k)】
  • 鏈地址法:發生衝突時,利用單鏈表把數據鏈在原數的指針上
  • 公共溢出區法:把衝突數據存放在溢出表的一樣位置
 1 #define HASESIZE 12
 2 #define NULLKEY -32768
 3 
 4 //利用散列函數獲得偏移地址,在數組中對偏移地址存儲相應數據達到查找效率爲O(1)
 5 typedef struct{
 6     int *elem;//數據元素基址(首地址),動態分配數組;
 7     int count;//當前數據元素個數
 8 }HashTable;
 9 
10 int InitHashTable(HashTable *H){
11     int i;
12     H->count=HASESIZE;
13     H->elem=(int *)malloc(HASESIZE*sizeof(int));
14     if(!H->elem){
15         return -1;
16     }
17     for(i=0;i<HASESIZE;i++){
18         H->elem[i]=NULLKEY;
19     }
20     return 0;
21 }
22 
23 //使用除留餘數法
24 int Hash(int key){
25     return key % HASESIZE;
26 }
27 
28 //插入關鍵字到散列表
29 void InsertHash(HashTable *H,int key){
30     int addr=Hash(key);
31     while(H->elem[addr]!=NULLKEY){//出現衝突
32         addr=(addr+1) % HASESIZE;//開放定址法處理
33         if(addr==Hash(key)){
34             return ;//已近存滿
35         }
36     }
37     H->elem[addr]=key;
38 }
39 
40 //散列表查找關鍵字
41 int SearchHase(HashTable H,int key,int *addr){
42     *addr=Hash(key);
43     while(H.elem[*addr]!=key){
44         *addr=(*addr+1)%HASESIZE;
45         if(H.elem[*addr]==NULLKEY || *addr==Hash(key)){
46             return -1;
47         }
48     }
49     return 0;
50 }
相關文章
相關標籤/搜索