日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hash函数的构造方法

發(fā)布時間:2023/12/31 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hash函数的构造方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

哈希函數(shù)的構造方法


哈希函數(shù)的構造方法

本文闡述了哈希函數(shù)的構造方法有很多,但應注意兩個原則:第一,函數(shù)值應在1至記錄總數(shù)之間;第二,盡可能避免沖突。

設要存放的數(shù)據(jù)元素有n個,存放數(shù)據(jù)元素的內(nèi)存單元有m個,設計哈希函數(shù)的目標就是要使通過哈希函數(shù)得到的n個數(shù)據(jù)元素的哈希地址盡可能均勻地分布在m個連續(xù)內(nèi)存單元上,同時使計算過程盡可能簡單以達到盡可能高的時間效率。

?

?

????????????????

引?言

構造哈希函數(shù)的方法很多。如何構造一個“好”的哈希函數(shù)是很強的技術性和實踐性問題,這里的“好”指的是哈希函數(shù)構造比較簡單,并且用此哈希函數(shù)產(chǎn)生的映射所發(fā)生的沖突可能性最小,換句話說一個好的哈希函數(shù)能將給定數(shù)據(jù)集合均勻地映射到給定的地址區(qū)間中。

Hash的原意是“弄亂,切碎”,這里的含義是“雜湊”。基本做法是,根據(jù)集合元素值的分布情況,設計一個哈希函數(shù)h(ki),存儲之素ki時,計算ki的哈希函數(shù)值,元素ki存儲在a(h)中。

如果“幸運”,所設計的哈希函數(shù)很均勻,即任何ki≠kj,都有h(ki)≠h(kj),那么在查找ki時(再計算ki的哈希函數(shù)函數(shù)值h),就能在a[h]中找到元素ki。

1.直接定址法

??直接定址法是以數(shù)據(jù)元素關鍵字k本身或它的線性函數(shù)作為它的哈希地址,即:H(k)=k??或?H(k)=a×k+b?;?(其中a,b為常數(shù))

??例1,有一個人口統(tǒng)計表,記錄了從1歲到100歲的人口數(shù)目,其中年齡作為關鍵字,哈希函數(shù)取關鍵字本身,如圖(1):

地址

A1

A2

……

A99

A100

年齡

1

2

……

99

100

人數(shù)

980

800

……

495

107

可以看到,當需要查找某一年齡的人數(shù)時,直接查找相應的項即可。如查找99歲的老人數(shù),則直接讀出第99項即可。這種哈希函數(shù)簡單,并且對于不同的關鍵字不會產(chǎn)生沖突,但可以看出這是一種較為特殊的哈希函數(shù),實際生活中,關鍵字的元素很少是連續(xù)的。用該方法產(chǎn)生的哈希表會造成空間大量的浪費,因此這種方法適應性并不強。[2]↑

2.數(shù)字分析法

?2.1數(shù)字分析法是取數(shù)據(jù)元素關鍵字中某些取值較均勻的數(shù)字位作為哈希地址的方法。即當關鍵字的位數(shù)很多時,可以通過對關鍵字的各位進行分析,丟掉分布不均勻的位,作為哈希值。它只適合于所有關鍵字值已知的情況。通過分析分布情況把關鍵字取值區(qū)間轉化為一個較小的關鍵字取值區(qū)間。

???例2,要構造一個數(shù)據(jù)元素個數(shù)n=80,哈希長度m=100的哈希表。不失一般性,我們這里只給出其中8個關鍵字進行分析,8個關鍵字如下所示:

K1=61317602??????K2=61326875??????K3=62739628??????K4=61343634

K5=62706815??????K6=62774638??????K7=61381262??????K8=61394220

分析上述8個關鍵字可知,關鍵字從左到右的第1、2、3、6位取值比較集中,不宜作為哈希地址,剩余的第4、5、7、8位取值較均勻,可選取其中的兩位作為哈希地址。設選取最后兩位作為哈希地址,則這8個關鍵字的哈希地址分別為:2,75,28,34,15,38,62,20。[1]↑

2.?2設有n個d?位數(shù),每一位可能有r種不同的符號,這r種不同的符號在各位上出現(xiàn)的頻率不一定相同,可能在某位上分布均勻些,每種符號出現(xiàn)的機會均等;在某位上分布不均勻,只有某幾種符號經(jīng)常出現(xiàn)。可根據(jù)哈希表的大小,選取其中各種符號分布均勻的若干位作為哈希地址。計算各位數(shù)字中符號分布均勻度rk的公式為:rk=其中,aki表示第i個符號k位上出現(xiàn)的的期望值。計算出rk值越小,

i=1

表明在該位(第k位)各種符號分布越不均勻。?

例3,有一組關鍵字,對其各位編碼如下:

9???2???1???4???8

9???1???2???6???9

