1. 程式人生 > >【Python算法】哈希存儲、哈希表、散列表原理

【Python算法】哈希存儲、哈希表、散列表原理

blank images 去掉 常用 ack 個數 style middle 1=1

哈希表的定義:

  哈希存儲的基本思想是以關鍵字Key為自變量,通過一定的函數關系(散列函數或哈希函數),計算出對應的函數值(哈希地址),以這個值作為數據元素的地址,並將數據元素存入到相應地址的存儲單元中。

  查找時再根據要查找的關鍵字采用同樣的函數計算出哈希地址,然後直接到相應的存儲單元中去取要找的數據元素即可。

哈希表的應用:

  哈希表(hash table)是實現字典操作的一種有效的數據結構。

  盡管最壞的情況下,散列表中查找一個元素的時間與鏈表中查找的時間相同,達到了O(n)。

  然而實際應用中,散列的查找的性能是極好的。在一些合理的假設下,在散列表中查找一個元素的平均時間是O(1)。

建立哈希表操作步驟:

  1) step1 取數據元素的關鍵字key,計算其哈希函數值(地址)。若該地址對應的存儲空間還沒有被占用,則將該元素存入;否則執行step2解決沖突。

  2) step2 根據選擇的沖突處理方法,計算關鍵字key的下一個存儲地址。若下一個存儲地址仍被占用,則繼續執行step2,直到找到能用的存儲地址為止。

常用的哈希函數:

  構造哈希函數的方法有很多,總的原則是盡可能將關鍵字集合空間均勻的映射到地址集合空間中,同時盡可能降低沖突發生的概率。

1、除留余數法:

  H(Key) = key % p (p ≤ m)

  取關鍵字除以p的余數作為哈希地址,p最好選擇一個小於或等於m(哈希地址集合的個數)的某個最大素數

哈希表長度 8 16 32 64 128 256 512
最大素數 7 13 31 61 127 251 503

2、直接地址法

  H(Key) = a * Key + b;這個“a,b”是常量。

3、數字分析法

  比如有一組key1=112233,key2=112633,key3=119033,

  針對這樣的數我們分析數中間兩個數比較波動,其他數不變。那麽我們取key的值就可以是 key1=22,key2=26,key3=90。

4、平方取中法

  此處忽略,見名識意。

5、折疊法

  比如key=135790,要求key是2位數的散列值。那麽我們將key變為13+57+90=160,然後去掉高位“1”,此時key=60,

  這就是他們的哈希關系,這樣做的目的就是地址與每一位的key都相關,來做到“散列地址”盡可能分散的目地。

沖突處理方法:

  影響哈希查找效率的一個重要因素是哈希函數本身。當兩個不同的數據元素的哈希值相同時,就會發生沖突。為減少發生沖突的可能性,哈希函數應該將數據盡可能分散地映射到哈希表的每一個表項中。

  解決沖突的方法有以下兩種: 

  (1) 開放地址法  

    如果兩個數據元素的哈希值相同,則在哈希表中為後插入的數據元素另外選擇一個表項。

    當程序查找哈希表時,如果沒有在第一個對應的哈希表項中找到符合查找要求的數據元素,程序就會繼續往後查找,直到找到一個符合查找要求的數據元素,或者遇到一個空的表項。  

    ①.線性探測法

      這種方法在解決沖突時,依次探測下一個地址,直到有空的地址後插入,若整個空間都找遍仍然找不到空余的地址,產生溢出。

      Hi =( H(Key) + di ) % m ( i = 1,2,3,...,k , k ≤ m-1 )

      地址增量 di = 1,2,...,m-1 , 其中 i 為探測次數

    ②.二次探測法

      地址增量序列為:di = 12,-12,22,-22 ,...,q2,-q2 (q ≤ m/2)

    ③.雙哈希函數探測法

      Hi =( H(Key) + i * RH(Key) ) % m ( i = 1,2,3,..., m-1 )

      H(Key) , RH(Key) 是兩個哈希函數,m為哈希表長度。

      先用第一個哈希函數對關鍵字計算哈希地址,一旦產生地址沖突,再用第二個函數確定移動的步長寅子,最後通過步長因子序列由探測函數尋找空余的哈希地址。

      H1 = ( a+b )%m , H2 = ( a + 2b )%m , ... , Hm-1 = ( a+(m-1)*b )%m

  (2) 鏈地址法

    將哈希值相同的數據元素存放在一個鏈表中,在查找哈希表的過程中,當查找到這個鏈表時,必須采用線性查找方法。

    技術分享

Python字典dict的實現 是使用開放尋址法中的二次探查來解決沖突的。

?? 參考鏈接

【Python算法】哈希存儲、哈希表、散列表原理