查詢(3)--雜湊表(雜湊查詢)

fan_rockrock發表於2014-02-22

一.基本概念:

            1. 雜湊查詢(雜湊查詢),與前面介紹的靜態查詢和動態查詢方法完全不同,前面介紹的所有查詢都是基於待查關鍵字與表中元素進行比較而實現的查詢方法,而雜湊查詢是通過構造雜湊函式來得到待查關鍵字的地址,按理論分析真正不需要用到比較的一種查詢方法。

            2.雜湊表定義:根據設定的雜湊函式 H(key) 和所選中的處理衝突的方法,將一組關鍵字映象到一個有限的、地址連續的地址集 (區間) 上,並以關鍵字在地址集中的“象”作                                        為相應記錄在表中的儲存位置,如此構造所得的查詢表稱之為“雜湊表”

            3.舉例來說明:

                            假設有一批關鍵字序列18,75,60,43,54,90,46,給定雜湊函式H(k)=k%13,存貯區的記憶體地址從0到15,則可以得到每個關鍵字的雜湊地址為:

                    H(18)=18%13=5,H(75)=75%13=10,H(60)=60%13=8,H(43)=43%13=4,H(54)=54%13=2,H(90)=90%13=12, H(46)=46%13=7,

                    於是,根據雜湊地址,可以將左邊7個關鍵字序列存貯到一個一維陣列HT(雜湊表或雜湊表)中,具體表示為:

                                           例如查詢元素:查詢75,只需計算出H(75)=75%13=10,則可以在HT[10]中找到75。


                            上面討論的雜湊表是一種理想的情形,即每一個關鍵字對應一個唯一的地址。但是有可能出現這樣的情形,兩個不同的關鍵字有可能對應同一個記憶體地址,即兩                 個記錄的關鍵值不等,但它們的雜湊函式的值相同,這樣,將導致後放的關鍵字無法存貯,我們把這種現象叫做衝突  

                使用雜湊方法,首先要選擇一個好的雜湊函式,使一組關鍵值所得到的雜湊地址能均勻分佈在整個地址空間中,並且衝突次數儘可能地少。

            4.發生衝突的可能性卻與三個方面因素有關

                        第一:是與裝填因子α有關,所謂裝填因子是指雜湊表中己存入的元素個數n與雜湊表的大小m的比值,即α=n/m。當α越小時,發生衝突的可能性越小,α越 (最                                       大為1)時,發生衝突的可能性就越大。但是, 為了減少衝突的發生,不能將α變得太小,這樣將會造成大量存貯空間的浪費,因此必須兼顧儲存空間和                                         衝突兩個方面。
                        第二:是與所構造的雜湊函式有關(前面己介紹)。
                        第三:是與解決衝突的方法有關。


二.雜湊函式的構造

             1.直接定址法 
                           可表示為H(k)=a.k+b,其中a、b均為常數。
                           這種方法計算特別簡單,並且不會發生衝突,但當關鍵字分佈不連續時,會出現很多空閒單元,將造成大量存貯單元的浪費

             2.數字分析法
                           對關鍵字序列進行分析,取那些位上數字變化多的、頻率大的作為雜湊函式地址。

                            例如: 有如下的關鍵字序列     9 9 3 4 6 5 3 2
                                                                                  9 9 3 7 2 2 4 2

                                                                                  9 9 3 8 7 4 3 2.......通過對上述關鍵字序列分析,發現前3位相同,第8位只取2,因此,這四位不可取。中間的四位的數字變化多                                                                                                                       些,可看成是隨機的,若規定地址取3位,則雜湊函式可取它的第4、5、6位。於是有:
                                                                                                                    H(99346532)=465 ,H(99372242)=722,H(99387433)=874

             3.平方取中法
                               取關鍵字平方後的中間幾位為雜湊函式地址。這是一種比較常用的雜湊函式構造方法,但在選定雜湊函式時不一定知道關鍵字的全部資訊,取其中哪幾位也不                               一定合適,而一個數平方後的中間幾位數和數的每一位都相關,因此,可以使用隨機分佈的關鍵字得到雜湊函式地址。

            4.摺疊法
                             將關鍵字分割成位數相同的幾部分(最後一部分的位數可以不同),然後取這幾部分的疊加和(捨去進位)作為雜湊函式地址,稱為摺疊法

                             例如,假設關鍵字為某人身份證號碼430104681015355,則可以用4位為一組進行疊加,即有5355+8101+1046+430=14932,捨去高位,則有     

                                        H(430104681015355)=4932為該身份證關鍵字的雜湊函式地址。

            5.除留餘數法
                          該方法是用關鍵字序列中的關鍵字k除以一個整數p所得餘數作為雜湊函式的地址,即
                           H(k)=k%p 。   P<=m   m為雜湊表長度

                            除留餘數法計算簡單,適用範圍廣,是一種最常使用的方法。這種方法的關鍵是選取較理想的p值,使得每一個關鍵字通過該函式轉換後對映到雜湊空間上任一                    地址的概率都相等,從而儘可能減少發生衝突的可能性。一般情形下,p 取為一個素數較理想,並且要求裝填因子α最好是在0.6∽0.9之間,所以p 最好取1.1n∽1.7n                    之間的一個素數較好,其中n為雜湊表中待裝元素個數。

            6.  隨機法
                        選擇一個隨機函式,取關鍵值的隨機函式值為它的雜湊地址,即 H(key)=random(key)
                          random()不能是一般的隨機函式,固定的引數必須返回確定的值。


