搜尋
首頁後端開發PHP問題什麼是資料結構Hash表(哈希表)?又有哪些具體操作呢?

一、什麼是Hash表

要想知道什麼是雜湊表,那就要先了解雜湊函數

雜湊函數:

比較先前部落格討論的二元排序樹二叉平衡樹紅黑樹B B 樹,它們的查找都是先從根節點進行查找,從節點取出資料或索引與查找值進行比較。那麼,有沒有一種函數H,根據這個函數和找出關鍵字key,可以直接決定查找值所在位置,而不需要一個個比較。這樣就**「預先知道」**key所在的位置,直接找到數據,提升效率。

即位址index=H(key) 

說穿了,hash函數就是根據key計算出應該儲存位址的位置,而雜湊表是基於雜湊函數建立的一種查找表

、雜湊函數的建構方法

根據前人經驗,統計如下幾種常用hash函數的建構方法: 

直接定製法 

雜湊函數為關鍵字的線性函數如H(key)=a* key b 

這種建構方法比較簡便,均勻,但有很大限制,僅限於位址大小=關鍵字集合的情況 

使用舉例: 

假設需要統計中國人口的年齡分佈,以10為最小單元。今年是2018年,那麼10歲以內的分佈在2008-2018,20歲以內的分佈在1998-2008…假設2018代表2018-2008直接的數據,那麼關鍵字應該是2018,2008,1998… 

那麼可以建構雜湊函數H(key)=(2018-key)/10=201-key/10 

那麼hash表建立如下

index key 年齡 人數(假設資料)

0 2018 0-10 200W

1 2008 10-20 250W

2 1998 20-30 253W

3 1988 30- 40 300W

……

數字分析法 
假設關鍵字集合中的每個關鍵字key都是由s位元數字組成(k1,k2 ,……,knk1,k2,……,kn),分析key中的全體數據,並從中提取分佈均勻的若干位或他們的組合構成全體

使用舉例 

#我們知道身分證號是有規律的,現在我們要儲存一個班級學生的身分證號碼,假設這個班級的學生都出生在同一個地區,同一年,那麼他們的身分證的前面數位都是相同的,那麼我們可以截取後面不同的幾位存儲,假設有5位元不同,那麼就用這五位來代表地址。

H(key)=key 0000 

此種方法通常用於數字位數較長的情況,必須數字存在一定規律,其必須知道數字的分佈情況,如上面的例子,我們事先知道這個班級的學生出生在同一年,同一個地區。

平方取中法 

如果關鍵字的每一位都有某些數字重複出現頻率很高的現象,可以先求關鍵字的平方值,透過平方擴大差異,而後取中間數字位元作為最終儲存位址。

使用範例 

例如key=1234 1234^2=1522756 取227作hash位址 

例如key=4321 4321^2=18671041 取671作#hash 

#這個方法適合事先不知道資料且資料長度較小的情況 

摺疊法 如果數字的位數很多,可以將數字分割為幾個部分,取他們的疊加和作為hash位址 
使用舉例 
例如key=123 456 789 
我們可以儲存在61524,取末三位,存在524的位置 
該方法適用於數字位數較多且事先不知道資料分佈的情況 

除留餘數法用的較多 

