当前位置:   article > 正文

C++--哈希表的实现及unorder_set和unorder_map的封装_c++中用unordered_set建立哈希表

c++中用unordered_set建立哈希表

1.什么是哈希表

哈希表是一种数据结构,用来存放数据的,哈希表存放的数据是无序的,可以实现增删查,当时不能修改数据。可以不经过任何比较,一次直接从表中得到要搜索的元素。如果构造一种存储结构,通过某种函数(hashFunc)使元素的存储位置与它的关键码之间能够建立一一映射的关系,那么在查找时通过该函数可以很快找到该元素。该方式即为哈希(散列)方法,哈希方法中使用的转换函数称为哈希(散列)函数,构造出来的结构称为哈希表(Hash Table)(或者称散列表)。
unordered_map是存储<key, value>键值对的关联式容器,其允许通过keys快速的索引到与其对应的value。
在unordered_map中,键值通常用于惟一地标识元素,而映射值是一个对象,其内容与此键关联。键和映射值的类型可能不同。
在内部,unordered_map没有对<kye, value>按照任何特定的顺序排序, 为了能在常数范围内找到key所对应的value,unordered_map将相同哈希值的键值对放在相同的桶中。
unordered_map容器通过key访问单个元素要比map快,但它通常在遍历元素子集的范围迭代方面效率较低。
unordered_maps实现了直接访问操作符(operator[]),它允许使用key作为参数直接访问value。
它的迭代器至少是前向迭代器。

unorder_set是用来存储<key>的关联式容器,可以用来快速的查找和去重,在内部是按照无序的方式排列的,它的迭代器和unorder_map的使用相同,其他的特性和unorder_map的特性差不多。

2.哈希冲突

对于两个数据元素的关键字$k_i$和 $k_j$(i != j),有$k_i$ != $k_j$,但有:Hash($k_i$) ==
Hash($k_j$),即:不同关键字通过相同哈希哈数计算出相同的哈希地址,该种现象称为哈希冲突或哈希碰撞。把具有不同关键码而具有相同哈希地址的数据元素称为“同义词”。

解决哈希冲突:

引起哈希冲突的一个原因可能是:哈希函数设计不够合理。
哈希函数设计原则:
哈希函数的定义域必须包括需要存储的全部关键码,而如果散列表允许有m个地址时,其值
域必须在0到m-1之间;哈希函数计算出来的地址能均匀分布在整个空间中;哈希函数应该比较简单。

解决哈希冲突两种常见的方法是:闭散列和开散列

闭散列:

线性探测:从发生冲突的位置开始,依次向后探测,直到寻找到下一个空位置为止。

通过哈希函数获取待插入元素在哈希表中的位置,如果该位置中没有元素则直接插入新元素,如果该位置中有元素发生哈希冲突,使用线性探测找到下一个空位置,插入新元素。

开散列:

开散列法又叫链地址法(开链法),首先对关键码集合用散列函数计算散列地址,具有相同地
址的关键码归于同一子集合,每一个子集合称为一个桶,各个桶中的元素通过一个单链表链
接起来,各链表的头结点存储在哈希表中。

开散列与闭散列比较:
应用链地址法处理溢出,需要增设链接指针,似乎增加了存储开销。事实上:
由于开地址法必须保持大量的空闲空间以确保搜索效率,如二次探查法要求装载因子a <=
0.7,而表项所占空间又比指针大的多,所以使用链地址法反而比开地址法节省存储空间。

3.哈希表的实现

