Presentasjon lastes. Vennligst vent

Presentasjon lastes. Vennligst vent

雜 湊 表. 內 容 大 綱 雜湊表的定義 雜湊表的操作 雜湊函數 碰撞處理 雜湊表資料刪除 雜湊表的範例程式.

Liknende presentasjoner


Presentasjon om: "雜 湊 表. 內 容 大 綱 雜湊表的定義 雜湊表的操作 雜湊函數 碰撞處理 雜湊表資料刪除 雜湊表的範例程式."— Utskrift av presentasjonen:

1 雜 湊 表

2 內 容 大 綱 雜湊表的定義 雜湊表的操作 雜湊函數 碰撞處理 雜湊表資料刪除 雜湊表的範例程式

3 雜湊表 (hash table) 是一種可以快速處理資料新 增、搜尋及刪除的資料結構。 利用資料的鍵值 (key) 直接對應至儲存位置的方 法,雜湊表可以在幾次的資料比對後就完成資料 加入、搜尋及刪除的動作。

4 雜湊表的定義 (1/2) 雜湊表 (hash table) : 是一個將資料鍵值透過雜湊函數 (hash function) 轉換為資料儲存位置,而可快速進行資料加入、 搜尋以及刪除的資料結構。 透過資料的鍵值 (key) 直接由雜湊函數 (hash function) 對應至儲存位置的方法,雜湊表可以在 幾次的資料比對後就完成資料新增、搜尋及刪除 的動作。 因此,雜湊表的各項操作的時間複雜度均為 O(1) 。 下圖顯示雜湊表、雜湊函數與儲存位置的關係。

5 雜湊表的定義 (2/2) 儲存位置 (position) 雜湊函數 (hash function) 鍵值 (key) ‧‧‧‧‧‧ ‧ p-2 p-1 雜湊表 (hash table) 位置 鍵值及資料 雜湊表、雜湊函數與儲存位置之關係。

6 雜湊表的操作 (1/1) 雜湊表的操作主要有以下三個: 新增 (insert) :將一新的鍵值加入雜湊表中。 刪除 (delete) :將一鍵值自雜湊表中移除。 搜尋 (search) :尋找某一鍵值所在位置。 下圖顯示一個執行各種雜湊表操作的實例。 假設 k 為鍵值、 p 為雜湊表大小,在下圖的實例中,採用 k%p 的公式 ( 除法 ) 來計算鍵值的儲存位置,而當二個鍵 值 k 1 、 k 2 對應至相同儲存位置時,這稱為發生碰撞 (collision) ,則採用線性探測 (linear probing) 的方式,依 序尋找 (k 2 +1)%p 、 (k 2 +2)%p 、 (k 2 +3)%p… 等位置來作 為新的儲存位置。

7 步 驟步 驟 操 作 輸 出輸 出 [0 雜湊表內容 p-1] 1. 新增 (10) ─[ ] 2. 新增 (26) ─[ ] 3. 新增 (50) ─[ ] 4. 新增 (66) ─[ ] 5. 新增 (74) ─[ ] 6. 搜尋 (66 ) 4[ ] 7. 刪除 (66 ) ─[ ] 8. 搜尋 (74 ) 6[ ] 9. 搜尋 (66 ) [ ] 10. 新增 (14) [ ] 11. 新增 (23) [ ] 12. 新增 (38) 雜湊表已滿例外 [ ]

8 雜湊函數 (1/8) 雜湊表必須依賴雜湊函數 (hash function) 來計算出資料 儲存位置,因此,雜湊函數與雜湊表有密不可分的關係。 一個雜湊函數 H 可以描述如下: H: H(key)=position 對雜湊表而言,若雜湊函數可以將所有的鍵值都對應到 一個獨一無二的位置,則可以很單純的直接進行資料的 加入、搜尋或刪除的動作。 然而,由於鍵值的可能值數目往往遠遠大於雜湊表的儲 存空間,因此難免會有不同的鍵值對應到相同儲存位置 的情況,我們將這種情況稱為碰撞 (collision) 。碰撞是雜 湊表的運作中最需要用心解決的問題。

