• C++--哈希表的实现及unorder_set和unorder_map的封装


    1.什么是哈希表

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

    unorder_set是用来存储的关联式容器,可以用来快速的查找和去重,在内部是按照无序的方式排列的,它的迭代器和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
    2. #include
    3. #include
    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
    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 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 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 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 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 _Date;//数据
    124. size_t n;//存储有效个数
    125. };
    126. }

    开散列的实现

    1. #include
    2. #include
    3. #include
    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
    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* _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//旧版
    44. template<class K, class T, class Ptr, class Ref, class KeyofT, class HashFunc>//新版
    45. struct HashIterator
    46. {
    47. typedef HashDateNode Node;
    48. typedef HashIterator Self;
    49. typedef HashIterator iterator;
    50. Node* _node;
    51. const HashDate* _pht; //设置位const ,防止普通类型无法转化为const类型
    52. //初始化
    53. /*const HashIterator(Node* node, HashDate* pht)
    54. :_node(node)
    55. , _pht(pht)
    56. {}*/
    57. //const初始化
    58. HashIterator(Node* node, const HashDate* 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>
    115. class HashDate
    116. {
    117. typedef HashDateNode 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 iterator;
    124. typedef HashIteratorconst 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. pairbool> 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 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类型
    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 _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::const_iterator iterator;
    17. typedef typename hash_bucket::HashDate::const_iterator const_iterator;
    18. //typedef typename hash_bucket::HashDate 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. pairbool> 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 _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::HashDateconst K, T>, MapkeyofT>::iterator iterator;//普通迭代器
    16. typedef typename hash_bucket::HashDateconst K, T>, MapkeyofT>::const_iterator const_iterator;//const迭代器
    17. //typedef typename hash_bucket::HashDate, 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. pairbool> insert(const pair& 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. pairbool> 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. HashDateconst 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::const_iterator iterator;
    18. typedef typename hash_bucket::HashDate::const_iterator const_iterator;
    19. //typedef typename hash_bucket::HashDate 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. pairbool> 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 _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::HashDateconst K, T>, MapkeyofT>::iterator iterator;//普通迭代器
    57. typedef typename hash_bucket::HashDateconst K, T>, MapkeyofT>::const_iterator const_iterator;//const迭代器
    58. //typedef typename hash_bucket::HashDate, 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. pairbool> insert(const pair& 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. pairbool> 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. HashDateconst K, T>, MapkeyofT> _ht;
    98. };
    99. //底层实现
    100. #pragma once//防止头文件重复引用
    101. #include
    102. #include
    103. #include
    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
    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 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 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 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 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 _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* _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//旧版
    241. template<class K, class T, class Ptr, class Ref, class KeyofT, class HashFunc>//新版
    242. struct HashIterator
    243. {
    244. typedef HashDateNode Node;
    245. typedef HashIterator Self;
    246. typedef HashIterator iterator;
    247. Node* _node;
    248. const HashDate* _pht; //设置位const ,防止普通类型无法转化为const类型
    249. //初始化
    250. /*const HashIterator(Node* node, HashDate* pht)
    251. :_node(node)
    252. , _pht(pht)
    253. {}*/
    254. //const初始化
    255. HashIterator(Node* node, const HashDate* 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>
    312. class HashDate
    313. {
    314. typedef HashDateNode 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 iterator;
    321. typedef HashIteratorconst 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. pairbool> 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 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类型
    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 _table; //存储数据
    484. size_t n=0; //记录容器中的个数
    485. };
    486. }

  • 相关阅读:
    S波与P波的定义(光波电矢量)(菲涅耳公式)
    写给自己:入职两个月的收获与变化
    新学期,我的FLAG不能倒~
    第一个SpringBoot程序
    IDEA插件Mybatis Log Plugin的安装及其使用教程
    基于视觉AI的管道高后果区预警系统
    wangeditor富文本编辑器使用(详细)
    JavaScript设计模式中的享元模式
    openguass数据库描述指令集合(等保)
    Linux从入门到精通 --- 2.基本命令入门
  • 原文地址:https://blog.csdn.net/weixin_66828150/article/details/133030844