闭散列的实现:

  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. //usng namespace std;
  5. using std::cout;
  6. using std:: endl;
  7. using std::cin;
  8. //闭散列
  9. namespace open_address
  10. {
  11. //处理不是整形的字符
  12. template<class T>
  13. struct DefaultHashFunc
  14. {
  15. size_t operator()(const T& t)
  16. {
  17. return size_t(value(t));
  18. }
  19. };
  20. //特殊化处理字符串
  21. template<>
  22. struct DefaultHashFunc<string>
  23. {
  24. const size_t operator()(const string& t)
  25. {
  26. //KeyofT value;
  27. size_t num=1;
  28. for (auto e : t)
  29. {
  30. num *= 131;
  31. num +=e;
  32. }
  33. return num;
  34. }
  35. };
  36. //枚举三种状态
  37. enum State
  38. {
  39. Empty,
  40. Exist,
  41. Delete
  42. };
  43. //哈希节点
  44. template<class T>
  45. struct HashDateNode
  46. {
  47. private:
  48. T _kv;
  49. State _state=Empty;
  50. };
  51. //哈希表
  52. template<class K, class T,class KeyofT,class DefaultHashFunc>
  53. class HashTable
  54. {
  55. typedef HashDateNode<T> Node;
  56. HashTable()//初始化,开辟10个空间
  57. {
  58. _Date.resize(10);
  59. }
  60. //插入数值
  61. bool insert(const T& Date)
  62. {
  63. DefaultHashFunc Func;//处理字符串问题
  64. KeyofT value;//处理set和map的数值问题函数
  65. //扩容
  66. if (n * 10 > _Date.size() * 7)//负载因子
  67. {
  68. int newsize = _Date.size() * 2;
  69. vector<Node*> newHT;
  70. newHT.resize(newsize);//开辟空间
  71. for (int i = 0; i < _Date.size(); i++)
  72. {
  73. if (_Date._state == Exist)//讲旧数据写入新空间中
  74. {
  75. newHT.insert(KetofT(_Date));
  76. }
  77. _Date.swap(newHT._Date);//交换数据
  78. }
  79. }
  80. //插入哈希表
  81. size_t hashi =Func(value(Date))% _Date.size();
  82. while (_Date[hashi]._state == Exist)//存在就++
  83. {
  84. ++hashi;
  85. hashi %= _Date.size();
  86. }
  87. _Date[hashi]._kv = Date;
  88. _Date[hashi]._state = Exist;
  89. n++;//存放个数加一
  90. return true;
  91. }
  92. //查找函数
  93. vector<Node*> Find(const K& t)
  94. {
  95. DefaultHashFunc Func;
  96. KeyofT value;
  97. size_t hashi = Func(value(t)) % _Date.size();
  98. while (_Date[hashi]._state != Empty)
  99. {
  100. if (_Date[hashi]._state == Exist
  101. && value(_Date[hashi]) == t)
  102. {
  103. return _Date[hashi];
  104. }
  105. ++hashi;
  106. hashi %= _Date.size();
  107. }
  108. return nullptr;
  109. }
  110. //删除
  111. bool erash(const K& key)
  112. {
  113. vector<Node*> ret = Find(key);//查找是否存在
  114. if (ret)
  115. {
  116. ret._state= Exist;
  117. n--;
  118. return true;
  119. }
  120. return false;
  121. }
  122. private:
  123. vector<Node*> _Date;//数据
  124. size_t n;//存储有效个数
  125. };
  126. }

