哈希算法python_哈希算法(Python代码实现)
1.常見的數(shù)據(jù)查找算法:
眾所周知,順序查找是最簡單的查找方式,但要將所有數(shù)據(jù)遍歷一遍所以效率相對較低,對大數(shù)據(jù)量的査找問題顯然不行。二分查找的查找效率雖然非常高但是數(shù)據(jù)必須有序,而對數(shù)據(jù)排序通常需要更多的時間,因此只適用于在排好序的數(shù)據(jù)中找。而深度優(yōu)先搜索算法、廣度優(yōu)先搜索算法 ,是一種暴力査找法優(yōu)化算法,同樣對大數(shù)據(jù)量的查找問題效率也不高。哈希算法也是一種查找算法,可以說哈希算法是最快的查找算法。對于查找問題,哈希算法一直是首選算法。
2.算法原理及特點:
1> 簡單來說,就是把一些復雜的數(shù)據(jù)通過某種函數(shù)映射關系映射成更加易于査找的方式。每個數(shù)據(jù)都會映射為獨一無二的地址,數(shù)據(jù)存儲時它會存儲于這個地址取數(shù)據(jù)時還會在這個地址取。哈希算法就像一本字典,當需要査詞的時候通過目錄找到頁碼,再到對應頁碼就能找到所需要的內(nèi)容了。
用書面語解釋就是:根據(jù)總體數(shù)據(jù)量預先設置一個數(shù)組,使用一個哈希函數(shù)并以數(shù)據(jù)的關鍵字作為自變量得到唯一的返回值。這樣就可以利用哈希函數(shù)將數(shù)據(jù)元素映射到數(shù)組的某位置并把數(shù)據(jù)存放在對應位置上。在查找時,通過哈希函數(shù)計算該數(shù)據(jù)應該存儲在哪里再到相應的存儲位置取出查找的數(shù)據(jù)。
2> 哈希算法的查找速度與數(shù)據(jù)多少無關,在沒有發(fā)生”碰撞”或“溢出”的情況下,只需一次讀取。同時該算法的保密性特別好,如果事先不知道哈希函數(shù)就無法進行查找從而獲得數(shù)據(jù)。(注意:設計一個好的哈希函數(shù)是重中之重,好的哈希函數(shù)應該使每個關鍵字都盡可能地散列到每一個位置中去。面對的第一個問題就是如何設計一個易于計算并且均勻分布所有的鍵的哈希函數(shù)。)
2.常見算法:(除法哈希算法、乘法哈希算法、平方取中法、隨機數(shù)哈希算法等。)
除法哈希算法:用每一個關鍵字去除以一個特定的質(zhì)數(shù),所得的余數(shù)就是該關鍵字的哈希值。通過 x 除以 m 的余數(shù)將關鍵字映射到數(shù)組的 m 個位置中。
除哈希函數(shù)公式為? :? ? ? ? ? ? ? ? h(x) = x mod m
舉個例子,設計一個程序,以除留余數(shù)法的哈希算法取得索引值,再用線性探測法來儲存數(shù)據(jù)。(線性探測法是用于處理當數(shù)據(jù)發(fā)生碰撞時,若該索引對應的儲存位置已有數(shù)據(jù),則會以線性的方式依次往后尋找空的存儲位置且此時該方法將存儲的位置視為一個環(huán)形結(jié)構(gòu),如果后面的位置被填滿而前面還有位置時數(shù)據(jù)還可以放在前面。但線性探測法也有缺點,相似的鍵值對經(jīng)常會匯聚在一起,因此平方探測法(或稱為二次探測法)也經(jīng)常被使用,只不過此處并不討論。)
import random
INDEXBOX=10 #哈希表最大元素
MAXNUM=7 #最大數(shù)據(jù)個數(shù)
def print_data(data,max_number): #打印數(shù)組子程序
print('\t',end='')
for i in range(max_number):
print('[%2d] ' %data[i],end='')
print()
#線性探測法
def create_table(num,index): #建立哈希表子程序
tmp=num%INDEXBOX #哈希函數(shù) = 數(shù)據(jù)%INDEXBOX
while True:
if index[tmp]==-1: #如果數(shù)據(jù)對應的位置是空的
index[tmp]=num #則直接存入數(shù)據(jù)
break
else:
tmp=(tmp+1)%INDEXBOX #否則往后找位置存放
#主程序
index=[None]*INDEXBOX
data=[None]*MAXNUM
print('原始數(shù)組值:')
for i in range(MAXNUM): #起始數(shù)據(jù)值
data[i]=random.randint(1,20)
for i in range(INDEXBOX): #清除哈希表
index[i]=-1
print_data(data,MAXNUM) #打印起始數(shù)據(jù)
print('哈希表的內(nèi)容:')
for i in range(MAXNUM): #建立哈希表
create_table(data[i],index)
print(' %2d =>' %data[i],end='') #打印單個元素的哈希表位置
print_data(index,INDEXBOX)
print('完成的哈希表:')
print_data(index,INDEXBOX) #打印最后完成的結(jié)果
結(jié)果:
乘法哈希算法:對給定的長度為 m 的數(shù)組,用關鍵字 x 乘以一個常數(shù) N, N 的值為大于0 并小于 1 的一個小數(shù),并提取出 Nx 的小數(shù)部分。之后,用 m 乘以這個小數(shù),再向下取整哈希函數(shù)公式為:? ? ? ? ? ?h(x) = ?m(Nx mod 1)?
(?,?,表示向下取整,其中 Nx mod 1 的意思就是 x 的小數(shù)部分。相對于除法哈希算法,乘法哈希算法對于數(shù)組的長度 m 沒有過多的要求。研究表明N 的值為 0.618 較好。)
例:關鍵字 8 需要存儲,哈希函數(shù)為 h(x) = ?10 × (0.618x mod 1)?,
計算過程如下:h(8) = ?10 × (0.618 × 8 mod 1)? = ?10 × (4.944 mod 1)? = ?10 × 0.944? = ?9.44? = 9
那么利用哈希函數(shù)存儲的數(shù)據(jù)如圖所示,注意數(shù)組下標從 0 開始。
平方取中法:首先計算出關鍵字的平方值,然后取平方值中間幾位作為哈希地址。哈希函數(shù)公式為:
h(x) = mid(x · x,n)? ? ? (其中 mid 的意思就是選取中間 n 位的函數(shù)。)
例:關鍵字的集合為 [123,234,245], 它們對應的平方值為[15129,54756,60025],如果我們選擇平方值的千位和百位作為哈希值,則它們的哈希值為 [51,47,0]。
例如,關鍵字 245 需要存儲,哈希函數(shù)為 h(x) = mid(x·x,2),計算過程如下:
h(245) = mid(245 × 245,2) = mid(60025,2) = 0
那么利用哈希函數(shù)存儲的數(shù)據(jù)如圖所示,注意數(shù)組下標從 0 開始。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結(jié)
以上是生活随笔為你收集整理的哈希算法python_哈希算法(Python代码实现)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: shell排序_Java后端技术精选:希
- 下一篇: python ssh登录设备_用Pyth