9???0???5???2???7

9???1???6???3???0

9???1???8???0???5

9???1???5???5???8

9???2???0???4???7

9???0???0???0???1???

①??②??③??④??⑤

①位僅“9”出現(xiàn)8次r1=(8-8/10)2*1+(0-8/10)2*9=57.60

②位“0,2”各出現(xiàn)2次,“1”出現(xiàn)4次r2=(2-8/10)2*2+(4-8/10)2*1+(0-8/10)2*7=17.60

③位“0,5”各出現(xiàn)2次,“1,2,6,8”各出現(xiàn)1次r3=(2-8/10)2*2+(1-8/10)2*4+(0-8/10)2*4=5.60

④位“0,4”各出現(xiàn)2次,“2,3,5,6”各出現(xiàn)1次

⑤位“7,8”各出現(xiàn)2次,“0,1,5,9”各出現(xiàn)1次

r3?=r4?=r5?=5.60

若哈希表地址范圍有3位數(shù)字,取各關鍵字的③④⑤位作為記錄的哈希地址。也可以把第①②和第⑤位想加,舍去進位,變成一位數(shù),再與第③④位合起來哈希地址等。顯然數(shù)字分析法僅適用于事先知道表中所有關鍵字每一位數(shù)值的分布情況,它完全依賴于關鍵字集合。如果換一個關鍵字集合,選擇哪幾位重新決定。

3.折疊法

??所謂折疊法是將關鍵字分割成位數(shù)相同的幾部分(最后一部分的位數(shù)可以不同),然后取這幾部分的疊加和(舍去進位),這方法稱為折疊法。這種方法適用于關鍵字位數(shù)較多,而且關鍵字中每一位上數(shù)字分布大致均勻的情況。

??折疊法中數(shù)位折疊又分為移位疊加和邊界疊加兩種方法,移位疊加是將分割后是每一部分的最低位對齊,然后相加;邊界疊加是從一端向另一端沿分割界來回折疊,然后對齊相加。

例4,當哈希表長為1000時,關鍵字key=110108331119891,允許的地址空間為三位十進制數(shù),則這兩種疊加情況如圖(2):

???????移位疊加?????????????????????????????????邊界疊加

???????8?9?1?????????????????????????????????????8?9?1

???????1?1?9?????????????????????????????????????9?1?1

???????3?3?1?????????????????????????????????????3?3?1

???????1?0?8?????????????????????????????????????8?0?1

????+??1?1?0???????????????????????????????????+?1?1?0??????????????

???(1)?5?5?9??????????????????????????????????(3)0?4?4

?????????????????圖(2)由折疊法求哈希地址

?????用移位疊加得到的哈希地址是559,而用邊界疊加所得到的哈希地址是44。如果關鍵字不是數(shù)值而是字符串,則可先轉化為數(shù)。轉化的辦法可以用ASCⅡ字符或字符的次序值。[3]↑

?

4.平方取中法

??這是一種常用的哈希函數(shù)構造方法。這個方法是先取關鍵字的平方,然后根據(jù)可使用空間的大小,選取平方數(shù)是中間幾位為哈希地址。

哈希函數(shù)?H(key)=“key2的中間幾位”因為這種方法的原理是通過取平方擴大差別,平方值的中間幾位和這個數(shù)的每一位都相關,則對不同的關鍵字得到的哈希函數(shù)值不易產(chǎn)生沖突,由此產(chǎn)生的哈希地址也較為均勻。

例5,若設哈希表長為1000則可取關鍵字平方值的中間三位,如圖(3)所示:

關鍵字

關鍵字的平方

哈希函數(shù)值

1234

1522756

227

2143

4592449

924

4132

17073424

734

3214

10329796

297

圖(3)平方取中哈希函數(shù)示例????[4]?↑

有人曾用“輪盤賭”的統(tǒng)計分析方法對它們進行了模擬分析,結論是平方取中法最接近“隨機化”。

?

??例6,設有一組關鍵字值為ABC,BCD,CDE,DEF其相應的機內(nèi)碼分別為010203,020304,030405,040506。假設可利用地址空間大小為103,平方后取平方數(shù)的中間三位作為相當記錄的存儲地址。如圖(4)所示:?????????

關鍵字

機內(nèi)碼

機內(nèi)碼的平方

哈希地址

ABC

010203

0104101209

101

BCD

020304

0412252416

252

CDE

030405

0924464025

464

DEF

040506

1640736036

736

圖(4)平方取中法關鍵字及其存儲地址[6]↑

???下面給出平方取中法的哈希函數(shù)

?????//平方取中法哈希函數(shù),結設關鍵字值32位的整數(shù)

?????//哈希函數(shù)將返回key?*?key的中間10位

???????Int??Hash?(int?key)

