哈希表(HashTable)筆記

深入底層學習php,肯定少不了hash表的學些,於是參考維基百科,做了以下筆記,並且實踐上用c語言實現了其中一種hash表;


一. HashTable在PHP中的地位

首先要知道,php中的變量存儲是通過zval這個結構體來實現的,而zval的查找尋址是通過php啓動內核裏面的HashTable來實現的。
除此之外,一個HashTable有很多元素,在php內核裏叫做bucket。然而每個bucket的大小是固定的, 所以如果我們想在bucket裏存儲任意數據時,最好的辦法便是申請一塊內存保存數據, 然後在bucket裏保存它的指針。

由此可見,hashtable可以說在php中的地位很關鍵。


二. Hashtable的概念

hashtable中文名是哈希表,是根據鍵(Key)而直接訪問在內存存儲位置的數據結構。

從定義上可以看出關鍵點有兩個:
(1)需要有key和存儲位置的映射關係,稱作散列函數*hash(key)【若均勻分佈,則稱爲均勻散列函數*】,計算值稱爲散列地址;
(2)需要處理不同key產出相同hash(key)的case,稱爲處理衝突


三. 常見構造散列函數的方法

(1)直接地址法:hash(k)=k或 hash(k)=a k+b 其中a,b爲常數(這種散列函數叫做自身函數);
(2)數字分析法
(3)平方取中法:取關鍵字平方後的中間幾位爲哈希地址【因爲平方後中間幾位和關鍵字的大部分位都有關係】。
(4)摺疊法: 講關鍵字按指定位數摺疊,然後捨去相對於最大地址的高位(哈希表的地址最大值取餘數),再得出地址;
(5)隨機數法
(6)除留餘數法:取關鍵字被某個不大於散列表表長m的數p除後所得的餘數爲散列地址。


四. 常見的處理衝突的方法

(1)開放定址法
散列函數: hash(k) = (hash0(k) + d) mod m
當不同的k衝突時,就通過以下方式改變d來尋找新的可用的地址,
A. 線性探測:d = 1,2 , 3….. m
B. 平方探測:d = 1^2, 2^2 …k^2 (k<=m/2)
C. 僞隨隨機探測:d=預先設定的僞隨機數

(2)單獨鏈表法: 就是當不同key得出相同hash(k)時,就在當前hash(k)下建立鏈表存儲鍵值;
(3)雙散列法:相對於開放地址法,就是在插入鍵值和查詢鍵值時使用兩套散列函數;
(4)再散列法:hash(k)=hash(hash(k));


五. 實踐時使用的hashtable-c語言版例子

(1)使用“摺疊法”構造散列函數
(2)使用“單獨鏈表法”處理衝突
例程見如下資源:

http://download.csdn.net/detail/gavin_new/9755014

使用:
linux環境下,解壓後,敲入命令:
(1)make clean && make
(3)./target

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