關於hash的一些話

發現hash在面試和實際應用中是一個很熱門的話題,大家都知道,在java中,hashmap和hashset都是通過hash進行存儲的,查找的速度非常的快,可以用來處理海量數據。那麼,我想提出以下幾個問題:

1、hash到底是什麼東東?

hash啊,我個人理解,就是通過一個hash函數(這個函數的寫法是關鍵,寫得好,衝突少),對某個對象進行求值,得到一個hash值,就像MD5一樣,對一個字符串進行求MD5,不過MD5是唯一的,不會重複(理論上是這樣),而hash值可能會重複,例如,對對象A求hash,得到的hash值是100,對對象B求hash,得到的hash值也是100,那麼,我們就說產生了衝突,這不是一個好的現象,取決於hash函數的算法是否OK。

2、產生了衝突,那麼怎麼辦捏?

衝突是不可避免的,既然不能避免,那麼我們就來處理(待會我會講講如何最大限度的避免),書上網上方法我總結了一下,主要有如下幾種:

1. 開放尋址法;

Hi=(H(key) + di) MOD m, i=1,2,…, k(k<=m-1),其中H(key)爲散列函數,m爲散列表長,di爲增量序列,可有下列三種取法:   

A. di=1,2,3,…, m-1,稱線性探測再散列;   

B. di=1^2, (-1)^2, 2^2,(-2)^2, (3)^2, …, ±(k)^2,(k<=m/2)稱二次探測再散列;   

C. di=僞隨機數序列,稱僞隨機探測再散列。 ==   

2. 再散列法:Hi=RHi(key), i=1,2,…,k RHi均是不同的散列函數,即在同義詞產生地址衝突時計算另一個散列函數地址,直到衝突不再發生,這種方法不易產生“聚集”,但增加了計算時間。   

3. 鏈地址法(拉鍊法)   

4. 建立一個公共溢出區

具體詳細,大家百度下看看就知道了。

3、解釋下啥是裝填因子

java中,hash的默認裝填因子是0.75,那麼啥是裝填因子捏?舉個例子,你要對5個對象進行hash,而內存中,準備了20個位子,來放他們,那麼,最後,就有15個空位啦,那麼裝填因子就是   5/20  ,裝填因子就爲0.45啦,你裝填因子越小,說明你備用的內存空間越多,裝填因子的選定,可以影響衝突的產生,百度百科上說,裝填因子越小,衝突越小(這個不是很理解,爲啥捏?)

4、啥是hash表?

理解成hash值和對象一對一映射的一個表,表的大小爲對象的大小。

5、常用的構造hash函數的方法(摘至百科)

  散列函數能使對一個數據序列的訪問過程更加迅速有效,通過散列函數,數據元素將被更快地定位ǐ   

A. 直接尋址法:取關鍵字或關鍵字的某個線性函數值爲散列地址。即H(key)=key或H(key) = a·key + b,其中a和b爲常數(這種散列函數叫做自身函數)   

B. 數字分析法   

C. 平方取中法   

D. 摺疊法   

E. 隨機數法   

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

6、啥是關鍵碼

關鍵碼就是在對某個對象求hash的時候,hash函數是根據那個字段來進行求hash的,例如: y=mx;  y是hash函數,x就是那個關鍵碼。

7、那如何生產出一個高效,衝突少,分佈均勻的hash函數呢?(淘寶面試問了我這個問題,後來我問了我們老師,現在在等答案,有答案了再更新吧)

1、質數理論,就是除留餘數法那個除數(除數也就是內存的長度)要是一個質數( 這個是TB給我的答案

2、裝填因子選定要合適,理論上越小越好(這個答案我也不是很理解)

3、、、、、

4、、、、

想到的基本就這樣寫了,歡迎大家跟帖補充

發佈了56 篇原創文章 · 獲贊 8 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章