H(key)=key MOD p (p很明顯,如何選取p是個關鍵問題。

使用範例 

例如我們儲存3 6 9,那麼p就不能取3 

因為3 MOD 3 == 6 MOD 3 == 9 MOD 3 

#p應為不大於m的質數或是不含20以下的質因子的合數,這樣可以減少位址的重複(衝突)

例如key = 7,39,18,24, 33,21時取表長m為9 p為7 那麼儲存如下

什麼是資料結構Hash表(哈希表)?又有哪些具體操作呢?

#隨機數法 H(key) =Random( key) 
取關鍵字的隨機函數值為它的雜湊位址

hash函數設計的考慮因素

1.計算雜湊位址所需的時間(即hash函數本身不要太複雜) 
2.關鍵字的長度 
3.表長 
4.關鍵字分佈是否均勻,是否有規律可循 
5.設計的hash函數在滿足以上條件的情況下盡量減少衝突

三、哈希衝突

即不同key值產生相同的位址,H(key1)=H(key2) 
例如我們上面所說的儲存3 6 9,p取3是 
3 MOD 3 == 6 MOD 3 == 9 MOD 3 
此時3 6 9都發生了hash衝突

哈希衝突的解決方案

#不管hash函數設計的如何巧妙,總會有特殊的key導致hash衝突,特別是對動態查找表來說。

hash函數解決衝突的方法有以下常用的方法 

1.開放客製化法 

2.鏈結位址法

3.公共溢出區法 

建立一個特殊儲存空間,專門存放衝突的資料。此種方法適用於數據和衝突較少的情況。

4.再散列法 

準備若干hash函數,如果使用第一個hash函數發生了衝突,就使用第二個hash函數,第二個也衝突,使用第三個… 

重點了解開放客製化法和鏈結位址法

開放客製化法

首先有一個H(key)的雜湊函數 

如果H(key1)=H(keyi) 

那麼keyi儲存位置Hi=(H(key) di)MODmHi=(H(key) di)MODmm為表長 

什麼是資料結構Hash表(哈希表)?又有哪些具體操作呢?

注意 

增量di應該具有以下特點(完整性):產生的Hi(位址)均不相同,且所產生的s (m-1)個Hi能覆蓋hash表中的所有位址 

* 平方偵測時表長m必須為4j 3的質數(平方偵測表長有限制) 

#* 隨機探測時m和di沒有公因子(隨機探測di有限制)

三種開放尋址法解決衝突方案的例子

有一組資料 

19 01 23 14 55 68 11 86 37要儲存在表長11的陣列中,其中H(key)=key MOD 11 

那麼依照上面三種解決衝突的方法,儲存程序如下:

(表格解釋:從前向後插入數據,如果插入位置已經佔用,發生衝突,衝突的另起一行,計算地址,直到地址可用,後面衝突的繼續向下另起一行。最終結果取最上面的資料(因為是最「佔座」的資料)) 

線性探測再散列 

我們取di=1,即衝突後存儲在衝突後一個位置,如果仍然衝突繼續向後

什麼是資料結構Hash表(哈希表)?又有哪些具體操作呢?

平方探測再散列

什麼是資料結構Hash表(哈希表)?又有哪些具體操作呢?

#在雜湊(雙探測再散列) 
#發生衝突後 
H(key)'=(H(key) di)MOD m 
在此範例中 
H(key)=key MOD 11 
我們取di=key MOD 10 1 
則有以下結果:

什麼是資料結構Hash表(哈希表)?又有哪些具體操作呢?

#

鏈結位址法

產生hash衝突後在儲存資料後面加上指針,指向後面衝突的資料 
上面的例子,用鏈結位址法則是下面這樣:

什麼是資料結構Hash表(哈希表)?又有哪些具體操作呢?

四、hash表的查找

找出過程和造表過程一致,假設採用開放定址法處理衝突,則尋找過程為: 

對於給定的key,計算hash位址index = H(key) 

如果陣列arr【index】的值為空則尋找不成功 

#如果陣列arr【index】== key 則找出成功 

否則使用衝突解決方法求下一個位址,直到arr【index】== key或arr【index】==null

什麼是資料結構Hash表(哈希表)?又有哪些具體操作呢?

可以看到無論哪個函數,裝載因子越大,平均查找長度越大,那麼裝載因子α越小越好?也不是,就像100的表長只存一個數據,α是小了,但是空間利用率不高啊,這裡就是時間空間的取捨問題了。通常情況下,認為α=0.75是時間空間綜合利用效率最高的情況。

上面的這個表可是特別有用的。假設我現在有10個數據,想用鏈結位址法解決衝突,並要求平均找出長度

那麼有1 α/2

α

即n/m

m>10/2 

m>5 即採用鏈結位址法,使得平均找出長度

之前我的部落格討論過各種樹的平均查找長度,他們都是基於存儲數據n的函數,而hash表不同,他是基於裝載因子的函數,也就是說,當當資料n增加時,我可以透過增加表長m,以維持裝載因子不變,確保ASL不變。

那麼hash表的建構應該是這樣的:

什麼是資料結構Hash表(哈希表)?又有哪些具體操作呢?

#五、hash表的刪除

首先鏈位址法是可以直接刪除元素的,但是開放定址法是不行的,拿前面的雙探測再散列來說,假如我們刪除了元素1,將其位置置空,那23就永遠找不到了。正確做法應該是刪除之後置入一個原來不存在的數據,例如-1。

更多相關問題請上PHP中文網:PHP實戰影片教學

#

以上是什麼是資料結構Hash表(哈希表)?又有哪些具體操作呢?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:CSDN。如有侵權,請聯絡admin@php.cn刪除
酸與基本數據庫:差異和何時使用。酸與基本數據庫:差異和何時使用。Mar 26, 2025 pm 04:19 PM

本文比較了酸和基本數據庫模型,詳細介紹了它們的特徵和適當的用例。酸優先確定數據完整性和一致性,適合財務和電子商務應用程序,而基礎則側重於可用性和

PHP安全文件上傳:防止與文件相關的漏洞。PHP安全文件上傳:防止與文件相關的漏洞。Mar 26, 2025 pm 04:18 PM

本文討論了確保PHP文件上傳的確保,以防止諸如代碼注入之類的漏洞。它專注於文件類型驗證,安全存儲和錯誤處理以增強應用程序安全性。

PHP輸入驗證:最佳實踐。PHP輸入驗證:最佳實踐。Mar 26, 2025 pm 04:17 PM

文章討論了PHP輸入驗證以增強安全性的最佳實踐,重點是使用內置功能,白名單方法和服務器端驗證等技術。

PHP API率限制:實施策略。PHP API率限制:實施策略。Mar 26, 2025 pm 04:16 PM

本文討論了在PHP中實施API速率限制的策略,包括諸如令牌桶和漏水桶等算法,以及使用Symfony/Rate-limimiter之類的庫。它還涵蓋監視,動態調整速率限制和手

php密碼哈希:password_hash和password_verify。php密碼哈希:password_hash和password_verify。Mar 26, 2025 pm 04:15 PM

本文討論了使用password_hash和pyspasswify在PHP中使用密碼的好處。主要論點是,這些功能通過自動鹽,強大的哈希算法和SECH來增強密碼保護

OWASP前10 php:描述並減輕常見漏洞。OWASP前10 php:描述並減輕常見漏洞。Mar 26, 2025 pm 04:13 PM

本文討論了OWASP在PHP和緩解策略中的十大漏洞。關鍵問題包括注射,驗證損壞和XSS,並提供用於監視和保護PHP應用程序的推薦工具。

PHP XSS預防:如何預防XSS。PHP XSS預防:如何預防XSS。Mar 26, 2025 pm 04:12 PM

本文討論了防止PHP中XSS攻擊的策略,專注於輸入消毒,輸出編碼以及使用安全增強的庫和框架。

PHP接口與抽像類:何時使用。PHP接口與抽像類:何時使用。Mar 26, 2025 pm 04:11 PM

本文討論了PHP中接口和抽像類的使用,重點是何時使用。界面定義了無實施的合同,適用於無關類和多重繼承。摘要類提供常見功能

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),