哈希桶:建一个存放指针的数组,将hash出的key跟数组的下标进行对应,将对应的数据链接到该位置。


eg:要存11 22 24 34 54 36 

利用模除算出位置:

11%10=1

21%10=1

24%10=4

34%10=4

54%10=4

36%10=6

wKioL1c5rivy7e7LAAAhjR4sqRA327.png

  1. 代码实现:
  2. #define  _CRT_SECURE_NO_WARNINGS
  3. #include<iostream>
  4. using namespace std;
  5. #include<string>
  6. #include<vector>
  7. template<class K,class V>
  8. struct KeyValue
  9. {
  10. K _key;
  11. V _value;
  12. KeyValue<K, V>* _next;
  13. KeyValue(const K& key, const V& value)
  14. :_key(key),
  15. _value(value),
  16. _next(NULL)
  17. {}
  18. };
  19. template<class K>
  20. struct HashFuncDefault
  21. {
  22. size_t operator()(const K& key)
  23. {
  24. return key;
  25. }
  26. };
  27. static size_t BKDRHash(const char * str)
  28. {
  29. unsigned int seed = 131// 31 131 1313 13131 131313
  30. unsigned int hash = 0;
  31. while (*str)
  32. {
  33. hash = hash * seed + (*str++);
  34. }
  35. return (hash & 0x7FFFFFFF);
  36. }
  37. template<>
  38. struct HashFuncDefault<string>
  39. {
  40. size_t operator()(const string& key)
  41. {
  42. return BKDRHash(key.c_str());
  43. }
  44. };
  45. template<class Kclass Vclass HF = HashFuncDefault<K>>
  46. class HashBucket
  47. {
  48. typedef KeyValue<K, V> KV;
  49. public:
  50. HashBucket()
  51. :_size(0)
  52. {}
  53. bool Insert(const K& key, const V& value)
  54. {
  55. _CheckCapacity();
  56. size_t index = HashFunc(key, _table.size());
  57. KV* cur = _table[index];
  58. while (cur)
  59. {
  60. if (cur->_key != key)
  61. {
  62. cur = cur->_next;
  63. }
  64. else
  65. {
  66. return false;
  67. }
  68. }
  69. KeyValue<K, V>* tem = new KeyValue<K, V>(key, value);   //用头插法插入节点
  70. tem->_next = _table[index];
  71. _table[index] = tem;
  72. _size++;
  73. return true;
  74. }
  75. size_t HashFunc(const K& key, size_t capacity)
  76. {
  77. HF hashFunc;
  78.  return hashFunc(key) % capacity;
  79. }
  80. KV* Find(const K& key)
  81. {
  82. size_t index = HashFunc(key, _table.size());
  83. KV* cur = _table[index];
  84. while (cur)
  85. {
  86. if (cur->_key == key)
  87. {
  88. return cur;
  89. }
  90. cur = cur->_next;
  91. }
  92. return NULL;
  93. }
  94. void Print()
  95. {
  96. size_t size = _table.size();
  97. for (size_t i = 0; i < size; i++)
  98. {
  99. if (_table[i])
  100. {
  101. KV* cur = _table[i];
  102. while (cur)
  103. {
  104. cout << "key:" << cur->_key << " value:" << cur->_value << " -> ";
  105. cur = cur->_next;
  106. }
  107. cout << "NULL";
  108. cout << endl;
  109. }
  110. }
  111. }
  112. void Remove(const K& key)
  113. {
  114. size_t index = HashFunc(key, _table.size());
  115. KV* cur = _table[index];
  116. if (cur == NULL)
  117. {
  118. return;
  119. }
  120. if (cur->_key == key)
  121. {
  122. _table[index] = cur->_next;
  123. }
  124. KV* prev = cur;
  125. while (cur->_next)
  126. {
  127. cur = cur->_next;
  128. if (cur->_key == key)
  129. {
  130. prev->_next = cur->_next;
  131. delete cur;
  132. cur = NULL;
  133. _size--;
  134. return;
  135. }
  136. prev = cur;
  137. }
  138. }
  139. ~HashBucket()
  140. {
  141. size_t size = _table.size();
  142. for (size_t i = 0; i < size; i++)
  143. {
  144. if (_table[i])
  145. {
  146. KV* cur = _table[i];
  147. while (cur)
  148. {
  149. KV* del = cur;
  150. cur = cur->_next;
  151. delete del;
  152. }
  153. }
  154. }
  155. }
  156. protected:
  157. void _CheckCapacity()
  158. {
  159. size_t newCapacity = 0;
  160. if (_table.size() == _size)
  161. {
  162. newCapacity = _GetSize(_size);
  163. vector<KV*> tmp;
  164. tmp.resize(newCapacity);
  165. for (size_t i = 0; i < _size; i++)
  166. {
  167. KV* cur = _table[i];
  168. while (cur)
  169. {
  170. KeyValue<K, V>* move = cur;
  171. cur = cur->_next;
  172. size_t index = HashFunc(move->_key, tmp.size());
  173. move->_next = tmp[index];            //用头插法更方便
  174. tmp[index] = move;
  175. }
  176. }
  177. _table.swap(tmp);
  178. }
  179. }
  180. size_t _GetSize(const size_t size)
  181. {
  182. const int _PrimeSize = 28;
  183. static const unsigned long _PrimeList[_PrimeSize] =
  184. {
  185. 53ul97ul193ul389ul769ul,
  186. 1543ul3079ul6151ul12289ul24593ul,
  187. 49157ul98317ul196613ul393241ul786433ul,
  188. 1572869ul3145739ul6291469ul12582917ul25165843ul,
  189. 50331653ul100663319ul201326611ul402653189ul805306457ul,
  190. 1610612741ul3221225473ul4294967291ul
  191. };
  192. size_t i = 0;
  193. for (; i < _PrimeSize; i++)
  194. {
  195. if (_PrimeList[i] <= size && i != _PrimeSize - 1)
  196. {
  197. i++;
  198. }
  199. else
  200. {
  201. break;
  202. }
  203. }
  204. return _PrimeList[i];
  205. }
  206. private:
  207. vector<KV*> _table;
  208. size_t _size;
  209. };
  210. void test()
  211. {
  212. //HashBucket<string, string> hs;
  213. //hs.Insert("hello", "你好");
  214. //hs.Insert("world", "世界");
  215. HashBucket<intint> s;
  216. s.Insert(12);
  217. s.Insert(22);
  218. s.Insert(541);
  219. s.Insert(5344);
  220. //s.Remove(1);
  221. //s.Remove(53);
  222. s.Print();
  223. }
  224. int main()
  225. {
  226. test();
  227. return 0;
  228. }