DS Hash表及布隆過濾器

2021-07-13 02:30:41 字數 3865 閱讀 7943

什麼是hash

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

hash主要用於資訊保安領域中加密演算法,它把一些不同長度的資訊轉化成雜亂的128位的編碼,這些編碼值叫做hash值. 也可以說,hash就是找到一種資料內容和資料存放位址之間的對映關係。

雜湊表是根據關鍵字key直接訪問在記憶體儲存位置的資料的一種資料結構。也就是說,它通過計算乙個關於鍵值的函式,將所需查詢的資料

對映到表中乙個位置來訪問記錄,這加快了查詢速度。這個對映函式稱做

雜湊函式

,存放記錄的陣列稱做雜湊表。

它通過乙個關鍵值的函式將所需的資料對映到表中的位置來訪問資料,這個對映函式叫做雜湊函式,存放記錄的陣列叫做雜湊表。

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

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

數字分析法:假設關鍵字是以r為基的數,並且雜湊表中可能出現的關鍵字都是事先知道的,則可取關鍵字的若干數字組成雜湊位址。

平方取中法:取關鍵字平方後的中間幾位為雜湊位址。通常在選定雜湊函式時不一定能知道關鍵字的全部情況,取其中的哪幾位也不一定合適,而乙個數平方後的中間幾位數和數的每一位都相關,由此使隨機分布的關鍵字得到的雜湊位址也是隨機的。取的位數由表長決定。

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

隨機數法

除留餘數法:取關鍵字被某個不大於雜湊表表長m的數p除后所得的餘數為雜湊位址。即}p}, 。不僅可以對關鍵字直接取模,也可在摺疊法、平方取中法等運算之後取模。對p的選擇很重要,一般取素數或m,若p選擇不好,容易產生衝突。

以下結構都採用除留餘數法來建立雜湊表:使用key%陣列的大小所得值為雜湊位址。

什麼是hash衝突

不同的key值經過雜湊函式hash(key)處理之後可能產生相同的值雜湊位址,這種情況為雜湊衝突,任意的hash函式都不能避免雜湊衝突。

雜湊表的載荷因子 :

解決hash衝突的方法

線性探測:當經過hash(key)得出的雜湊位置被占用,則

往後順序依次key+i的順序查詢沒有被使用的值,

來存放資料,i遞增。

二次探測:當經過hash(key)得出的雜湊位置被占用,則

往後順序按照key+i^2的順序查詢沒有被使用的值,

來存放資料,i遞增。

如圖所示:

處理雜湊衝突的開鏈法,雜湊桶,結構如下:

由於hash函式採用除留餘數法,而且除數一般是建立的雜湊表的capacity(容量),所以為了減少雜湊衝突,我們應該盡量使capacity為素數,這樣可以一定程度上減少雜湊衝突。

下面給上有關雜湊表實現的**,基於線性探測,二次探測,雜湊桶的資料結構實現。

什麼是布隆過濾器:

在日常生活中,包括在設計計算機軟體時,我們經常要判斷乙個元素是否在乙個集合中。最直接的方法就是將集合中全部的元素存在計算機中,遇到乙個新 元素時,將它和集合中的元素直接比較即可。一般來講,計算機中的集合是用雜湊表(hash table)來儲存的。它的好處是快速準確,缺點是費儲存空間。當集合比較小時,這個問題不顯著,但是當集合巨大時,雜湊表儲存效率低的問題就顯現出來 了。為此我們引入了布隆過濾器,它其實只是一種檢測手段而已,而不會真正的儲存資料值。

布隆過濾器是由bitmap和幾個hash函式實現的,主要用於檢查乙個元素是否存在與乙個集合中,他的優點就是查詢時間和快空間效率都優於其他的演算法,缺點就是他有誤錯率。

如果想判斷乙個元素是不是在乙個集合裡,一般想到的是將所有元素儲存起來,然後通過比較確定。鍊錶,樹等等資料結構都是這種思路. 但是隨著集合中元素的增加,我們需要的儲存空間越來越大,檢索速度也越來越慢。不過世界上還有一種叫作