三. 解決衝突的方法

             1.開放定址法
                           開放定址法就是從發生衝突的那個單元開始,按照一定的次序,從雜湊表中找出一個空閒的儲存單元,把發生衝突的待插入關鍵字儲存到該單元中,從而解決衝                              突的發生。在雜湊表未滿時,處理衝突需要的“下一個”空地址在雜湊表中解決。
                           開放定址法利用下列公式求“下一個”空地址
                                   Hi=(H(key)+di) MOD m     i=1,2,…K(K<=m-1)    其中H(key)為雜湊函式,m為雜湊表長度,di為增量序列。

              根據di的取法,解決衝突時具體使用下面一些方法。

                            (1)線性探測法:

                                      假設雜湊表的地址為0∽m-1,則雜湊表的長度為m。若一個關鍵字在地址d處發生衝突,則依次探查d+1,d+2,…,m-1(當達到表尾m-1時,又從0,1,                                       2,….開始探查)等地址,直到找到一個空閒位置來裝衝突處的關鍵字,將這一種方法稱為線性探查法。假設發生衝突時的地址為d0=H(k),則探查下一位                                         置的公式為di=(di-1+1)%m (1≤i≤m-1),最後將衝突位置的關鍵字存入di地址中。

                                       例:  給定關鍵字序列為19,14,23,1,68,20,84,27,55,11,10,79,雜湊函式H(k)=k%13 ,雜湊表空間地址為0∽12,試用線性探查法建                                                    立雜湊存貯(雜湊表)結構。
                                                   得到的雜湊表如下圖所示:

                                                             

                            (2) 二次方探查法
                                         該方法規定,若在d地址發生衝突,下一次探查位置為d+12,d-12,d+22,d- 22, …,直到找到一個空閒位置為止。
                                         開放地址法充分利用了雜湊表的空間,但在解決一個衝突時,可能造成下一個衝突。另外,用開放地址法解決衝突不能隨便對結點進行刪除。

                2. 鏈地址法
                           鏈地址法也稱拉鍊法,是把相互發生衝突的同義詞用一個單鏈錶連結起來,若干組同義詞可以組成若干個單連結串列 

                           例:對給定的關鍵字序列19,14,23,1,68,20,84,27,55,11,10,79,給定雜湊函式為H(k)=k%13,試用拉鍊法解決衝突建立雜湊表。

                            


四.雜湊查詢的效能分析:

                    雜湊查詢按理論分析,它的時間複雜度應為O(1),它的平均查詢長度應為ASL=1,但實際上由於衝突的存在,它的平均查詢長度將會比1大。下面將分析幾種方法的                     平均查詢長度。

     1.線性探查法的效能分析
                由於線性探查法解決衝突是線性地查詢空閒位置的,平均查詢長度與表的大小m無關,只與所選取的雜湊函式H及裝填因子α的值和該處理方法有關,這時的成功的平 均 查詢長度為ASL=1/2 (1+1/(1- α)) 。

2.拉鍊法查詢的效能分析
由於拉鍊法查詢就是在單連結串列上查詢,查詢單連結串列中第一個結點的次數為1,第二個結點次數為2,其餘依次類推。它的平均查詢長度ASL=1+α/2。 


查詢綜合練習題:

             例:給定關鍵字序列11,78,10,1,3,2,4,21,試分別用順序查詢、二分查詢、二叉排序樹查詢、雜湊查詢(用線性探查法和拉鍊法)來實現查詢,試畫出它們的對應儲存形式(順序查詢的順序表,二分查詢的判定樹,二叉排序樹查詢的二叉排序樹,雜湊查詢的雜湊表),並求出每一種查詢的成功平均查詢長度。雜湊函式H(k)=k%11。

             (1)順序查詢:

                        順序查詢的順序表(一維陣列)如下所示,

                          

                         從上圖可以得到順序查詢的成功平均查詢長度為:
                                              ASL=(1+2+3+4+5+6+7+8)/8=4.5;

              (2)二分查詢:

                           二分查詢的判定樹(中序序列為從小到大排列的有序序列)如下圖所示, 

                           

                           從上圖可以得到二分查詢的成功平均查詢長度為:
                           ASL=(1+2*2+3*4+4)/8=2.625;

             (3).二叉排序樹(關鍵字順序已確定,該二叉排序樹應唯一)如下圖所示, 

                                  

                              從上圖可以得到二叉排序樹查詢的成功平均查詢長度為:
                              ASL=(1+2*2+3*2+4+5*2)=3.125;

               (4)線性探查法解決衝突的雜湊表如下圖所示, 

                                    

                         從上圖可以得到線性探查法的成功平均查詢長度為:
                           ASL=(1+1+2+1+3+2+1+8)/8=2.375;

              (5)拉鍊法解決衝突的雜湊表如下圖所示。

                            

              從上圖可以得到拉鍊法的成功平均查詢長度為:
             ASL=(1*6+2*2)/8=1.25。

相關文章