9 雜湊函數 (2/8) 雜湊函數可以進行資料鍵值與雜湊表儲存位置之 間的轉換,一個好的雜湊函數必須具有以下的特 點: 1. 計算簡單。 2. 碰撞 (collision) 少。 3. 不可造成雜湊表儲存位置局部偏重 (bias) 的狀況。

10 雜湊函數 (3/8) 以下我們介紹常用的雜湊函數: 1. 除法 (division method) : H(key)=key mod p ,其中 p 代表雜湊表的大小, 它必須是質數 (prime number) 。我們將雜湊表大小 p 限 制為質數是為了減少碰撞發生,例如,鍵值 10 , 26 , 50 ,在 p=8 的情況下都會得到 2 的雜湊位置,即 H(10)=H(26)=H(50)=H(74)=2 ,若我們選擇 p=7 , 則 H(10)=3 , H(26)=5 , H(50)=1 , H(74)=4 ,其中完 全沒有碰撞發生。

11 雜湊函數 (4/8) 2. 平方取中間為數法 (mid-square method) : H(key)=mid(key 2 ) ,其中 mid 可以取得 key 2 的 一些中間位數。因為一個鍵值平方的中間位數與 鍵值的所有位數的數字大都沒有關係,因此,不 同鍵值就有較大的機率對應到不同的位置;例如: 若我們取萬位數、千位數及百位數,則 H(1234)=mid( )=227 H(4321)=mid( )=710

12 雜湊函數 (5/8) 3. 折疊法 (folding method) : 此方法將鍵值 key 分割為長度為 L 的幾個片段, 使之除了最後一個片段之外,其他所有的片段長 度均相同。分段完畢之後再將所有片段相加,即 可得到最後的儲存位置,例如: key= ,取 L=3 ,我們可將 key 分成 下列幾個片段: 123 、 456 、 789 、 89 ,我們再 將這些片段相加起來得到 =1457 ,其中 1457 就是我們 儲存資料的位置。

13 雜湊函數 (6/8) 折疊法還有許多不同的做法,例如,我們可以將 各片段進行不同的旋轉 ( 如 456 可旋轉為 564 或 645) 或翻轉 ( 如 456 可翻轉為 654) ,相加的時候也 可以選擇向左對齊或向右對齊相加 ( 如 89 選擇向 左對齊相加,則實際加入的值為 890) ,甚至於再 將最後片段相加的值再除以表格大小 ( 質數 p) 。 例如,若表格大小為 97 ,則前述 Key= 的實際儲存位置 =1457 mod 97=2 。

14 雜湊函數 (7/8) 4. 位數分析法 (digit analysis method) : 假如所有的鍵值已經事先知道了,則非常適合 使用此方法。這個方法首先會針對每個位數中所 有數字出現的頻率加以分析,並挑出其中分佈最 均勻的幾個位數,用來作為計算位置的依據,例 如,以鍵值為電話號碼為例 ( 如下圖 ) :

15 雜湊函數 (8/8) 位置 ( 取 3 位 ) ˇ ˇ ˇ 我們注意到其中第 4 個,第 6 個及第 7 個電 話號碼的分部最為平 均,因此我們取這三 個位置的數字作為最 後儲存資料的位置, 如此可以將碰撞發生 的機會減到最低。

16 碰撞處理 (1/7) 即使經過仔細的設計,雜奏函數還是難免會有碰 撞產生,此時,我們要使用碰撞處理 (collision- handling) 方法來處理這樣的狀況,以下我們說明 常見的碰撞處理方法: 1. 線性探測 (linear probing) 法: 當碰撞發生時,就從發生碰撞的位置開始, 一個一個的尋找未被佔用的儲存位置,直到找到 一個未被佔用的位置或整個雜湊表完全被搜尋完 畢為止。

