最近在作負荷分擔的優化,將數據流均勻分到八條流中,學習點哈希算法算法
什麼是哈希表?
哈希表(Hash table,也叫散列表),是根據關鍵碼值(Key value)而直接進行訪問的數據結構。也就是說,它經過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。這個映射函數叫作散列函數,存放記錄的數組叫作散列表。說白了哈希表的原理其實就是經過空間換取時間的作法。。
哈希表的作法其實很簡單,就是把Key經過一個固定的算法函數既所謂的哈希函數轉換成一個整型數字,而後就將該數字對數組長度進行取餘,取餘結果就看成數組的下標,將value存儲在以該數字爲下標的數組空間裏。
而當使用哈希表進行查詢的時候,就是再次使用哈希函數將key轉換爲對應的數組下標,並定位到該空間獲取value,如此一來,就能夠充分利用到數組的定位性能進行數據定位。。數組
哈希函數的構造方法: 數據結構
若對於關鍵字集合中的任一個關鍵字,哈希函數映像到地址集合中任何一個地址的機率是相等的,則稱此類哈希函數爲均勻的哈希函數。換句話說,就是使關鍵字通過哈希函數獲得一個「隨機的地址「,以便使一組關鍵字的哈希地址均勻分佈在整個地址區間中,從而減小衝突。
(1)直接定址法
取關鍵字或關鍵字的某個線性函數值爲哈希地址。即: H(key)=key或H(key)=a*key+b; 其中a和b爲常數(這種哈希函數叫作自身函數)。
因爲直接定址所得地址集合和關鍵字集合的大小相同。所以,對於不一樣的關鍵字不會發生衝突。但實際中使用這種哈希函數的狀況不多。
(2)數字分析法
假設關鍵字是以r爲基的數(如:以10爲基的十進制數),而且哈希表中可能出現的關鍵字都是事先知道的,則可取關鍵字的若干數位組成哈希地址。
(3)平方取中法
取關鍵字平方後的中間幾位爲哈希地址。
(4)斐波那契(Fibonacci)散列法
平方散列法的缺點是顯而易見的,因此咱們能不能找出一個理想的乘數,而不是拿value自己看成乘數呢?答案是確定的。
1)對於16位整數而言,這個乘數是40503
2)對於32位整數而言,這個乘數是2654435769
3)對於64位整數而言,這個乘數是11400714819323198485
這幾個「理想乘數」是如何得出來的呢?這跟一個法則有關,叫黃金分割法則,而描述黃金分割法則的最經典表達式無疑就是著名的斐波那契數列,即如此形式的序列:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144,233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946,…。另外,斐波那契數列的值和太陽系八大行星的軌道半徑的比例出奇吻合。
對咱們常見的32位整數而言,公式: index = (value * 2654435769) >> 28
(5)摺疊法
將關鍵字分割成位數相同的幾部分(最後一部分的位數能夠不一樣),而後取這幾部分的疊加和(捨去進位)做爲哈希地址,這方法稱爲摺疊法。
(6)除留餘數法(==最經常使用的方法)
取關鍵字被某個不大於哈希表表長m的數p除後所得餘數爲哈希地址。即H(key)=key MOD p,(p<=m),這是一種最簡單,也是最經常使用的構造哈希函數的方法。它不只能夠對關鍵字直接取模(MOD),也可在摺疊、平方取中等運算以後取模。
(7)隨機數法
選擇一個隨機函數,取關鍵字的隨機函數值爲它的哈希地址,即H(key)=random(key),其中random爲隨機函數。一般,當關鍵字長度不等時採用此法構造哈希函數較切當。
總結:
實際工做中需視不一樣狀況採用不一樣的哈希函數,一般,考慮的因素有:
(1)計算哈希函數所需時間(包括硬件指令的因素);
(2)關鍵字的長度;
(3)哈希表的大小;
(4)關鍵字的分佈狀況;
(5)記錄的查找頻率。dom
處理衝突的方法(衝突只能減小,不能避免):
(1)開放定址法
(2)再哈希法
(3)鏈地址法
(4)創建一個公共溢出區
哈希表的查找及其分析:
在哈希表上進行查找的過程和哈希造表的過程基本一致。給定的K值,根據造表時設定的哈希函數求得哈希地址,若表中此位置上沒有記錄,則查找不成功;不然必將關鍵字,若和給定的值相等,則查找成功;不然根據造表時設定的處理衝突的方法找」下一地址「,直至哈希表中的某個位置爲」空「或者表中所填記錄的關鍵字等於給定值時爲止。
哈希表的裝填因子定義爲:
α=(表中填入的記錄數)/(哈希表的長度)函數