散列表又稱哈希表,查找只需要花費常數時間,查找效率極高,對龐大數據的查找很有作用。
散列表解決沖突的方式有多種,這里采用了分離鏈接法,除此外還有開放地址法和雙散列。
Vocabulary類是用來儲存單詞的類,用於實現一個離線詞典的數據方案,當然這並不是最高效的方法,但是我認為是比較容易理解的方法,對於初學哈希表的人來說還是比較容易接受的。
1 /************************************************************************/ 2 /* 文件說明: 3 /* 采用分離鏈接法實現哈希表,采用C++標准庫中的vector和list實現 4 /* 5 /************************************************************************/ 6 #include <vector> 7 #include <list> 8 #include <string> 9 10 class Vocabulary; 11 12 int hash(const std::string & key, const int &tableSize); 13 int hash(const int & key, const int &tableSize); 14 //int hash(const Vocabulary & e, const int &tableSize); 15 16 namespace stl 17 { 18 19 template <typename HashedObj> 20 class HashTable 21 { 22 public: 23 //typedef vector<std::list<HashedObj> >::size_type SIZE; 24 25 HashTable(int size = 101); //初始化哈希表的大小 26 ~HashTable(){} 27 bool contains(const HashedObj & obj); 28 bool insert(const HashedObj & obj); 29 bool remove(const HashedObj & obj); 30 private: 31 32 std::vector<std::list<HashedObj> > theList; //哈希表 33 int myhash(const HashedObj & obj) const; //哈希函數 34 }; 35 36 37 //函數定義 38 template <typename HashedObj> 39 HashTable<HashedObj>::HashTable(int size /*= 101*/) 40 { 41 /*根據哈希表的大小分配vector的空間*/ 42 theList.reserve(size); 43 theList.resize(size); 44 } 45 46 template <typename HashedObj> 47 int HashTable<HashedObj>::myhash(const HashedObj & obj) const 48 { 49 //根據object不同調用不同版本的hash重載函數 50 return hash(obj, theList.size()); 51 } 52 53 /************************************************************************/ 54 /* 函數名稱:contains 55 /* 函數功能:查找指定對象是否在哈希表中 56 /* 返回值:存在返回true,不存在返回false 57 /************************************************************************/ 58 template <typename HashedObj> 59 bool HashTable<HashedObj>::contains(const HashedObj & obj) 60 { 61 int iHashValue = myhash(obj); 62 const std::list<HashedObj> & tempList = theList[iHashValue]; 63 64 std::list<HashedObj>::const_iterator it = tempList.cbegin(); 65 66 for (; it != tempList.cend() && *it != obj; ++it); 67 68 if(it != tempList.cend()) 69 return true; 70 else 71 return false; 72 } 73 74 /************************************************************************/ 75 /* 函數名稱:insert 76 /* 函數功能:向hash表中插入元素,如果元素已經存在則返回false,不存在則在鏈表的最前面插入 77 /* 返回值:成功返回true,失敗返回返回false 78 /************************************************************************/ 79 template <typename HashedObj> 80 bool HashTable<HashedObj>::insert(const HashedObj & obj) 81 { 82 int iHashValue = myhash(obj); 83 84 std::list<HashedObj> & tempList = theList[iHashValue]; 85 if (contains(obj)) 86 { 87 return false; //已經存在返回false 88 } 89 90 tempList.push_back(obj); 91 return true; 92 } 93 94 /************************************************************************/ 95 /* 函數名稱:remove 96 /* 函數功能:從哈希表中刪除指定元素,如果元素不存在則返回false 97 /* 返回值:成功返回true,失敗返回返回false 98 /************************************************************************/ 99 template <typename HashedObj> 100 bool HashTable<HashedObj>::remove(const HashedObj & obj) 101 { 102 list<HashedObj> & tempList = theList[myhash(obj)]; 103 auto it = find(tempList.begin(), tempList.end(), obj); 104 if (it == tempList.end()) 105 { 106 return false; 107 } 108 tempList.erase(it); 109 return true; 110 } 111 } 112 113 114 //hash表中存入單詞表類,一個對象表示對應一個單詞 115 class Vocabulary 116 { 117 public: 118 Vocabulary(){ } 119 120 ~Vocabulary(){ } 121 122 void SetWordName(std::string name) 123 { 124 m_sWord = name; 125 } 126 127 void SetWordExplain(std::string explain) 128 { 129 m_sExplain = explain; 130 } 131 132 const std::string getName() const 133 { 134 return m_sWord; 135 } 136 137 Vocabulary(const Vocabulary &vc){ 138 139 } 140 141 Vocabulary& operator= (const Vocabulary & v) 142 { 143 m_sWord = v.m_sWord; 144 m_sExplain = v.m_sExplain; 145 return *this; 146 } 147 148 149 150 151 private: 152 std::string m_sWord; 153 std::string m_sExplain; 154 }; 155 156 bool operator== (const Vocabulary & word1, const Vocabulary & word2) 157 { 158 if (word1.getName() == word2.getName()) 159 { 160 return true; 161 } 162 else 163 { 164 return false; 165 } 166 } 167 168 bool operator!= (const Vocabulary & word1, const Vocabulary & word2) 169 { 170 return !(word1 == word2); 171 } 172 173 int hash(const Vocabulary & e,const int &tableSize) 174 { 175 return hash(e.getName(), tableSize); 176 } 177 178 int hash(const std::string & key, const int &tableSize) 179 { 180 //采用公式:h = (k1*32 + k2) * 32 + k3,將其擴展到n次多項式 181 long long int hashVal = 0; 182 int count = 0; 183 for (auto it = key.begin(); it != key.end(); ++it) 184 { 185 if (count++ % 2 == 0) 186 { 187 hashVal += (hashVal << 5) + *it; 188 } 189 190 } 191 return hashVal %= tableSize; 192 } 193 194 int hash(const int & key, const int &tableSize) 195 { 196 return key % tableSize; 197 }