簡單哈希表(散列表)的理解

散列表

在線性表、樹等數據結構中,記錄在結構中的相對位置是隨機的,和記錄的關鍵字之間不存在確定的關係,因此在結構中查找記錄時需進行一系列和關鍵字的比較。它們查找的效率都依賴於查找過程中所進行的比較次數。

1、散列表的強大

即使是二分查找,查找的時間複雜度也是 O(log2N)。
但是——散列表,理想的情況下有沒有不經過任何比較,一次存取便能得到所查記錄。時間複雜度是 O(1)。

2、散列表的實現

1、使用散列函數將給定鍵轉化爲一個“數組的索引”,數組內可以存儲記錄對應的值,這個函數,我們稱之爲散列(哈希)函數;
2、但對於不同的關鍵字,可能得到同一哈希地址,即k1≠ k2,而f(k1) = f(k2),這種現象我們稱之爲衝突。衝突只能儘可能的少,但是不能完全避免;

2.1 散列函數描述

哈希表的容量一般設置爲素數,因爲無論按照何種步長,總可以遍歷素數。

2.1.1 散列函數特徵

1、相同輸入映射到相同索引;
2、不同輸入映射到不同索引;
3、散列表知道數組多大,只返回有效索引

構造方法:

直接定址法:

					Hash(key) = a × key + b

數字分析法:

			比如手機號前三位是接入號,中間四位是 HLR 識別號,只有後四位纔是真正的用戶號,此時我們選擇後四位作爲散列地址就是不錯的選擇;
			數字分析法通常適合處理關鍵字位數比較大的情況,如果事先知道關鍵字的分佈且關鍵字的若干位分佈較均勻,就可以考慮用這個方法。

平方取中法:

			如果事先知道關鍵字的分佈且關鍵字的若干位分佈較均勻,就可以考慮用這個方法
			平方取中法比較適合於不知道關鍵字的分佈,而位數又不是很大的情況

摺疊法:

			1、將關鍵字從左到右分割成位數相等的幾部分(注意最後一部分位數不夠時可以短些)
			2、然後將這幾部分疊加求和
			3、按散列表表長,取後幾位作爲散列地址

除留餘數法

					Hash(key) = key / a ... b  ,b即爲數組地址

隨機數法

2.2衝突處理

2.2.1 拉鍊法

如果多個鍵映射到了同一位置,就在這個位置存儲一個鏈表。

2.2.2 開放地址法

數據項具有相同下標時,在數組中其他地方尋找一個空白單元放置要插入的數據項。

2.2.2.2 線性探測:

在用除留餘數法時:Hi = (Hash(key) + di) mod m           di爲增量序列
線性探測中di每次衝突都加1,知道找到空序列;
刪除操作:刪除操作複雜,這裏不進行討論
查找操作
在這裏插入圖片描述
線性探測是逐步搜索空的位置。缺點:數據項聚集,越來越大,越後面找到空位插入數據項需要時間越多。

2.2.2.3 二次探測法:

Hi = (Hash(key) + di) mod m           di爲增量序列
di先後取(±1)2 ,(±2)2,(±3)……

2.2.2.4 僞隨機探測法:

di爲僞隨機數

2.2.3 再散列法(雙散列函數)
2.2.4 建立公共溢出區

3、應用

3.1 DNS解析

如:在訪問像http://adit.io這樣的網站時,計算機必須將adit.io轉換爲IP地址:

					ADIT.IO -> 173.255.248.55

無論哪個網站,網址都要轉化爲IP地址:

					GOOGLE.COM  ->  74.125.239.133
					FACEBOOK.COM -> 173.252.120.6

這是將網址映射到IP地址,這過程被成爲DNS解析,散列表是提供這種功能方式之一。

3.2 緩存內放入散列表加快訪問速度

3.3 總結:

散列函數在查找、加密、海量數據處理過程都有強大優勢;
如果在能提前預測數據量的大小。那麼哈希表在速度和易用性方面——無與倫比!!!
缺點:數組創建後難於擴展,某些哈希表被基本填滿時,性能下降得非常嚴重

鏈接: 開放地址法描述.

鏈接: 開放地址法哈希表代碼篇.

鏈接: 散列函數描述.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章