开散列的实现

  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. using namespace std;
  5. //处理字符
  6. template<class T>
  7. struct DefaultHashFunc
  8. {
  9. size_t operator()(const T& t)
  10. {
  11. return size_t(t);
  12. }
  13. };template<>
  14. struct DefaultHashFunc<string>
  15. {
  16. size_t operator()(const string& t)
  17. {
  18. size_t num = 0;
  19. for (auto e : t)
  20. {
  21. num *= 131;
  22. num += e;
  23. }
  24. return num;
  25. }
  26. };
  27. //哈希桶,闭散列
  28. namespace hash_bucket
  29. {
  30. template<class T>
  31. struct HashDateNode
  32. {
  33. T _Date;
  34. HashDateNode<T>* _next;
  35. HashDateNode(const T& Date)
  36. :_Date(Date)
  37. ,_next(nullptr)
  38. {}
  39. };
  40. template<class K, class T, class KeyofT, class HashFunc>
  41. class HashDate;//前置声明
  42. //迭代器
  43. //template<class K,class T,class KeyofT ,class HashFunc>//旧版
  44. template<class K, class T, class Ptr, class Ref, class KeyofT, class HashFunc>//新版
  45. struct HashIterator
  46. {
  47. typedef HashDateNode<T> Node;
  48. typedef HashIterator<K,T, Ptr, Ref,KeyofT, HashFunc> Self;
  49. typedef HashIterator<K, T, T*, T&, KeyofT, HashFunc> iterator;
  50. Node* _node;
  51. const HashDate<K, T, KeyofT, HashFunc>* _pht; //设置位const ,防止普通类型无法转化为const类型
  52. //初始化
  53. /*const HashIterator(Node* node, HashDate<K, T, KeyofT, HashFunc>* pht)
  54. :_node(node)
  55. , _pht(pht)
  56. {}*/
  57. //const初始化
  58. HashIterator(Node* node, const HashDate<K, T, KeyofT, HashFunc>* pht)
  59. :_node(node)
  60. , _pht(pht)
  61. {}
  62. // 普通迭代器时,他是拷贝构造
  63. // const迭代器时,他是构造函数
  64. HashIterator(const iterator& it)//防止set类型的const类型与非const类型的转换(模板不同)
  65. :_node(it._node)
  66. , _pht(it._pht)
  67. {}
  68. Ref operator*()
  69. {
  70. return _node->_Date;
  71. }
  72. Ptr operator->()
  73. {
  74. return &_node->_Date;
  75. }
  76. bool operator!=(const Self& s)
  77. {
  78. return _node != s._node;
  79. }
  80. bool operator==(const Self& s)
  81. {
  82. return _node == s._node;
  83. }
  84. Self& operator++()
  85. {
  86. if (_node->_next)
  87. {
  88. _node = _node->_next;
  89. }
  90. else
  91. {
  92. HashFunc Func;
  93. KeyofT value;
  94. size_t hashi = Func(value(_node->_Date)) % _pht->_table.size(); //该用仿函数
  95. //从下一个哈希桶查找
  96. hashi++;
  97. while (hashi < _pht->_table.size())
  98. {
  99. if (_pht->_table[hashi])//不为空
  100. {
  101. _node = _pht->_table[hashi];
  102. return *this;
  103. }
  104. else//为空
  105. {
  106. ++hashi;
  107. }
  108. }
  109. _node = nullptr;
  110. }
  111. return *this;
  112. }
  113. };
  114. template<class K, class T, class KeyofT, class HashFunc = DefaultHashFunc<K>>
  115. class HashDate
  116. {
  117. typedef HashDateNode<T> Node;
  118. //
  119. //友元
  120. template<class K, class T, class Ptr, class Ref, class KeyofT, class HashFunc>
  121. friend struct HashIterator;//可以使用迭代器
  122. public:
  123. typedef HashIterator<K, T, T*, T&, KeyofT, HashFunc> iterator;
  124. typedef HashIterator<K, T, const T*, const T&, KeyofT, HashFunc> const_iterator;
  125. iterator begin()
  126. {
  127. for (size_t i = 0; i < _table.size(); i++)
  128. {
  129. Node* cur = _table[i];
  130. if (cur)
  131. {
  132. return iterator(cur,this);
  133. }
  134. }
  135. return iterator(nullptr, this);
  136. }
  137. const_iterator begin() const
  138. {
  139. for (size_t i = 0; i < _table.size(); i++)
  140. {
  141. Node* cur = _table[i];
  142. if (cur)
  143. {
  144. return iterator(cur, this);
  145. }
  146. }
  147. return iterator(nullptr, this);
  148. }
  149. iterator end()
  150. {
  151. return iterator(nullptr, this);
  152. }
  153. const_iterator end() const
  154. {
  155. return iterator(nullptr, this);
  156. }
  157. HashDate()
  158. {
  159. _table.resize(10, nullptr);
  160. }
  161. ~HashDate()
  162. {
  163. for (size_t i = 0; i < _table.size(); i++)
  164. {
  165. Node* cur = _table[i];
  166. while (cur)
  167. {
  168. Node* next = cur->_next;
  169. delete cur;
  170. cur = next;
  171. }
  172. _table[i] = nullptr;
  173. }
  174. }
  175. pair<iterator,bool> Insert(const T& date)
  176. {
  177. KeyofT value;
  178. HashFunc Func;
  179. iterator it = Find(value(date));
  180. //it!=end()
  181. if(it != end())
  182. {
  183. return make_pair(it,false);
  184. }
  185. if (n == _table.size())//扩容
  186. {
  187. int newsize = _table.size() * 2;
  188. vector<Node*> newHash;
  189. newHash.resize(newsize);
  190. for (size_t i = 0; i < _table.size(); i++)//旧数据
  191. {
  192. Node* cur = _table[i];
  193. while (cur)
  194. {
  195. Node* next = cur->_next;
  196. size_t hashi = Func(value(cur->_Date))% newsize;
  197. cur->_next = newHash[hashi];
  198. newHash[hashi] = cur;
  199. cur = next;
  200. }
  201. _table[i] = nullptr;
  202. }
  203. _table.swap(newHash);//交换数据
  204. }
  205. //插入
  206. size_t hashi = Func(value(date))% _table.size();//改变
  207. //Node* cur = _table[hashi];
  208. //尾插
  209. //Node* newNode = new Node(date);
  210. //while (cur)
  211. //{
  212. // cur = cur->_next;
  213. //}
  214. //cur = newNode;
  215. //头插
  216. Node* newNode = new Node(date);//新节点
  217. newNode->_next = _table[hashi];//头结点
  218. _table[hashi] = newNode;//尾节点
  219. n++;
  220. return make_pair(iterator(newNode,this),true);
  221. }
  222. //查找
  223. iterator Find(const K& key)//Find为K类型的只用一个数值,T类型的在map中为pair<K,T>类型
  224. {
  225. HashFunc Func;
  226. KeyofT value;
  227. size_t hashi = Func(key) % _table.size();
  228. //size_t hashi = Func(value(key)) % _table.size();//不能使用这个
  229. Node* cur = _table[hashi];
  230. while (cur)
  231. {
  232. if (value(cur->_Date) == key)//?
  233. {
  234. return iterator(cur,this);
  235. }
  236. cur = cur->_next;
  237. }
  238. return iterator(nullptr,this);
  239. }
  240. //删除
  241. bool Erase(const K& key)
  242. {
  243. HashFunc Func;
  244. KeyofT value;
  245. iterator ret=Find(key);
  246. if (ret == end())
  247. return true;
  248. size_t x = Func(value(key))% _table.size();
  249. Node* cur = _table[x];
  250. Node* prev = nullptr;
  251. while (cur)
  252. {
  253. if (value(cur->_Date) == key)
  254. {
  255. if (prev == nullptr)
  256. {
  257. _table[x] = cur->_next;
  258. }
  259. else
  260. {
  261. prev->_next = cur->_next;
  262. }
  263. }
  264. prev = cur;
  265. cur = cur->_next;
  266. delete cur;
  267. return true;
  268. }
  269. return false;
  270. }
  271. //打印
  272. void Print()
  273. {
  274. for (int i = 10; i < _table.size(); i++)
  275. {
  276. Node* cur = _table[i];
  277. while (cur)
  278. {
  279. std::cout << cur->_Date.first<<" " << cur->_Date.second <<" " << std::endl;
  280. cur = cur->_next;
  281. }
  282. }
  283. std::cout << std::endl;
  284. }
  285. private:
  286. vector<Node*> _table; //存储数据
  287. size_t n=0; //记录容器中的个数
  288. };
  289. }