17 碰撞處理 (2/7) 我們用 C(key)=(H(key)+d i ) mod p 來表示,其中 d i =1, 2,..., p-1 ,表示第 i 次產生碰撞後,碰撞處理所探測的 資料儲存位置。例如,鍵值 10, 26, 50, 66, 74 在探用除 法為雜湊函數 (p=7) ,並採用線性探測為碰撞處理法的 情況下,所有鍵值對應的儲存位置為: C(10)=10%7=3 C(26)=26%7=5 C(50)=50%7=1 C(66)=(66%7=3) → 4 C(74)=(74%7=4) → 5 → 6

18 碰撞處理 (3/7) 2. 雙重雜湊 (double hashing) 法: 當碰撞發生時,就使用第二個預先設定的雜湊函數來 進行新的第二個儲存位置的取得,如果在第二個位地也 產生碰撞,則再利用第三個預先設定的雜湊函數來取得 新的第三個儲存位置,依此類推, … 。 例如,我們將雜湊函數設為: C 1 =H 1 (key)= key%p; C 2 =H 2 (key)= C 1 *key%p; C 3 =H 3 (key)= C 2 *key%p; 餘類推, … 。

19 碰撞處理 (4/7) 在 p 為 7 的情況下,鍵值 10, 26, 50, 66, 74 的儲 存位置為 ─ H(10)=10%7=3; H(26)=26%7=5; H(50)=50%7=1; H(66)=((66%7)=3 → (3×66%7))=2 H(74)=74%7=4 一般而言,採用雙重雜湊的碰撞處理法會比採 用線性碰撞處理所需的探測次數來得少。

20 碰撞處理 (5/7) 3. 分別鏈結 (separate chaining) : 當碰撞發生時,就將資料儲存到鏈結串列中, 這種方法的優點是不需要因為碰撞而需要重新計 算資料的儲存位置,而其缺點是當碰撞次數 ( 假 設為 t) 較多時,使用鏈結串列來儲存這些鍵值發 生碰撞的資料會較無效率,因為針對一個長度為 t 的鏈結串列而言,資料的刪除與搜尋的時間與 t 成正比。

21 碰撞處理 (6/7) 例如,當雜湊表大小 p 為 7 的情況下,鍵值 10, 26, 50, 66, 74, 17 使用「分別鏈結」 方式儲存的情形如下: 雜湊表

22 碰撞處理 (7/7) 上述鍵值中的 10, 66 及 17 經過雜湊函數的計算, 都對應到儲存位置 3 ,因此,我們用鏈結串列將 這三個鍵值分別儲存起來。

23 雜湊表資料刪除 (1/3) 對於使用線性探測或雙重雜湊探測碰撞處理法的雜湊表, 在刪除資料時必須將資料位置標示為「已刪除」,以免 讓後續的探測誤以為此位置為空而停止搜尋。 例如,在採用除法為雜湊函數 (p=7) 以及線性探測為碰 撞處理法的情況下,鍵值 10, 26, 50, 66, 74 的儲存位置 為如下圖 (a) ,在刪除 66 之後形成下圖 (b) ,此時若尋找 鍵值 74 ,則會形成如下圖 (c) 中回應「找不到」的錯誤 狀況。此時應如下圖 (d) 一般,在刪除 66 之後將之標示 為「已刪除」 ( 我們將「已刪除」的鍵值以 D 表示 ) ,則 可以如下圖 (e) 中所示的狀況,正確的找到欲搜尋的資 料。

24 雜湊表資料刪除 (2/3) 刪除 66 尋找 ,回應找不到 74 (a)(b)(c)

25 雜湊表資料刪除 (3/3) D (d)(e) D ,線性探測往下找 線性探測往下找 回應找到

