在實際程式設計中,我們常常面臨著兩個問題:儲存和查詢,這兩個過程的效率往往制約著整個程式的效率,而我們常見的儲存資料的資料結構比如線性表,樹,圖等,資料在結構中的位置往往是不明確的,當我們在這些資料結構中要查詢乙個資料,都避免不了去執行查詢演算法,去遍歷資料結構,拿關鍵字和結構中的資料進行一一比較,從而得到想要的資料,我們就希望能不能不通過比較就能獲得我們想要的結果呢?
答案是有的,不通過任何比較,一次儲存便能取得所查記錄,但這就必須在記錄的儲存位置和他的關鍵字之間建立乙個確定的對應關係f,使得每個關鍵字和結構中的唯一的儲存位置相對應,這個關係就是我們所說的雜湊函式f(x),在這個思想上建立起來的表就成為雜湊表。
雜湊表有兩種形式——雜湊集合和雜湊對映。
雜湊集合是用來儲存關鍵字的,而雜湊對映是用來儲存鍵-值對的。
關於雜湊表只要關注兩個操作:
插入。搜尋。
其他操作都可以基於這兩個操作——比如重新從0開始建立hash table,我們可以不斷插入元素。
如果要刪除乙個元素,只要檢索到相應的元素,修改桶的值來達到。
如果我們的hash函式是一對一的,那麼我們就無需擔心衝突的發生。
但大部分情況下我們的hash函式不是一對一的,也就說,是會產生衝突的。
比如y = x % 5;如果我們的x取2或者7,就會發現我們的y都是2。
所以,在面對衝突的時候,我們主要考慮以下兩個問題即可:
相同的元素在同乙個桶中怎麼儲存。(怎麼插入乙個已經存在的元素)
如何在特定的桶中搜尋特定的值。(怎麼搜尋乙個重複的元素)
不使用任何內建的雜湊表庫設計乙個雜湊集合
具體地說,你的設計應該包含以下的功能
示例:
myhashset hashset = new myhashset();我們這篇部落格僅僅是介紹了hash table的乙個基本概念。所以我也打算實現得簡單一點。hashset.add(1);
hashset.add(2);
hashset.contains(1); // 返回 true
hashset.contains(3); // 返回 false (未找到)
hashset.add(2);
hashset.contains(2); // 返回 true
hashset.remove(2);
hashset.contains(2); // 返回 false (已經被刪除)
這裡我們的hash函式選擇y = x。
ac**:
class myhashset
void add(int key)
void remove(int key)
/** returns true if this set contains the specified element */
bool contains(int key)
};/**
* your myhashset object will be instantiated and called as such:
* myhashset* obj = new myhashset();
* obj->add(key);
* obj->remove(key);
* bool param_3 = obj->contains(key);
*/
雜湊表 雜湊集合(bitmap)
之前我們提到了雜湊集合的樸素實現。你要知道雜湊表的乙個重要思想就是使用空間換時間。他引入了乙個用作桶的陣列。所以我們可以通過o 1 的時間 雜湊函式進行插入和檢索。不過這種做法空間的浪費太嚴重了,注意到我們c 中使用hash來實現的set,是不能儲存重複元素的。在這種背景下,我們使用乙個int的空間...
雜湊表(雜湊表)的實現
雜湊函式直接用key size的形式,size為雜湊表的大小。衝突處理採用平方探測法,為保證可以探測到整個雜湊表空間,雜湊表大小設定為4k 3形式的素數。當雜湊表中的元素過多時會造成效能下降,這時應該倍增雜湊表的大小,重新計算原來雜湊表中每個元素在新的雜湊表中的位置。雜湊表的實現 hashtable...
雜湊表(雜湊表) C 實現
雜湊函式就是 關鍵字key 到 值value 的對映 value f key value反映的是關鍵字key的儲存位址。直接定址法 f key a key b 例如存放不同出生年份的人口數量,出生年份是關鍵字,那麼可以用直接定址法。直接定址法的優點是簡單均勻,也不會產生衝突 缺點是該方法適合表比較小...