4.Unorderset和Unordermap的实现

4.1 Unorderset

  1. #pragma once
  2. #include "HashTable.h"
  3. using namespace hash_bucket;
  4. //using namespace open_address;
  5. template<class K>
  6. class Unorderset
  7. {
  8. struct SetKeyofT
  9. {
  10. const K& operator()(const K& k)
  11. {
  12. return k;
  13. }
  14. };
  15. public:
  16. typedef typename hash_bucket::HashDate<K, K, SetKeyofT>::const_iterator iterator;
  17. typedef typename hash_bucket::HashDate<K, K, SetKeyofT>::const_iterator const_iterator;
  18. //typedef typename hash_bucket::HashDate<K, K, SetKeyofT> Hash;
  19. public:
  20. const_iterator begin() const
  21. {
  22. return _ht.begin();
  23. }
  24. const_iterator end() const
  25. {
  26. return _ht.end();
  27. }
  28. pair<iterator, bool> insert(const K& k)
  29. {
  30. return _ht.Insert(k);
  31. }
  32. iterator find(const K& kk)
  33. {
  34. return _ht.Find(kk);
  35. }
  36. bool erase(const K& kk)
  37. {
  38. return _ht.Erase(kk);
  39. }
  40. private:
  41. HashDate<K, K, SetKeyofT> _ht;
  42. };

