Hash演算法學習小記(一)

2022-04-28 15:54:13 字數 1481 閱讀 1524

關於hash演算法的應用是十分廣泛的,其中的最簡單的原因就是我們生活的這個時代每天都在產生著巨大複雜資料,但是對於我們有價值的資料的挖掘和儲存一直是乙個難點。如何把我們找到和我們密切相關的且有價值的資料一直是電腦科學面臨的關鍵問題。hash演算法從某種角度講,其實就是為了解決這一問題,儘管效果會因具體的問題和資料體積而參差不齊。所以有必要對hash演算法做乙個學習,這裡是自己的一點小紀錄。

先從資料結構的雜湊開始,hash table由雜湊實現,雜湊是一種用於「以常數平均時間來執行插入,刪除和查詢」的技術。

雜湊(hasing)的核心其實就是把我們的資訊項,又叫key對映到hashtable中的不同位置中去。所以這裡的有兩個直接的問題需要解決,一是對映函式如何設計,二是當不同的key帶人到hash fuction後得到的儲存位置相同怎麼辦(collision)?

ok,現在先看第乙個問題:hash fuction?

一般的方法是針對int型資料,我們直接對其用儲存單元大小將他們分別取餘來儲存。但是有乙個數學的問題會出現,當我們用來儲存的記憶體即hashtable大小是一些非質數時比如10,9等,又當key為帶零的整數或是可以被9整除的數時,這種hash function的結果往往等於0,而發生大量衝突。所以在hashtable的大小size時,往往採用數素來定義,ok,這裡也可以說明在數學中一下求最大數素或和研究數素性質的猜想的重要作用了,呵呵~

ok,我們以int型資料和string型資料為例來,做乙個簡單的hash function:

typedef string elemtype;//int

int hash(const elemtype &key,int tabsize){

int datanumed=0;

for(int i=0;idatanumed+=key[i];

return datanumed%tabsize;   

其實上面的hash function當tabsize很大時,我們往往不能保證資料儲存的分布均勻,甚至仍會有很多衝突發生。

那麼如何設計hash函式呢?那首先要明確問題處在**,這裡我們把hash函式的問題先列出來:1.盡量不讓key發生collision。2.盡量讓key在hash table中均有分布,即不要浪費儲存資源。

ok,還是上面的string的hashfunction,我們對其進一步改造,希望hash 的key值統計時可以盡量充滿tablesize,同時要注意和利用計數溢位的情況:

typedef string elemtype;

int hash(const elemtype &key,int size){

int count=0;

for(int i=0;icount=(24+10+1)*count+key[i];

int hashval=0;

hashval=count % size;

if(hashval<0)  hashval+=size;

return hashval; 

ok,下一步,我們就來看看第乙個問題,關於collision的解決方法.

km演算法學習小記

這個演算法其實在學匈牙利演算法時就看過了,不過當時沒搞懂?現在一看,其實還挺好理解的。km演算法是求最大權完備匹配,事實上它同時能處理最小權完備匹配 把邊權取反 和非完備匹配 新增原本不存在的邊且邊權賦值為0 另外還在一位神犇的部落格裡了解到,如果我想要邊權之積最大,則每條邊權取自然對數,然後求最大...

帶花樹演算法學習小記

眾所周知,帶花樹演算法用來解決一般圖最大匹配問題。因為人很菜理解不清楚,所以建議對板理解。以下都是本人的感性理解,有不嚴謹的說法請包涵。同樣是找增廣路。增廣路定義為一條路徑 p 1,p 2,dots,p k 滿足 p 2,p 3 匹配,p 4,p 5 匹配 p p 匹配。p 1 和 p k 不在匹配...

一致性hash演算法學習

在解決分布式系統中負載均衡的問題時候可以使用hash演算法讓固定的一部分請求落到同一臺伺服器上,這樣每台伺服器固定處理一部分請求,起到負載均衡的作用。但是普通的餘數hash hash 比如使用者id 伺服器機器數 演算法伸縮性很差,當新增或者下線伺服器機器時候,使用者id與伺服器的對映關係會大量失效...