雜湊表(又叫雜湊表,hash table)的資料結構。它可以通過乙個hash函式將乙個元素對映成乙個位陣列(bit array)中的乙個點。這樣一來,我們只要看看這個點是不是 1 就知道可以集合中有沒有它了。這就是布隆過濾器的基本思想。

hash面臨的問題就是衝突。假設 hash 函式是良好的,如果我們的位陣列長度為 m 個點,那麼如果我們想將衝突率降低到例如 1%, 這個雜湊表就只能容納 m/100 個元素。顯然這就不叫空間有效了(space-efficient)。解決方法也簡單,就是使用多個 hash,如果它們有乙個說元素不在集合中,那肯定就不在。如果它們都說在,雖然也有一定可能性它們在說謊,不過直覺上判斷這種事情的概率是比較低的。

布隆過濾器的缺點分析:可能你要查詢的元素並不存在,但是以前插入的資料剛好將你的key經過幾個對映函式的bit位置為1,這就造成一種假象,你要查詢的資料存在。直覺上判斷這種情況發生的概率還是比較低的,能想到的就是當你的資料量很大 的時候,這種錯誤率就明顯上公升了。

如圖分析:x元素經過4個hash函式對映的bit位置為1,y,z同樣如此,但是此時要對映m元素時,經過hash函式剛好對映到這幾個bit位上,就會對其是否存在的判斷存在影響。

在很多key-value系統中也使用了布隆過濾器來加快查詢過程,如 hbase,accumulo,leveldb,一般而言,value 儲存在磁碟中,訪問磁碟需要花費大量時間,然而使用布隆過濾器可以快速判斷某個key對應的value是否存在,因此可以避免很多不必要的磁碟io操作,只是引入布隆過濾器會帶來一定的記憶體消耗,下圖是在key-value系統中布隆過濾器的典型使用:

1,當插入的資料增加時,判斷效率就降低了。當插入的資料越來越多時,bit位的占用也就越來越多,因此造成的誤差判斷也就越來越多。判斷效率下降。

2,無法增容,沒有key值,無法得知原來的數。當擴容時,原來儲存的節點的資料就不準確,因此還要重新設計

布隆過濾器無法增容是因為,它不具有hash表的key值,當你擴容時,以前儲存的資料就沒有對映到,增容後的位置。以前的對映也就沒有用,因此得重新插入資料,進行對映。

3,無法刪除。刪除的時候可能影響其他節點雜湊值

設計乙個可以刪除的布隆過濾器,對每個位記錄其引用計數。

設計思路:bitmap_arr;將bitmap 的乙個int拆分出來,最高位作為bit位,判斷資料存在與否,其他的31作為引用計數(引用計數值可達21億,這個值可以根據具體的情況來分析,以此來設定引用計數的位數,當然也可以將vector的int改為char),當引用計數字0時才真正的將此bit位置為0;其他情況引用計數減一;

布隆過濾器

布隆過濾器 bloom filter 是1970年由布隆提出的。它實際上是乙個很長的二進位制向量和一系列隨機對映函式。布隆過濾器可以用於檢索乙個元素是否在乙個集合中。它的優點是空間效率和查詢時間都遠遠超過一般的演算法,缺點是有一定的誤識別率和刪除困難。如果想要判斷乙個元素是不是在乙個集合裡,一般想到...

布隆過濾器

布隆過濾器的概念 如果想要判斷乙個元素是不是在乙個集合裡,一般想到的是將所有元素儲存起來,然後通過比較確定。鍊錶,樹等等資料結構都是這種思路.但是隨著集合中元素的增加,我們需要的儲存空間越來越大,檢索速度也越來越慢 o n o logn 不過世界上還有一種叫作雜湊表 又叫 雜湊表,hash tabl...

布隆過濾器

如果想判斷乙個元素是不是在乙個集合裡,一般想到的是將集合中所有元素儲存起來,然後通過比較確定。鍊錶 樹 雜湊表 又叫雜湊表,hash table 等等資料結構都是這種思路。但是隨著集合中元素的增加,我們需要的儲存空間越來越大。同時檢索速度也越來越慢。bloom filter 是一種空間效率很高的隨機...