4.2 Unordermap

  1. #pragma once
  2. #include "HashTable.h"
  3. using namespace hash_bucket;
  4. template<class K,class T>
  5. class Unordermap
  6. {
  7. struct MapkeyofT
  8. {
  9. const K& operator()(const pair<const K, T>& kt)
  10. {
  11. return kt.first;
  12. }
  13. };
  14. public:
  15. typedef typename hash_bucket::HashDate<K, pair<const K, T>, MapkeyofT>::iterator iterator;//普通迭代器
  16. typedef typename hash_bucket::HashDate<K, pair<const K, T>, MapkeyofT>::const_iterator const_iterator;//const迭代器
  17. //typedef typename hash_bucket::HashDate<K, pair<K, T>, MapkeyofT> Hash;
  18. iterator begin()
  19. {
  20. return _ht.begin();
  21. }
  22. iterator end()
  23. {
  24. return _ht.end();
  25. }
  26. const_iterator begin() const
  27. {
  28. return _ht.begin();
  29. }
  30. const_iterator end() const
  31. {
  32. return _ht.end();
  33. }
  34. //插入
  35. pair<iterator, bool> insert(const pair<K,T>& kt)
  36. {
  37. return _ht.Insert(kt);
  38. }
  39. //查找
  40. iterator find(const K& kk)
  41. {
  42. return _ht.Find(kk);
  43. }
  44. //重载[]
  45. T& operator[](const K& kk)
  46. {
  47. pair<iterator, bool> ret = insert(make_pair(kk, T()));
  48. return ret.first->second;
  49. }
  50. //删除
  51. bool eraser(const K& kk)
  52. {
  53. return _ht.Erase(kk);
  54. }
  55. private:
  56. HashDate<K, pair<const K, T>, MapkeyofT> _ht;
  57. };

4.3 完整代码

