1. 程式人生 > >胡凡《演算法筆記》總結2——Hash雜湊

胡凡《演算法筆記》總結2——Hash雜湊

目錄

1.定義及本質

2.基本概念

性質

3.經典例項

3.1常用HASH函式

3.2構造方法


1.定義及本質

雜湊是常用的演算法思想之一,雜湊的本質是一種數學對映,是輸入(input)通過雜湊函式(hash function)對映到輸出(output)的一種壓縮變換。

百科上是這樣介紹雜湊的:

關聯陣列是這樣的陣列,它的每個資料元素與一個鍵相對配對,該鍵用於識別資料元素。由於雜湊函式用來建立關聯陣列中的指定元素,並在關聯陣列中查詢指定元素,因此關聯陣列通常稱為雜湊。在某種意義上,陣列元素與列表類似,而雜湊元素的存放與幾何類似,其元素之間沒有相對次序。在Ruby中,陣列與雜湊之間的兩個最本質的區別是:陣列使用數值下標來定位特定的元素,而雜湊使用字串值(鍵)來定位元素;陣列中的元素按下標排序,而雜湊中的元素則不是。

雜湊的建立方法有兩種:new方法或將一個字面量賦值給一個變數。

準確地說,陣列是數字下標與數值的對映,而雜湊則是任何型別的數字/字元/字串都可以進行相關對映,來定位元素。無論從範圍還是內涵上,雜湊都具有更一般的含義。

關於雜湊函式,定義如下:

Hash,一般翻譯做“雜湊”,也有直接音譯為“雜湊”的,就是把任意長度的輸入(又叫做預對映pre-image)通過雜湊演算法變換成固定長度的輸出,該輸出就是雜湊值。這種轉換是一種壓縮對映,也就是,雜湊值的空間通常遠小於輸入的空間,不同的輸入可能會雜湊成相同的輸出,所以不可能從雜湊值來確定唯一的輸入值。簡單的說就是一種將任意長度的訊息壓縮到某一固定長度的

訊息摘要的函式。

2.基本概念

  • 若結構中存在和關鍵字K相等的記錄,則必定在f(K)的儲存位置上。由此,不需比較便可直接取得所查記錄。稱這個對應關係f為雜湊函式(Hash function),按這個事先建立的表為散列表
  • 對不同的關鍵字可能得到同一雜湊地址,即key1≠key2,而f(key1)=f(key2),這種現象稱碰撞。具有相同函式值的關鍵字對該雜湊函式來說稱做同義詞。綜上所述,根據雜湊函式H(key)和處理衝突的方法將一組關鍵字映象到一個有限的連續的地址集(區間)上,並以關鍵字在地址集中的“象” 作為記錄在表中的儲存位置,這種表便稱為散列表,這一映象過程稱為雜湊造表
    雜湊,所得的儲存位置稱雜湊地址
  • 若對於關鍵字集合中的任一個關鍵字,經雜湊函式映象到地址集合中任何一個地址的概率是相等的,則稱此類雜湊函式為均勻雜湊函式(Uniform Hash function),這就是使關鍵字經過雜湊函式得到一個“隨機的地址”,從而減少衝突。

性質

所有雜湊函式都有如下一個基本特性:如果兩個雜湊值是不相同的(根據同一函式),那麼這兩個雜湊值的原始輸入也是不相同的。這個特性是雜湊函式具有確定性的結果。但另一方面,雜湊函式的輸入和輸出不是一一對應的,如果兩個雜湊值相同,兩個輸入值很可能是相同的,但不絕對肯定二者一定相等(可能出現雜湊碰撞)。輸入一些資料計算出雜湊值,然後部分改變輸入值,一個具有強混淆特性的雜湊函式會產生一個完全不同的雜湊值。

典型的雜湊函式都有無限定義域,比如任意長度的位元組字串,和有限的值域,比如固定長度的位元串。在某些情況下,雜湊函式可以設計成具有相同大小的定義域和值域間的一一對應。一一對應的雜湊函式也稱為排列。可逆性可以通過使用一系列的對於輸入值的可逆“混合”運算而得到。

3.經典例項

先來看一個簡單例子:給出N個正整數,再給出M個正整數,問這M個數中的每一個數分別是否在N個數中出現過。

最樸素的思路是將M中的每個元素在N個元素的陣列中挨個查詢,找到說明存在;找不到說明不存在。這種情況下的時間複雜度位O(N*M)。這種方法的弊端是如果資料量太大,比如達到10^5級別,時間效率就會變得極低。

還可以採用先將N個元素快速排序,在採用二分查詢的方法,這種方法會提高效率。但是如果資料過多,快排和查詢的時間就會比較長。這種情況下可以開闢一個數組。比如我們有一個字串,就可以開闢一個a[128]的陣列,陣列初始化為0,然後查詢,凡是出現過的字元,都記錄為1,這樣再判斷下一個字元時,就可以根據是否為0就可以判斷該字元之前是否出現過。

3.1常用HASH函式

·直接取餘法:f(x):= x mod maxM ; maxM一般是不太接近 2^t 的一個質數。

·乘法取整法:f(x):=trunc((x/maxX)*maxlongit) mod maxM,主要用於實數。

·平方取中法:f(x):=(x*x div 1000 ) mod 1000000); 平方後取中間的,每位包含資訊比較多。

3.2構造方法

雜湊函式能使對一個數據序列的訪問過程更加迅速有效,通過雜湊函式,資料元素將被更快地定位。

(詳細構造方法可以參考hash函式中的【雜湊表的構造方法】)

1.直接定址法:取關鍵字或關鍵字的某個線性函式值為雜湊地址。即H(key)=key或H(key) = a·key + b,其中a和b為常數(這種雜湊函式叫做自身函式)

2. 數字分析法

3. 平方取中法

4. 摺疊法

5. 隨機數法

6. 除留餘數法:取關鍵字被某個不大於散列表表長m的數p除後所得的餘數為雜湊地址。即 H(key) = key MOD p,p<=m。不僅可以對關鍵字直接取模,也可在摺疊、平方取中等運算之後取模。對p的選擇很重要,一般取素數或m,若p選的不好,容易產生同義詞。