26 雜湊表的範例程式 (1/11) 以下我們以 Java 語言撰寫雜湊表的範例程式,我們採用除法為雜 湊函數,並採用線性探測為碰撞處理方法。我們並假設所有的鍵 值均為正數,而使用 -1 代表已刪除之鍵值,使用 0 代表未被佔用 的儲存位置。 1: // 檔名 : 雜湊表類別.java 2: // 說明 : 「雜湊表類別」範例程式 3: // 假設所有的鍵值均大於 0 ,鍵值為 -1 則代表鍵值已刪除 4: public class 雜湊表類別 { 5: private int[] 儲存陣列 ; // 儲存鍵值之陣列 6: private int p; //p 代表儲存陣列大小 7: 雜湊表類別 (int 大小參數 ) { 8: 儲存陣列 =new int[ 大小參數 ]; 9: p= 大小參數 ; 10: }

27 雜湊表的範例程式 (2/11) 11: public int 搜尋 (int k) { //k 代表鍵值 12: int 位置 ; 13: 位置 =k%p; 14: if ( 儲存陣列 [ 位置 ]==k) return 位置 ; 15: else return 搜尋碰撞處理 ( 位置, k); 16: } 17: public int 搜尋碰撞處理 (int 碰撞位置, int k) { 18: int 位置 = 碰撞位置 ; 19: while(true) { 20: 位置 =( 位置 +1)%p; 21: if( 位置 == 碰撞位置 ) return -1; // 「位置」指標已繞一圈, 表示整個空間已滿 22: if( 儲存陣列 [ 位置 ]==k) return 位置 ; // 傳回 k 位於雜湊表中之位 置 23: if( 儲存陣列 [ 位置 ]==0) return -1; // 傳回 -1 代表找不到 24: }

28 雜湊表的範例程式 (3/11) 25: } 26: public int 新增搜尋 (int k) { //k 代表鍵值 27: int 位置 ; 28: 位置 =k%p; 29: if ( 儲存陣列 [ 位置 ]==0) return 位置 ; 30: else return 新增搜尋碰撞處理 ( 位置, k); 31: } 32: public int 新增搜尋碰撞處理 (int 碰撞位置, int k) { 33: int 位置 = 碰撞位置 ; 34: while(true) { 35: 位置 =( 位置 +1)%p; 36: if( 儲存陣列 [ 位置 ]==0) return 位置 ;// 找到空的位置 37: if( 位置 == 碰撞位置 ) return -1; // 「位置」指標已繞一圈,表 示整個空間已滿 38: // 傳回 -1 代表找不到未被佔用之位置

29 雜湊表的範例程式 (4/11) 39: } 40: } 41: public void 新增 (int k) throws 雜湊表滿出例外 { //k 代表鍵值 42: int 位置 = 新增搜尋 (k); 43: if ( 位置 >=0) 儲存陣列 [ 位置 ]=k; 44: else throw new 雜湊表滿出例外 (); 45: } 46: public void 刪除 (int k) throws 資料不存在例外 { //k 代表鍵值 47: int 位置 = 搜尋 (k); 48: if ( 位置 >=0) 儲存陣列 [ 位置 ]=-1; // 使用 -1 代表鍵值已刪除 49: else throw new 資料不存在例外 (); 50: }

30 雜湊表的範例程式 (5/11) 51: public String toString( ) { 52: String 傳回字串 =""; 53: for (int i=0;i

31 雜湊表的範例程式 (6/11) 1: // 檔名 : 雜湊表測試.java 2: // 說明 : 「雜湊表類別」之測試程式 3: import javax.swing.*; 4: public class 雜湊表測試 extends JApplet { 5: public void init( ) { 6: 雜湊表類別 雜湊表 =new 雜湊表類別 (7); 7: String 顯示字串 =""; 8: try { 9: 顯示字串 +=" 操作 \t 輸出 \t0( 雜湊表內容 )p-1"; 10: 顯示字串 +="\n 新增 (10)";

32 雜湊表的範例程式 (7/11) 11: 雜湊表. 新增 (10); 12: 顯示字串 += “ \t\t ” + 雜湊表 ; // 將整個雜湊表之內容轉為字串後 併入顯示文字中 13: 顯示字串 +="\n 新增 (26)"; 14: 雜湊表. 新增 (26); 15: 顯示字串 += “ \t\t ” + 雜湊表 ; // 將整個雜湊表之內容轉為字串後 併入顯示文字中 16: 顯示字串 +="\n 新增 (50)"; 17: 雜湊表. 新增 (50); 18: 顯示字串 += “ \t\t ” + 雜湊表 ; // 將整個雜湊表之內容轉為字串後 併入顯示文字中 19: 顯示字串 +="\n 新增 (66)"; 20: 雜湊表. 新增 (66); 21: 顯示字串 += “ \t\t ” + 雜湊表 ; // 將整個雜湊表之內容轉為字串後併 入顯示文字中 22: 顯示字串 +="\n 新增 (74)";

33 雜湊表的範例程式 (8/11) 23: 雜湊表. 新增 (74); 24: 顯示字串 += “ \t\t ” + 雜湊表 ; // 將整個雜湊表之內容轉為字串後 併入顯示文字中 25: 顯示字串 +="\n 搜尋 (66)"; 26: 顯示字串 +="\t"+ 雜湊表. 搜尋 (66); 27: 顯示字串 += “ \t ” + 雜湊表 ; // 將整個雜湊表之內容轉為字串後 併入顯示文字中 28: 顯示字串 +="\n 刪除 (66)"; 29: 雜湊表. 刪除 (66) ; 30: 顯示字串 += “ \t\t ” + 雜湊表 ; // 將整個雜湊表之內容轉為字串後 併入顯示文字中 31: 顯示字串 +="\n 搜尋 (74)"; 32: 顯示字串 +="\t"+ 雜湊表. 搜尋 (74); 33: 顯示字串 += “ \t ” + 雜湊表 ; // 將整個雜湊表之內容轉為字串後併入顯示 文字中

34 雜湊表的範例程式 (9/11) 34: 顯示字串 +="\n 搜尋 (66)"; 35: 顯示字串 +="\t"+ 雜湊表. 搜尋 (66); 36: 顯示字串 +="\t"+ 雜湊表 ; // 將整個雜湊表之內容轉為字串後併入顯 示文字中 37: 顯示字串 +="\n 新增 (14)"; 38: 雜湊表. 新增 (14); 39: 顯示字串 +="\t\t"+ 雜湊表 ; // 將整個雜湊表之內容轉為字串後併入顯 示文字中 40: 顯示字串 +="\n 新增 (23)"; 41: 雜湊表. 新增 (23); 42: 顯示字串 +="\t\t"+ 雜湊表 ; // 將整個雜湊表之內容轉為字串後併入顯 示文字中 43: 顯示字串 +="\n 新增 (38)";

35 雜湊表的範例程式 (10/11) 44: 雜湊表. 新增 (38); 45: 顯示字串 += “ \t\t ” + 雜湊表 ; // 將整個雜湊表之內容轉為字串後 併入顯示文字中 46: 顯示字串 +="\n 新增 (5)"; 47: 雜湊表. 新增 (5); 48: 顯示字串 += “ \t\t ” + 雜湊表 ; // 將整個雜湊表之內容轉為字串後 併入顯示文字中 49: } 50: catch( 雜湊表滿出例外 e) { 顯示字串 +="\t 雜湊表滿出 "; } 51: catch( 資料不存在例外 e) { 顯示字串 +="\t 欲刪除之資料不存在 "; } 52: finally {JOptionPane.showMessageDialog(null,new JTextArea( 顯示字串 ));} 53: } // 方法 :init() 定義區塊結束 54: } // 類別 : 雜湊表測試 定義區塊結束

36 雜湊表的範例程式 (11/11) 1: 2: 「雜湊表測試」執行中 3: 4: 5: 程式執行結果

37 Q&A

38 程式執行結果


Laste ned ppt "雜 湊 表. 內 容 大 綱 雜湊表的定義 雜湊表的操作 雜湊函數 碰撞處理 雜湊表資料刪除 雜湊表的範例程式."

Liknende presentasjoner


Annonser fra Google