Ps:具体实现中建议分开写

  1. #pragma once
  2. #include "HashTable.h"
  3. using namespace hash_bucket;
  4. using namespace open_address;
  5. //set实现
  6. template<class K>
  7. class Unorderset
  8. {
  9. struct SetKeyofT
  10. {
  11. const K& operator()(const K& k)
  12. {
  13. return k;
  14. }
  15. };
  16. public:
  17. typedef typename hash_bucket::HashDate<K, K, SetKeyofT>::const_iterator iterator;
  18. typedef typename hash_bucket::HashDate<K, K, SetKeyofT>::const_iterator const_iterator;
  19. //typedef typename hash_bucket::HashDate<K, K, SetKeyofT> Hash;
  20. public:
  21. const_iterator begin() const
  22. {
  23. return _ht.begin();
  24. }
  25. const_iterator end() const
  26. {
  27. return _ht.end();
  28. }
  29. pair<iterator, bool> insert(const K& k)
  30. {
  31. return _ht.Insert(k);
  32. }
  33. iterator find(const K& kk)
  34. {
  35. return _ht.Find(kk);
  36. }
  37. bool erase(const K& kk)
  38. {
  39. return _ht.Erase(kk);
  40. }
  41. private:
  42. HashDate<K, K, SetKeyofT> _ht;
  43. };
  44. //map实现
  45. template<class K,class T>
  46. class Unordermap
  47. {
  48. struct MapkeyofT
  49. {
  50. const K& operator()(const pair<const K, T>& kt)
  51. {
  52. return kt.first;
  53. }
  54. };
  55. public:
  56. typedef typename hash_bucket::HashDate<K, pair<const K, T>, MapkeyofT>::iterator iterator;//普通迭代器
  57. typedef typename hash_bucket::HashDate<K, pair<const K, T>, MapkeyofT>::const_iterator const_iterator;//const迭代器
  58. //typedef typename hash_bucket::HashDate<K, pair<K, T>, MapkeyofT> Hash;
  59. iterator begin()
  60. {
  61. return _ht.begin();
  62. }
  63. iterator end()
  64. {
  65. return _ht.end();
  66. }
  67. const_iterator begin() const
  68. {
  69. return _ht.begin();
  70. }
  71. const_iterator end() const
  72. {
  73. return _ht.end();
  74. }
  75. //插入
  76. pair<iterator, bool> insert(const pair<K,T>& kt)
  77. {
  78. return _ht.Insert(kt);
  79. }
  80. //查找
  81. iterator find(const K& kk)
  82. {
  83. return _ht.Find(kk);
  84. }
  85. //重载[]
  86. T& operator[](const K& kk)
  87. {
  88. pair<iterator, bool> ret = insert(make_pair(kk, T()));
  89. return ret.first->second;
  90. }
  91. //删除
  92. bool eraser(const K& kk)
  93. {
  94. return _ht.Erase(kk);
  95. }
  96. private:
  97. HashDate<K, pair<const K, T>, MapkeyofT> _ht;
  98. };
  99. //底层实现
  100. #pragma once//防止头文件重复引用
  101. #include <iostream>
  102. #include <vector>
  103. #include <string>
  104. using namespace std;
  105. //处理不是整形的字符
  106. template<class T>
  107. struct DefaultHashFunc
  108. {
  109. size_t operator()(const T& t)
  110. {
  111. return size_t(value(t));
  112. }
  113. };
  114. //特殊化处理字符串
  115. template<>
  116. struct DefaultHashFunc<string>
  117. {
  118. const size_t operator()(const string& t)
  119. {
  120. //KeyofT value;
  121. size_t num=1;
  122. for (auto e : t)
  123. {
  124. num *= 131;
  125. num +=e;
  126. }
  127. return num;
  128. }
  129. };
  130. //开散列
  131. namespace open_address
  132. {
  133. //枚举三种状态
  134. enum State
  135. {
  136. Empty,
  137. Exist,
  138. Delete
  139. };
  140. //哈希节点
  141. template<class T>
  142. struct HashDateNode
  143. {
  144. private:
  145. T _kv;
  146. State _state=Empty;
  147. };
  148. //哈希表
  149. template<class K, class T,class KeyofT,class DefaultHashFunc>
  150. class HashTable
  151. {
  152. typedef HashDateNode<T> Node;
  153. HashTable()//初始化,开辟10个空间
  154. {
  155. _Date.resize(10);
  156. }
  157. //插入数值
  158. bool insert(const T& Date)
  159. {
  160. DefaultHashFunc Func;//处理字符串问题
  161. KeyofT value;//处理set和map的数值问题函数
  162. //扩容
  163. if (n * 10 > _Date.size() * 7)//负载因子
  164. {
  165. int newsize = _Date.size() * 2;
  166. vector<Node*> newHT;
  167. newHT.resize(newsize);//开辟空间
  168. for (int i = 0; i < _Date.size(); i++)
  169. {
  170. if (_Date._state == Exist)//讲旧数据写入新空间中
  171. {
  172. newHT.insert(KetofT(_Date));
  173. }
  174. _Date.swap(newHT._Date);//交换数据
  175. }
  176. }
  177. //插入哈希表
  178. size_t hashi =Func(value(Date))% _Date.size();
  179. while (_Date[hashi]._state == Exist)//存在就++
  180. {
  181. ++hashi;
  182. hashi %= _Date.size();
  183. }
  184. _Date[hashi]._kv = Date;
  185. _Date[hashi]._state = Exist;
  186. n++;//存放个数加一
  187. return true;
  188. }
  189. //查找函数
  190. vector<Node*> Find(const K& t)
  191. {
  192. DefaultHashFunc Func;
  193. KeyofT value;
  194. size_t hashi = Func(value(t)) % _Date.size();
  195. while (_Date[hashi]._state != Empty)
  196. {
  197. if (_Date[hashi]._state == Exist
  198. && value(_Date[hashi]) == t)
  199. {
  200. return _Date[hashi];
  201. }
  202. ++hashi;
  203. hashi %= _Date.size();
  204. }
  205. return nullptr;
  206. }
  207. //删除
  208. bool erash(const K& key)
  209. {
  210. vector<Node*> ret = Find(key);//查找是否存在
  211. if (ret)
  212. {
  213. ret._state= Exist;
  214. n--;
  215. return true;
  216. }
  217. return false;
  218. }
  219. private:
  220. vector<Node*> _Date;//数据
  221. size_t n;//存储有效个数
  222. };
  223. }
  224. //哈希桶,闭散列
  225. namespace hash_bucket
  226. {
  227. template<class T>
  228. struct HashDateNode
  229. {
  230. T _Date;
  231. HashDateNode<T>* _next;
  232. HashDateNode(const T& Date)
  233. :_Date(Date)
  234. ,_next(nullptr)
  235. {}
  236. };
  237. template<class K, class T, class KeyofT, class HashFunc>
  238. class HashDate;//前置声明
  239. //迭代器
  240. //template<class K,class T,class KeyofT ,class HashFunc>//旧版
  241. template<class K, class T, class Ptr, class Ref, class KeyofT, class HashFunc>//新版
  242. struct HashIterator
  243. {
  244. typedef HashDateNode<T> Node;
  245. typedef HashIterator<K,T, Ptr, Ref,KeyofT, HashFunc> Self;
  246. typedef HashIterator<K, T, T*, T&, KeyofT, HashFunc> iterator;
  247. Node* _node;
  248. const HashDate<K, T, KeyofT, HashFunc>* _pht; //设置位const ,防止普通类型无法转化为const类型
  249. //初始化
  250. /*const HashIterator(Node* node, HashDate<K, T, KeyofT, HashFunc>* pht)
  251. :_node(node)
  252. , _pht(pht)
  253. {}*/
  254. //const初始化
  255. HashIterator(Node* node, const HashDate<K, T, KeyofT, HashFunc>* pht)
  256. :_node(node)
  257. , _pht(pht)
  258. {}
  259. // 普通迭代器时,他是拷贝构造
  260. // const迭代器时,他是构造函数
  261. HashIterator(const iterator& it)//防止set类型的const类型与非const类型的转换(模板不同)
  262. :_node(it._node)
  263. , _pht(it._pht)
  264. {}
  265. Ref operator*()
  266. {
  267. return _node->_Date;
  268. }
  269. Ptr operator->()
  270. {
  271. return &_node->_Date;
  272. }
  273. bool operator!=(const Self& s)
  274. {
  275. return _node != s._node;
  276. }
  277. bool operator==(const Self& s)
  278. {
  279. return _node == s._node;
  280. }
  281. Self& operator++()
  282. {
  283. if (_node->_next)
  284. {
  285. _node = _node->_next;
  286. }
  287. else
  288. {
  289. HashFunc Func;
  290. KeyofT value;
  291. size_t hashi = Func(value(_node->_Date)) % _pht->_table.size(); //该用仿函数
  292. //从下一个哈希桶查找
  293. hashi++;
  294. while (hashi < _pht->_table.size())
  295. {
  296. if (_pht->_table[hashi])//不为空
  297. {
  298. _node = _pht->_table[hashi];
  299. return *this;
  300. }
  301. else//为空
  302. {
  303. ++hashi;
  304. }
  305. }
  306. _node = nullptr;
  307. }
  308. return *this;
  309. }
  310. };
  311. template<class K, class T, class KeyofT, class HashFunc = DefaultHashFunc<K>>
  312. class HashDate
  313. {
  314. typedef HashDateNode<T> Node;
  315. //
  316. //友元
  317. template<class K, class T, class Ptr, class Ref, class KeyofT, class HashFunc>
  318. friend struct HashIterator;//可以使用迭代器
  319. public:
  320. typedef HashIterator<K, T, T*, T&, KeyofT, HashFunc> iterator;
  321. typedef HashIterator<K, T, const T*, const T&, KeyofT, HashFunc> const_iterator;
  322. iterator begin()
  323. {
  324. for (size_t i = 0; i < _table.size(); i++)
  325. {
  326. Node* cur = _table[i];
  327. if (cur)
  328. {
  329. return iterator(cur,this);
  330. }
  331. }
  332. return iterator(nullptr, this);
  333. }
  334. const_iterator begin() const
  335. {
  336. for (size_t i = 0; i < _table.size(); i++)
  337. {
  338. Node* cur = _table[i];
  339. if (cur)
  340. {
  341. return iterator(cur, this);
  342. }
  343. }
  344. return iterator(nullptr, this);
  345. }
  346. iterator end()
  347. {
  348. return iterator(nullptr, this);
  349. }
  350. const_iterator end() const
  351. {
  352. return iterator(nullptr, this);
  353. }
  354. HashDate()
  355. {
  356. _table.resize(10, nullptr);
  357. }
  358. ~HashDate()
  359. {
  360. for (size_t i = 0; i < _table.size(); i++)
  361. {
  362. Node* cur = _table[i];
  363. while (cur)
  364. {
  365. Node* next = cur->_next;
  366. delete cur;
  367. cur = next;
  368. }
  369. _table[i] = nullptr;
  370. }
  371. }
  372. pair<iterator,bool> Insert(const T& date)
  373. {
  374. KeyofT value;
  375. HashFunc Func;
  376. iterator it = Find(value(date));
  377. //it!=end()
  378. if(it != end())
  379. {
  380. return make_pair(it,false);
  381. }
  382. if (n == _table.size())//扩容
  383. {
  384. int newsize = _table.size() * 2;
  385. vector<Node*> newHash;
  386. newHash.resize(newsize);
  387. for (size_t i = 0; i < _table.size(); i++)//旧数据
  388. {
  389. Node* cur = _table[i];
  390. while (cur)
  391. {
  392. Node* next = cur->_next;
  393. size_t hashi = Func(value(cur->_Date))% newsize;
  394. cur->_next = newHash[hashi];
  395. newHash[hashi] = cur;
  396. cur = next;
  397. }
  398. _table[i] = nullptr;
  399. }
  400. _table.swap(newHash);//交换数据
  401. }
  402. //插入
  403. size_t hashi = Func(value(date))% _table.size();//改变
  404. //Node* cur = _table[hashi];
  405. //尾插
  406. //Node* newNode = new Node(date);
  407. //while (cur)
  408. //{
  409. // cur = cur->_next;
  410. //}
  411. //cur = newNode;
  412. //头插
  413. Node* newNode = new Node(date);//新节点
  414. newNode->_next = _table[hashi];//头结点
  415. _table[hashi] = newNode;//尾节点
  416. n++;
  417. return make_pair(iterator(newNode,this),true);
  418. }
  419. //查找
  420. iterator Find(const K& key)//Find为K类型的只用一个数值,T类型的在map中为pair<K,T>类型
  421. {
  422. HashFunc Func;
  423. KeyofT value;
  424. size_t hashi = Func(key) % _table.size();
  425. //size_t hashi = Func(value(key)) % _table.size();//不能使用这个
  426. Node* cur = _table[hashi];
  427. while (cur)
  428. {
  429. if (value(cur->_Date) == key)//?
  430. {
  431. return iterator(cur,this);
  432. }
  433. cur = cur->_next;
  434. }
  435. return iterator(nullptr,this);
  436. }
  437. //删除
  438. bool Erase(const K& key)
  439. {
  440. HashFunc Func;
  441. KeyofT value;
  442. iterator ret=Find(key);
  443. if (ret == end())
  444. return true;
  445. size_t x = Func(value(key))% _table.size();
  446. Node* cur = _table[x];
  447. Node* prev = nullptr;
  448. while (cur)
  449. {
  450. if (value(cur->_Date) == key)
  451. {
  452. if (prev == nullptr)
  453. {
  454. _table[x] = cur->_next;
  455. }
  456. else
  457. {
  458. prev->_next = cur->_next;
  459. }
  460. }
  461. prev = cur;
  462. cur = cur->_next;
  463. delete cur;
  464. return true;
  465. }
  466. return false;
  467. }
  468. //打印
  469. void Print()
  470. {
  471. for (int i = 10; i < _table.size(); i++)
  472. {
  473. Node* cur = _table[i];
  474. while (cur)
  475. {
  476. std::cout << cur->_Date.first<<" " << cur->_Date.second <<" " << std::endl;
  477. cur = cur->_next;
  478. }
  479. }
  480. std::cout << std::endl;
  481. }
  482. private:
  483. vector<Node*> _table; //存储数据
  484. size_t n=0; //记录容器中的个数
  485. };
  486. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/501816
推荐阅读
相关标签
  

闽ICP备14008679号