上一篇博客我們實現(xiàn)了key形式的線性探測法處理哈希沖突,有了前面的基礎,我們就可以實現(xiàn)更加有難度的key/value形式的二次探測。
鲅魚圈網站建設公司創(chuàng)新互聯(lián),鲅魚圈網站設計制作,有大型網站制作公司豐富經驗。已為鲅魚圈1000多家提供企業(yè)網站建設服務。企業(yè)網站搭建\外貿網站制作要多少錢,請找那個售后服務好的鲅魚圈做網站的公司定做!什么是key/value形式呢?
在這里我們的目標是實現(xiàn)一個英漢字典,一個英語字符串就是key,對應的有一個漢語翻譯value,通過key我們可以找到value。所以在這里key和value是“綁”在一起的,我們就用一個結構體來聚合起來:
templatestruct Key_Value { K _key; V _value; Key_Value(const K& key=K(), const V& value=V()) :_key(key) , _value(value) {} };
key_value的構造函數中的形參key和value都有一個默認值,默認值是一個臨時對象。
還是同樣的方法,我們用哈希表來實現(xiàn)字典,哈希表的查找效率真的太誘人?。?/p>
字典的結構如下:
#pragma once #include#include using namespace std; enum State { EXIST, EMPTY, DELETE }; template struct DefaultFunc { size_t operator()(const T& data) { return (size_t)data; } }; struct StringFunc { size_t operator()(const string& str) { size_t sum = 0; for (size_t i = 0; i < str.size(); ++i) { sum += str[i]; } return sum; } }; template > class Dictionary { typedef Key_Value KV; public: Dictionary(); //~Dictionary(); Dictionary(size_t size);//初始化字典的大小 bool Add(const K& key, const V& value); bool Delete(const K& key); size_t Find(const K& key); bool Alter(const K& key,const K& newkey,const V& newvalue); void Print(); protected: size_t HashFunc(const K& key);//哈希函數 void Swap(Dictionary & d); protected: KV* _table; State* _state; size_t _size; size_t _capacity; FuncModel _HF; };
對于一個英漢字典我們要實現(xiàn)的是它的增刪改查功能
(一)添加條目:
template> bool Dictionary ::Add(const K& key, const V& value) { if (_size * 10 >= _capacity * 8)//載荷因子超過0.8,增容 { Dictionary tmp(_capacity * 2 + 1); for (size_t i = 0; i < _capacity; ++i) { if (_state[i] == EXIST) { KV node(_table[i]._key, _table[i]._value); size_t adress = HashFunc(_table[i]._key); size_t index = adress; size_t flag = 0; while (tmp._state[index] == EXIST) { index = adress + flag*flag; while (index >= _capacity)//如果到了散列表的末尾,要返回表的頭 { index -= _capacity; } flag++; } tmp._table[index] = node; tmp._size++; tmp._state[index] = EXIST; } } Swap(tmp);//this和tmp交換內容 } size_t adress = HashFunc(key); size_t index = adress;//adress是不能變的,用index來標記最后的位置 size_t flag = 0; while (_state[index] == EXIST)//二次探測 { index = adress + flag*flag; while(index >= _capacity)//如果到了散列表的末尾,要返回表的頭 { index -= _capacity; } flag++; } KV tmp(key, value); _table[index] = tmp; _state[index] = EXIST; _size++; return true; }
(二)查找條目:
template> size_t Dictionary ::Find(const K& key) { size_t adress = HashFunc(key); size_t index = adress; for (size_t flag = 0; flag < _capacity;) { if (_table[index]._key == key)//二次探測 { return index; } index = adress + flag*flag; while (index >= _capacity) { index -= _capacity; } flag++; } return -1; }
在查找的時候flag不僅用來控制查找的次數,還可以控制二次探測的增量(i^2,i++)。最多查找_capacity次就可以了。找了_capacity次還沒找到就說明不存在。
(三)刪除條目:
調用查找條目,若找到則刪除,否則返回flase.
template> bool Dictionary ::Delete(const K& key) { size_t index = Find(key); if (index >= 0) { _state[index] = DELETE; _size--; return true; } return false; }
(四)修改條目:
調用查找條目,若找到則修改,否則返回flase.
emplate> bool Dictionary :: Alter(const K& key,const K& newkey,const V& newvalue) { size_t index = Find(key); if (index > 0) { _table[index]._key = newkey; _table[index]._value = newvalue; return true; } return false; }
另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。