1. 程式人生 > >資料結構——hash函式、散列表

資料結構——hash函式、散列表

散列表(hash表):是根據關鍵碼值而直接進行訪問的資料結構

在記錄的儲存位置和它的關鍵字之間建立一個確定的對應關係f,使每一個關鍵字和結構中唯一的儲存位置相對應。稱這個對應關係f為雜湊(hash)函式,按這個思想建立的表為雜湊表若關鍵字為k,則其值存放在f(k)的儲存位置上。

對不同的關鍵字可能得到同一雜湊地址,即k1≠k2,而f(k1)=f(k2),這種現象稱為衝突。具有相同函式值的關鍵字對於該雜湊函式來說稱作同義詞。(此處,k1,k2互為同義詞)

根據雜湊函式f(k)處理衝突的方法將一組關鍵字對映到一個有限的連續的地址集(區間)上,並以關鍵字k在地址集中的“像”f(k)作為記錄在表中的儲存位置

,這種表便稱為散列表,所得的儲存位置稱雜湊地址

實際工作中需視不同的情況採用不同的雜湊函式和不同的處理碰撞衝突的方法。

常用的hash函式:

  • 直接地址法
  • 數字分析法
  • 平方取中法
  • 摺疊法
  • 除留餘數法(H\left ( key \right )=key MOD\displaystyle p,p\leq M,選p為素數或小於20的質因數的和數,eg:3,5,7,15,23.....)
  • 隨機法

雜湊函式和鍵的型別有關,eg:如果鍵是一個數字, 我們可以直接使用這個數字;如果鍵是一個字串,就需要將這個字串轉化為一個數字;如果鍵包含多個部分(比如email地址),就需要某種方法將這些部分結合起來。 

構造hash函式 需要考慮的因素有:

  • 計算hash函式所需時間;
  • 關鍵字的長度;
  • hash表的大小;
  • 關鍵字的分佈情況;
  • 記錄的查詢頻率。

對於長度為M的表,必須滿足\forall k,f(k)\sqsubseteq (0,M-1),即任何關鍵字所得的儲存位置必須落在表長允許範圍內。

常用處理衝突的方法:

  • 開放地址法(依靠陣列中的空位解決碰撞衝突,要求陣列長度M〉鍵值對個數N)
  • 再雜湊法
  • 鏈地址法 (將所有關鍵字為同義詞的記錄儲存在同一線性連結串列中)。最常用
  •  建立一個公共溢位區

 圖中,紫色部分即代表雜湊表,也稱為雜湊陣列,陣列的每個元素都是一個單鏈表的頭節點,連結串列是用來解決衝突的,如果不同的key對映到了陣列的同一位置處,就將其放入單鏈表中。

  java中的HashMap的底層主要就是基於陣列和連結串列來實現的,HashMap底層是通過連結串列來解決hash衝突的。