?????????{

?????//計算key的平方

??????Key?*?=?key?;

?????//去掉低11位

?????Key>>=11;

?????//?返回低10位(即key?*?key的中間10位)

???????Return?key?%1024;

??????????}

?

5.減去法

???減去法是數(shù)據(jù)的鍵值減去一個特定的數(shù)值以求得數(shù)據(jù)存儲的位置。

例7,公司有一百個員工,而員工的編號介于1001到1100,減去法就是員工編號減去1000后即為數(shù)據(jù)的位置。編號1001員工的數(shù)據(jù)在數(shù)據(jù)中的第一筆。編號1002員工的數(shù)據(jù)在數(shù)據(jù)中的第二筆…依次類推。從而獲得有關員工的所有信息,因為編號1000以前并沒有數(shù)據(jù),所有員工編號都從1001開始編號。

?

6.基數(shù)轉換法

??將十進制數(shù)X看作其他進制,比如十三進制,再按照十三進制數(shù)轉換成十進制數(shù),提取其中若干為作為X的哈希值。一般取大于原來基數(shù)的數(shù)作為轉換的基數(shù),并且兩個基數(shù)應該是互素的。

?

例8,Hash(80127429)=(80127429)13=8*137+0*136+1*135+2*134+7*133+4*132+2*131+9=(502432641)10如果取中間三位作為哈希值,得Hash(80127429)=432

?為了獲得良好的哈希函數(shù),可以將幾種方法聯(lián)合起來使用,比如先變基,再折疊或平方取中等等,只要散列均勻,就可以隨意拼湊。[5]?↑

?

7.除留余數(shù)法

取關鍵字被某個不大于哈希表表長m的數(shù)p除后所得余數(shù)為哈希地址,即設定哈希函數(shù)為??Hash(key)=key?mod?p?(p≤m),其中,除數(shù)p稱作模。

除留余數(shù)法不僅可以對關鍵字直接取模,也可以在折疊、平方取中等運算后取模。對于除留余數(shù)法求哈希地址,關鍵在于模p的選擇。使得數(shù)據(jù)元素集合中每一個關鍵字通過該哈希函數(shù)映射到內(nèi)存單元的任意地址上的概率相等,從而盡可能減少發(fā)生哈希沖突的可能性。

理論研究表明,除留余數(shù)法的模p取不大于表長且最接近表長m素數(shù)時效果最好,且p最好取1.1n~1.7n之間的一個素數(shù)(n為存在的數(shù)據(jù)元素個數(shù))。例如:當n=7時,p最好取11、13等素數(shù)。?又例圖(5):

表長m

8

16

32

64

128

256

512

1000

模p

7

13

31

61

127

251

503

997

由于除留余數(shù)法的地址計算方法簡單,而且在許多情況下效果較好。[2]↑

例9,公司有236個員工,而員工編號介于1000到9999,除留余數(shù)法就是員工編號除以數(shù)據(jù)個數(shù)236后,去余數(shù)即為數(shù)據(jù)的位置。編號5428員工的數(shù)據(jù)(編號5428除以236取余數(shù)得0)放數(shù)據(jù)中的第一筆,編號3512員工數(shù)據(jù)(編號3512除以236取余數(shù)得8)放數(shù)據(jù)中的第九筆…依次類推。

?

8.隨機乘數(shù)法

??亦稱為“乘余取整法”。隨機乘數(shù)法使用一個隨機實數(shù)f,0≤f<1,乘積f*k的分數(shù)部分在0~1之間,用這個分數(shù)部分的值與n(哈希表的長度)相乘,乘積的整數(shù)部分就是對應的哈希值,顯然這個哈希值落在0~n-1之間。其表達公式為:Hash(k)=「n*(f*k%1)」其中“f*k%1”表示f*k?的小數(shù)部分,即f*k%1=f*k-「f*k」[5]?↑

??例10,對下列關鍵字值集合采用隨機乘數(shù)法計算哈希值,隨機數(shù)f=0.103149002?哈希表長度n=100得圖(6):

?

k

f*k

n*((f*k)的小數(shù)部分)

Hash(k)

319426

32948.47311

47.78411

47

718309

74092.85648

86.50448

86

629443

64926.41727

42.14427

42

919697

84865.82769

83.59669

83

??此方法的優(yōu)點是對n的選擇不很關鍵。通常若地址空間為p位就是選n=2p.Knuth對常數(shù)f的取法做了仔細的研究,他認為f取任何值都可以,但某些值效果更好。如f=(-1)/2=0.6180329...比較理想。[8]?↑

9.字符串數(shù)值哈希法

在很都情況下關鍵字是字符串,因此這樣對字符串設計Hash函數(shù)是一個需要討論的問題。下列函數(shù)是取字符串前10個字符來設計的哈希函數(shù)

Int?Hash?_?char?(char?*X)

