Hash表的實現原理
雜湊表存在的意義
雜湊表最重要的意義就是快速定位查詢,類比來講就是將Hash表就是將程式中毫無規律的資料項組合成了“新華字典”,根據“雜湊表”可以快速找到字典中的每一個字。
雜湊表(散列表)快速定位所需要的手段
雜湊表目的就是為了使資料均勻分佈同時保證計算簡單,花費在計算地址上的時間要遠小於遍歷的時間。
兩種雜湊函式
1直接定址法
在雜湊之前要知道所有的關鍵值,且資料之間對應的經過雜湊函式之後得到的值不能有衝突。(異想天開:只適用於小的資料分佈)
這樣的雜湊函式優點就是簡單、均勻,也不會產生衝突,但問題是這需要事先知道關鍵字的分佈情況,適合査找表較小且連續的情況。由於這樣的限制,在現實應用中,直接定址法雖然簡單,但卻並不常用。
2除留餘數法
根據關鍵值得取值範圍去一個在其範圍內最大的質數,這樣可以更均勻的雜湊資料,同時也能減少衝突。(這種方法比較常用)
兩種衝突處理的方法
1.開放定址法(線性探測):
公式為:
fi(key) = (f(key)+di) MOD m (di=1,2,3,......,m-1)
基本上屬於順序查詢還有的空下來的位置
根據di的變化有兩種不同的探測方法:
二次探測法:雙向查詢
隨機探測發:隨機分配,但是這時是偽隨機,在查詢時和插入用的是同一個隨機數
如果發生衝突,這個位置資料項的指標指向下一個資料項的位置。也就是說同義詞在一個鏈內。
2.拉鍊法
拉鍊法解決衝突的做法是:將所有關鍵字為同義詞的結點連結在同一個單鏈表中。若選定的散列表長度為m,則可將散列表定義為一個由m個頭指標組成的指標陣列T[0..m-1]。凡是雜湊地址為i的結點,均插入到以T[i]為頭指標的單鏈表中。T中各分量的初值均應為空指標。在拉鍊法中,裝填因子α可以大於 1,但一般均取α≤1。
拉鍊法的優勢與缺點
與開放定址法相比,拉鍊法有如下幾個優點:
拉鍊法處理衝突簡單,且無堆積現象,即非同義詞決不會發生衝突,因此平均查詢長度較短; 由於拉鍊法中各連結串列上的結點空間是動態申請的,故它更適合於造表前無法確定表長的情況; 開放定址法為減少衝突,要求裝填因子α較小,故當結點規模較大時會浪費很多空間。而拉鍊法中可取α≥1,且結點較大時,拉鍊法中增加的指標域可忽略不計,因此節省空間; 在用拉鍊法構造的散列表中,刪除結點的操作易於實現。只要簡單地刪去連結串列上相應的結點即可。而對開放地址法構造的散列表,刪除結點不能簡單地將被刪結 點的空間置為空,否則將截斷在它之後填人散列表的同義詞結點的查詢路徑。這是因為各種開放地址法中,空地址單元(即開放地址)都是查詢失敗的條件。因此在用開放地址法處理衝突的散列表上執行刪除操作,只能在被刪結點上做刪除標記,而不能真正刪除結點。
拉鍊法的缺點:指標需要額外的空間,故當結點規模較小時,開放定址法較為節省空間,而若將節省的指標空間用來擴大散列表的規模,可使裝填因子變小,這又減少了開放定址法中的衝突,從而提高平均查詢速度。