演算法函式 左神演算法基礎 雜湊函式和雜湊表

2021-10-14 17:08:58 字數 1859 閱讀 7371

筆者在讀研剛開始的時候,偶爾看面經,有這樣乙個問題:只用2gb內存在20億個整數中找到出現次數最多的數,當時的我一臉懵逼,怎麼去思考,20億個數?what the ****! 但是,看完今天的文章,你或許就會覺得原來也不過如此啊!其核心就是雜湊函式和雜湊表的應用!

雜湊函式又稱為雜湊函式,就是把任意長度的輸入(又叫做預對映, pre-image),通過雜湊演算法,變換成固定長度的輸出,該輸出就是雜湊值。這種轉換是一種壓縮對映,也就是,雜湊值的空間通常遠小於輸入的空間,不同的輸入可能會雜湊成相同的輸出,而不可能從雜湊值來唯一的確定輸入值。假設輸出值域為s,雜湊函式的性質如下:

典型的雜湊函式都有無限的輸入值域

當雜湊函式輸入一致時,輸出必相同

當雜湊函式傳入不同的輸入值時,返回值可能一樣,也可能不一樣,由於輸入域遠大於值域

(重要)很多的不同輸入所得的輸出值會均勻的分布在s上(但不是絕對均勻)

最後乙個性質對於乙個優秀的雜湊函式是非常重要的,並且這種均勻與資料的輸入規律無關。比如「aa1」、"aa2"經過hash後可能結果會相差很多,當乙個雜湊函式的輸出在s中是均勻的,那麼我們將輸出值對m取餘(%m),就會將不定長輸入對映到0~m-1空間中,並且在這個空間也保持均勻分布!雜湊表就是這麼做的,一會再說!雜湊函式還有以下特點:

免碰撞:即不會出現輸入 x≠y ,但是h(x)=h(y) 的情況,其實這個特點在理論上並不成立,比如目前位元幣使用的 sha256 演算法,會有

隱匿性:也就是說,對於乙個給定的輸出結果 h(x) ,想要逆推出輸入 x ,在計算上是不可能的。如果想要得到 h(x) 的可能的原輸入,不存在比窮舉更好的方法。

常見的雜湊函式有:sha1、md5、sha2等

雜湊表就是利用雜湊函式,可以根據關鍵碼而直接進行訪問的資料結構,也就是將關鍵碼(key value)通過雜湊函式對映到表中的乙個位置來進行訪問。由於是直接訪問,所以對於雜湊表的元素理論上的增刪改查時間複雜度都是o(1)。

而計算雜湊位址的方法有很多種,通常我們使用的是除留餘數法,也就是說使用雜湊函式對關鍵字得到的輸出值對雜湊表長度取餘得到的餘數即為雜湊位址。

由於我們的輸入長度和範圍是任意的,但是經過雜湊函式後的輸出值域是固定的,所以必然會產生衝突。如上圖的buckets152(紅色區域)就相當於發生衝突!處理衝突的方法有:

c++的hash_map和map的用法很類似,但一定要區別,map和hash_map雖然都是key-value形式,但是map的底層是紅黑樹,而hash_map的底層是hash表!如果在linux下使用hash_map,一定要加上乙個__gnu_cxx的命名空間宣告!

#include#includeusing namespace __gnu_cxx;    // linux下使用時,需要加上這句話才可以使用hash_map.

using namespace std;

int main(int args, char** ar**)); // 兩種插入元素的方法

演算法工程師之路

左神演算法學習筆記基礎篇(7) 雜湊函式

設計一種結構,在該結構中有三個功能 insert key 將某個key加入到該結構,做到不重複加入。delete key 將原本在結構中的某個key移除。getrandom 等概率隨機返回結構中的任何乙個key。要求 這三個功能的時間複雜度都為o 1 建立兩張雜湊表 map1 map2 keystr...

左神演算法 RandomPool

題目 設計一種結構,在該結構中有如下三個功能 insert key 將某個key加入到該結構,做到不重複加入。delete key 將原本在結構中的某個key移除。getrandom 等概率隨機返回結構中的任何乙個key。要求 insert delete和getrandom方法的時間複雜度都是 o ...

左神演算法課總結(hash函式及應用)

hash 雜湊 又稱 雜湊 雜湊 hash 英文原意是 混雜 拼湊 重新表述 的意思。在某種程度上,雜湊是與排序相反的一種操作,排序是將集合中的元素按照某種方式比如字典順序排列在一起,而雜湊通過計算雜湊值,打破元素之間原有的關係,使集合中的元素按照雜湊函式的分類進行排列。在介紹一些集合時,我們總強調...