哈希表(Hash Table)的應用近兩年纔在NOI中出現,做爲一種高效的數據結構,它正在競賽中發揮着愈來愈重要的做用。
哈希表最大的優勢,就是把數據的存儲和查找消耗的時間大大下降,幾乎能夠看 成是常數時間;而代價僅僅是消耗比較多的內存。然而在當前可利用內存愈來愈 多的狀況下,用空間換時間的作法是值得的。另外,編碼比較容易也是它的特色之一。
哈希表又叫作散列表,分爲「開散列」 和「閉散列」。考慮到競賽時多數人一般避免使用動態存儲結構,本文中的「哈希表」僅指「閉散列」,關於其餘方面讀者可參閱其餘書籍。數組
咱們使用一個下標範圍比較大的數組來存儲元素。能夠設計一個函數(哈希函數, 也叫作散列函數),使得每一個元素的關鍵字都與一個函數值(即數組下標)相對應,因而用這個數組單元來存儲這個元素;也能夠簡單的理解爲,按照關鍵字爲每一 個元素「分類」,而後將這個元素存儲在相應「類」所對應的地方。 可是,不可以保證每一個元素的關鍵字與函數值是一一對應的,所以極有可能出現對於不一樣的元素,卻計算出了相同的函數值,這樣就產生了「衝突」,換句話說,就是把不一樣的元素分在了相同的「類」之中。後面咱們將看到一種解決「衝突」的簡便作法。
總的來講,「直接定址」與「解決衝突」是哈希表的兩大特色。數據結構
構造函數的經常使用方法(下面爲了敘述簡潔,設 h(k) 表示關鍵字爲 k 的元素所對應的函數值):
a) 除餘法:
選擇一個適當的正整數 p ,令 h(k ) = k mod p ,這裏, p 若是選取的是比較大的素數,效果比較好。並且此法很是容易實現,所以是最經常使用的方法。
b) 數字選擇法:
若是關鍵字的位數比較多,超過長整型範圍而沒法直接運算,能夠選擇其中數字分佈比較均勻的若干位,所組成的新的值做爲關鍵字或者直接做爲函數值。函數
線性從新散列技術易於實現且能夠較好的達到目的。令數組元素個數爲 S ,則當 h(k) 已經存儲了元素的時候,依次探查 (h(k)+i) mod S , i=1,2,3…… ,直到找到空的存儲單元爲止(或者從頭至尾掃描一圈仍未發現空單元,這就是哈希表已經滿了,發生了錯誤。固然這是能夠經過擴大數組範圍避免的)。編碼