{

??int?I?,sum?

??i=0;

??while?(i?10?&&?X[i])?

??Sum?+=X[i++];

??sum%=N;??????//N是記錄的條數(shù)

??}

這種函數(shù)把字符串的前10個字符的ASCⅡ值之和對N取摸作為Hash地址,只要N較小,Hash地址將較均勻分布[0,N]區(qū)間內(nèi),因此這個函數(shù)還是可用的。對于N很大的情形,可使用下列函數(shù)

int?ELFhash?(char?*key?)

{

?Unsigned?long?h=0,g;

whie?(*key)

{?

h=(h<<4)+?*key;

key++;

g=h?&?0?xF0000000L;

if?(g)?h^=g>>24;

h?&?=~g;

}

h=h?%?N

return?(h);

}

??這個函數(shù)稱為ELFHash(Exextable?and?Linking?Format?,ELF,可執(zhí)行鏈接格式)函數(shù)。它把一個字符串的絕對長度作為輸入,并通過一種方式把字符的十進制值結合起來,對長字符串和短字符串都有效,這種方式產(chǎn)生的位置不可能不均勻分布。[7]?↑

10.旋轉法

??旋轉法是將數(shù)據(jù)的鍵值中進行旋轉。旋轉法通常并不直接使用在哈希函數(shù)上,而是搭配其他哈希函數(shù)使用。

??例11,某學校同一個系的新生(小于100人)的學號前5位數(shù)是相同的,只有最后2位數(shù)不同,我們將最后一位數(shù),旋轉放置到第一位,其余的往右移。

新生學號

旋轉過程

旋轉后的新鍵值

5062101

5062101

1506210

5062102

5062102

2506210

5062103

5062103

3506210

5062104

5062104

4506210

5062105

5062105

5506210

??????????????????????如圖(7)

?運用這種方法可以只輸入一個數(shù)值從而快速地查到有關學生的信息。[9]?↑

11.偽隨機數(shù)法

偽隨機數(shù)法是將利用數(shù)據(jù)的鍵值經(jīng)過隨機數(shù)法的運算后的結果作為數(shù)據(jù)存儲的位置。其公式如下(a和c為質(zhì)數(shù)):

Y=(a?*?Key?+?c)mod?數(shù)組的大小

例12,某公司的某女員工的編號是321547,現(xiàn)該公司共有107個女職工,我們?nèi)=13,c=5則

Y=(13*321547+5)%107

?=(4180111+5)%107

?=54

則取54當作該員工數(shù)據(jù)存儲的位置。[10]?↑

小?結

有許多種不同的哈希函數(shù)設計方法,這里主要討論幾種常用的不同類型關鍵字的希函數(shù)設計方法:直接定址法、數(shù)字分析法、折疊法、平方取中法、減去法、基數(shù)轉換法、除留余數(shù)法、隨機乘數(shù)法、字符串數(shù)值哈希法、偽隨機數(shù)法、旋轉法。

盡管哈希函數(shù)的構造方法有很多,但不同的方法適用于不同的情況。如:當鍵字是字符串時可以用字符串數(shù)值哈希法構造哈希函數(shù);當關鍵字是整數(shù)類型時就可以用除留余數(shù)法、直接定址法和數(shù)字分析法等設計哈希函數(shù);而關鍵字是小數(shù)類型常用偽隨機數(shù)法來構造哈希函數(shù)等。

?

參?考?文?獻

[1]朱戰(zhàn)立編著.數(shù)據(jù)結構(C++語言描述)?北京:高等教育出版社,2004

[2]陳明編著.實用數(shù)據(jù)結構基礎??北京:清華大學出版社,2002

[3]嚴蔚敏等編著.數(shù)據(jù)結構及應用算法教程??北京:清華大學出版社,2000

[4]殷人昆等編著.數(shù)據(jù)結構:面向對象方法與C++描述??北京:清華大學出版社,1999

[5]熊岳山等編著.數(shù)據(jù)結構:C++語言描述,??長沙:國防科技大學出版社,2002.2

[6]蘇光奎等編著.?數(shù)據(jù)結構導學。??北京:清華大學出版社,2002

[7]陳松喬等編著.算法與數(shù)據(jù)結構(C與C++描述)??北京:北方交通大學出版社??2002.8

[8]卓滋德克著.陳曙暉譯?數(shù)據(jù)結構與算法——C++??北京:清華大學出版社,?2003

[9]王慶瑞編著.數(shù)據(jù)結構教程(C++語言描述)?北京:高等教育出版社,2002.8

[10]黃國瑜等編著.數(shù)據(jù)結構(Java語言版)?北京:清華大學出版社,2002?

?

?

轉自http://wenku.baidu.com/view/61b121c06137ee06eff918c1.html

總結

以上是生活随笔為你收集整理的hash函数的构造方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。