文章目录
- 1.Map && Set
- RBTree.h
- Map.h
- Set.h
- main.cc
- 2.HashMap && HashSet
- HashTable_Test.h
- HashTable.h
- Unordered_Map.h
- Unordered_Set.h
- main.cc
1.Map && Set
RBTree.h
#pragma once
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <array>
#include <time.h>
#include <queue>
#include <stack>
#include <string>
#include <set>
#include <map>
#include <functional>
#include <assert.h>
using namespace std;
enum Colour
{RED,BLACK,
};
template <class T>
struct RBTreeNode
{RBTreeNode<T> *_left;RBTreeNode<T> *_right;RBTreeNode<T> *_parent;T _data;Colour _col;RBTreeNode(const T &data): _left(nullptr), _right(nullptr), _parent(nullptr), _data(data), _col(RED){}
};
template <class T, class Ref, class Ptr>
struct RBTreeIterator
{typedef RBTreeNode<T> Node;typedef RBTreeIterator<T, Ref, Ptr> Self;Node *_node;RBTreeIterator(Node *node): _node(node){}RBTreeIterator(const RBTreeIterator<T, T &, T *> &it): _node(it._node){}Ref operator*(){return _node->_data;}Ptr operator->(){return &_node->_data;}bool operator!=(const Self &s){return _node != s._node;}Self &operator++(){if (_node->_right){Node *subLeft = _node->_right;while (subLeft->_left){subLeft = subLeft->_left;}_node = subLeft;}else{Node *cur = _node;Node *dad = cur->_parent;while (dad && cur == dad->_right){cur = dad;dad = dad->_parent;}_node = dad;}return *this;}Self operator++(int){Self it(_node);++*this;return it;}Self &operator--(){if (_node->_left){Node *subRight = _node->_left;while (subRight->_right){subRight = subRight->_right;}_node = subRight;}else{Node *cur = _node;Node *dad = cur->_parent;while (dad && cur == dad->_left){cur = dad;dad = dad->_parent;}_node = dad;}return *this;}Self operator--(int){Self it(_node);--*this;return it;}
};
template <class K, class T, class GetKey>
class RBTree
{typedef RBTreeNode<T> Node;private:Node *_root = nullptr;public:typedef RBTreeIterator<T, T &, T *> itertaor;typedef RBTreeIterator<T, const T &, const T *> const_itertaor;itertaor begin(){Node *cp = _root;while (cp && cp->_left){cp = cp->_left;}return itertaor(cp);}itertaor end(){return itertaor(nullptr);}const_itertaor begin() const{Node *cp = _root;while (cp && cp->_left){cp = cp->_left;}return const_itertaor(cp);}const_itertaor end() const{return const_itertaor(nullptr);}Node *Find(const K &key){Node *cp = _root;GetKey get;while (cp){if (get(cp->_data) < key){cp = cp->_right;}else if (get(cp->_data) > key){cp = cp->_left;}else{return cp;}}return nullptr;}pair<itertaor, bool> Insert(const T &data){if (_root == nullptr){_root = new Node(data);_root->_col = BLACK; return make_pair(itertaor(_root), true);}GetKey get;Node *dad = nullptr;Node *cur = _root;while (cur){if (get(cur->_data) < get(data)){dad = cur;cur = cur->_right;}else if (get(cur->_data) > get(data)){dad = cur;cur = cur->_left;}else{return make_pair(itertaor(cur), false);}}cur = new Node(data);Node *tmp = cur;if (get(dad->_data) > get(data)){dad->_left = cur;}else{dad->_right = cur;}cur->_parent = dad;while (dad && dad->_col == RED){Node *grandpa = dad->_parent;assert(grandpa && grandpa->_col == BLACK);if (dad == grandpa->_left){Node *uncle = grandpa->_right;if (uncle && uncle->_col == RED){dad->_col = uncle->_col = BLACK;grandpa->_col = RED;cur = grandpa;dad = cur->_parent;}else{if (cur == dad->_left){RotateR(grandpa);dad->_col = BLACK;grandpa->_col = RED;}else{RotateL(dad);RotateR(grandpa);cur->_col = BLACK;grandpa->_col = RED;}break;}}else{Node *uncle = grandpa->_left;if (uncle && uncle->_col == RED){dad->_col = uncle->_col = BLACK;grandpa->_col = RED;cur = grandpa;dad = cur->_parent;}else{if (cur == dad->_right){RotateL(grandpa);dad->_col = BLACK;grandpa->_col = RED;}else{RotateR(dad);RotateL(grandpa);cur->_col = BLACK;grandpa->_col = RED;}break;}}}_root->_col = BLACK;return make_pair(itertaor(tmp), true);}bool IsRBTree(){if (_root && _root->_col == RED){cout << "根节点颜色错误!" << endl;return false;}int certain = 0;Node *cur = _root;while (cur){if (cur->_col == BLACK)++certain;cur = cur->_left;}return PrevJudge(_root, 0, certain);}int Height(){return _Height(_root);}~RBTree(){_Destroy(_root);_root = nullptr;}private:void _Destroy(Node *root){if (root == nullptr){return;}_Destroy(root->_left);_Destroy(root->_right);delete root;}int _Height(Node *root){if (root == NULL)return 0;int leftH = _Height(root->_left);int rightH = _Height(root->_right);return leftH > rightH ? leftH + 1 : rightH + 1;}bool PrevJudge(Node *root, int BNcount, int &certain){if (root == nullptr){if (BNcount != certain){cout << "性质4违例: 存在某一路径黑色节点的数量不等!" << endl;return false;}return true;}if (root->_col == BLACK){++BNcount;}if (root->_col == RED && root->_parent && root->_parent->_col == RED){cout << "性质3违例: 存在连续红节点!" << endl;return false;}return PrevJudge(root->_left, BNcount, certain) && PrevJudge(root->_right, BNcount, certain);}void RotateL(Node *dad){Node *subR = dad->_right;Node *subRL = subR->_left;dad->_right = subRL;if (subRL)subRL->_parent = dad;Node *grandpa = dad->_parent;subR->_left = dad;dad->_parent = subR;if (grandpa == nullptr){_root = subR;_root->_parent = nullptr;}else{if (grandpa->_left == dad){grandpa->_left = subR;}else{grandpa->_right = subR;}subR->_parent = grandpa;}}void RotateR(Node *dad){Node *subL = dad->_left;Node *subLR = subL->_right;dad->_left = subLR;if (subLR)subLR->_parent = dad;Node *grandpa = dad->_parent;subL->_right = dad;dad->_parent = subL;if (dad == _root){_root = subL;_root->_parent = nullptr;}else{if (grandpa->_left == dad){grandpa->_left = subL;}else{grandpa->_right = subL;}subL->_parent = grandpa;}}
};
Map.h
#pragma once
#include "RBTree.h"namespace ape
{template <class K, class V>class map{struct GetKeyMap{const K &operator()(const pair<const K, V> &pair){return pair.first;}};private:RBTree<K, pair<const K, V>, GetKeyMap> _rbtree;public:typedef typename RBTree<K, pair<const K, V>, GetKeyMap>::itertaor iterator;iterator begin(){return _rbtree.begin();}iterator end(){return _rbtree.end();}V &operator[](const K &key){pair<iterator, bool> pair = _rbtree.Insert(make_pair(key, V()));return pair.first->second;}pair<iterator, bool> insert(const pair<const K, V> &pair){return _rbtree.Insert(pair);}iterator find(const K &key){return _rbtree.Find(key);}map() = default;template <class InputIterator>map(InputIterator first, InputIterator last){while (first != last){_rbtree.Insert(*first);++first;}}};void test_map1(){map<string, string> m;string a = "Eddie", b = "彭于晏";m.insert(make_pair(a, b));m.insert(make_pair("Tom", "汤姆"));m.insert(make_pair("Jerry", "杰瑞"));map<string, string>::iterator it = m.begin();while (it != m.end()){cout << it->first << ":" << it->second << endl;++it;}cout << endl;for (auto &e : m){cout << e.first << ":" << e.second << endl;}cout << endl;}void test_map2(){string s[] = {"陀螺", "陀螺", "洋娃娃", "陀螺", "洋娃娃", "洋娃娃", "陀螺","洋娃娃", "悠悠球", "洋娃娃", "悠悠球", "乐高"};map<string, int> m;for (auto &e : s){m[e]++;}for (auto &e : m){cout << e.first << ":" << e.second << endl;}}
}
Set.h
#pragma once
#include "RBTree.h"
namespace ape
{template <class K>class set{struct GetKeySet{const K &operator()(const K &key){return key;}};private:RBTree<K, K, GetKeySet> _rbtree;public:typedef typename RBTree<K, K, GetKeySet>::const_itertaor iterator; typedef typename RBTree<K, K, GetKeySet>::const_itertaor const_iterator;iterator begin(){return _rbtree.begin();}iterator end(){return _rbtree.end();}pair<iterator, bool> insert(const K &key){return _rbtree.Insert(key);}set() = default;template <class InputIterator>set(InputIterator first, InputIterator last){while (first != last){_rbtree.Insert(*first);++first;}}iterator find(const K &k){return _rbtree.Find(k);}};void test_set(){int a[] = {16, 3, 7, 11, 9, 26, 18, 14, 15};set<int> s;for (auto e : a){s.insert(e);}set<int>::iterator it = s.begin();while (it != s.end()){cout << *it << " ";++it;}cout << endl;for (auto e : s){cout << e << " ";}cout << endl;}
}
main.cc
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <array>
#include <time.h>
#include <queue>
#include <stack>
#include <string>
#include <set>
#include <map>
#include <functional>
using namespace std;#include "RBTree.h"
#include "Map.h"
#include "Set.h"int main()
{ape::test_set();ape::test_map2();return 0;
}
2.HashMap && HashSet
HashTable_Test.h
#include <iostream>
#include <vector>
#include <functional>
#include <utility>
#include <cassert>
using namespace std;
namespace OpenAddressing
{enum State{EMPTY,EXIST,DELETE};template <class K, class V>struct HashData{pair<K, V> _pair;State _state = EMPTY;};template <class K, class V>class HashTable{private:vector<HashData<K, V>> _tables;size_t _n = 0; public:bool Insert(const pair<K, V> &pair){if (Find(pair.first))return false;if (_tables.size() == 0 || _n * 10 / _tables.size() >= 7){/ 低级代码 /size_t newsize = _tables.size() == 0 ? 10 : _tables.size() * 2;HashTable<K, V> other;other._tables.resize(newsize);for (auto &e : _tables){if (e._state == EXIST)other.Insert(e._pair);}_tables.swap(other._tables);/}size_t hashi = pair.first % _tables.size();size_t index = hashi; for (size_t i = 1; _tables[index]._state == EXIST; ++i){index = hashi + i; index %= _tables.size(); }_tables[index]._pair = pair;_tables[index]._state = EXIST;_n++; return true;}HashData<K, V> *Find(const K &key){if (_tables.size() == 0)return nullptr;size_t hashi = key % _tables.size();size_t index = hashi;for (size_t i = 1; _tables[index]._state != EMPTY; ++i){if (_tables[index]._state == EXIST && _tables[index]._pair.first == key){return &_tables[index];}index = hashi + i;index %= _tables.size();if (index == hashi)break;}return nullptr;}bool Erase(const K &key){HashData<K, V> *pos = Find(key);if (pos){pos->_state = DELETE;--_n; return true;}elsereturn false;}};void TestHashTable(){int a[] = {3, 33, 2, 13, 5, 12, 1002};HashTable<int, int> ht;for (auto &e : a)ht.Insert(make_pair(e, e));ht.Insert(make_pair(15, 15));int tmp = 12;if (ht.Find(tmp))cout << tmp << "在" << endl;elsecout << tmp << "不在" << endl;ht.Erase(tmp);if (ht.Find(tmp))cout << tmp << "在" << endl;elsecout << tmp << "不在" << endl;}
}
namespace ChainAddressing
{template <class K, class V>struct HashNode{HashNode<K, V> *_next;pair<K, V> _pair;HashNode(const pair<K, V> &pair): _next(nullptr), _pair(pair){}};template <class K>struct hash{size_t operator()(const K &key){return key;}};template <>struct hash<string>{size_t operator()(const string &s){size_t value = 0;for (auto ch : s){value = value * 131 + ch;}return value;}};struct StringToInt{size_t operator()(const string& s){size_t value = 0;for (auto& ch : s){value = value * 131 + ch;}return value;}};template <class K, class V, class Hash = hash<K>>class HashTable{typedef HashNode<K, V> Node;private:vector<Node *> _tables; size_t _n = 0; public:~HashTable(){for (auto &ptr : _tables){while (ptr){Node *next = ptr->_next;delete ptr;ptr = next;}ptr = nullptr;}}Node *Find(const K &key){if (_tables.size() == 0)return nullptr;size_t hashi = key % _tables.size();Node *ptr = _tables[hashi];while (ptr){if (ptr->_pair.first == key)return ptr;ptr = ptr->_next;}return nullptr;}bool Erase(const K &key){size_t hashi = key % _tables.size();Node *ptr = _tables[hashi];Node *prv = nullptr;while (ptr){if (ptr->_pair.first == key){if (prv == nullptr)_tables[hashi] = ptr->_next;elseprv->_next = ptr->_next;delete ptr;return true;}else{prv = ptr;ptr = ptr->_next;}}return false;}bool Insert(const pair<K, V> &pair){if (Find(pair.first))return false;Hash hash;if (_n == _tables.size()){size_t newsize = _tables.size() == 0 ? 10 : _tables.size() * 2;vector<Node *> newtables(newsize, nullptr);for (auto &ptr : _tables){while (ptr){size_t hashi = hash(ptr->_pair.first) % newtables.size();Node *next = ptr->_next;ptr->_next = newtables[hashi];newtables[hashi] = ptr;ptr = next;}}_tables.swap(newtables);}size_t hashi = hash(pair.first) % _tables.size();Node *newnode = new Node(pair);newnode->_next = _tables[hashi];_tables[hashi] = newnode;++_n;return true;}size_t MaxBucketSize(){size_t max = 0;for (size_t i = 0; i < _tables.size(); ++i){auto ptr = _tables[i];size_t size = 0;while (ptr){++size;ptr = ptr->_next;}if (size > max)max = size;}return max;}size_t GetNextPrime(size_t index){static const int num = 28;static const unsigned long prime[num] = {53, 97, 193, 389, 769,1543, 3079, 6151, 12289, 24593,49157, 98317, 196613, 393241, 786433,1572869, 3145739, 6291469, 12582917, 25165843,50331653, 100663319, 201326611, 402653189, 805306457,1610612741, 3221225473, 4294967291};size_t i = 0;for (i = 0; i < num; ++i){if (prime[i] > index)return prime[i];}return prime[i];}};void TestHashTable1(){int a[] = {3, 33, 2, 13, 5, 12, 1002};HashTable<int, int> ht;for (auto &e : a){ht.Insert(make_pair(e, e));}ht.Insert(make_pair(15, 15));ht.Insert(make_pair(25, 25));ht.Insert(make_pair(35, 35));ht.Insert(make_pair(45, 45));}void TestHashTable2(){int a[] = {3, 33, 2, 13, 5, 12, 1002};HashTable<int, int> ht;for (auto &e : a){ht.Insert(make_pair(e, e));}ht.Erase(12);ht.Erase(3);ht.Erase(33);}void TestHashTable3(){HashTable<string, string> ht;ht.Insert(make_pair("Kevin", "凯文"));ht.Insert(make_pair("Eddie", "彭于晏"));ht.Insert(make_pair("Tom", "汤姆"));ht.Insert(make_pair("Jerry", "杰瑞"));ht.Insert(make_pair("", "null_string"));}void TestHashTable4(){size_t N = 900000;HashTable<int, int> ht;srand(time(0));for (size_t i = 0; i < N; ++i){size_t x = rand() + i;ht.Insert(make_pair(x, x));}cout << "最大桶数据个数" << ht.MaxBucketSize() << endl;}
}
HashTable.h
#pragma once#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <array>
#include <time.h>
#include <queue>
#include <stack>
#include <string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <functional>
#include <assert.h>
using namespace std;
template <class K>
struct HashFunc
{size_t operator()(const K &key){return key;}
};
template <>
struct HashFunc<string>
{size_t operator()(const string &s){size_t value = 0;for (auto ch : s){value = value * 131 + ch;}return value;}
};
namespace ChainAddressing
{template <class T>struct HashNode{T _data;HashNode<T> *_next;HashNode(const T &data): _next(nullptr), _data(data){}};template <class K, class T, class GetKey, class Hash>class HashTable;template <class K, class T, class Ref, class Ptr, class GetKey, class Hash>struct HashIterator{typedef HashNode<T> Node;typedef HashTable<K, T, GetKey, Hash> HT;typedef HashIterator<K, T, Ref, Ptr, GetKey, Hash> Self;typedef HashIterator<K, T, T &, T *, GetKey, Hash> Iterator;Node *_node;const HT *_ht;HashIterator(Node *node, const HT *ht): _node(node), _ht(ht){}HashIterator(const Iterator &it): _node(it._node), _ht(it._ht){}Ref operator*(){return _node->_data;}Ptr operator->(){return &_node->_data;}bool operator!=(const Self &s){return _node != s._node;}Self &operator++(){if (_node->_next != nullptr){_node = _node->_next;}else{GetKey get;Hash hash;size_t hashi = hash(get(_node->_data)) % _ht->_tables.size();++hashi;while (hashi < _ht->_tables.size()){if (_ht->_tables[hashi]){_node = _ht->_tables[hashi];break;}else++hashi;}if (hashi == _ht->_tables.size())_node = nullptr;}return *this;}};template <class K, class T, class GetKey, class Hash>class HashTable{typedef HashNode<T> Node;template <class U, class V, class Ref, class Ptr, class GetKEY, class HASH>friend struct HashIterator;private:vector<Node *> _tables; size_t _n = 0; public:typedef HashIterator<K, T, T &, T *, GetKey, Hash> iterator;typedef HashIterator<K, T, const T &, const T *, GetKey, Hash> const_iterator;iterator begin(){Node *ptr = nullptr;for (size_t i = 0; i < _tables.size(); ++i){ptr = _tables[i];if (ptr)break;}return iterator(ptr, this);}iterator end(){return iterator(nullptr, this);}const_iterator begin() const{Node *ptr = nullptr;for (size_t i = 0; i < _tables.size(); ++i){ptr = _tables[i];if (ptr)break;}return const_iterator(ptr, this);}const_iterator end() const{return const_iterator(nullptr, this);}~HashTable(){for (auto &ptr : _tables){while (ptr){Node *next = ptr->_next;delete ptr;ptr = next;}ptr = nullptr;}}iterator Find(const K &key){if (_tables.size() == 0)return end();GetKey get;Hash hash;size_t hashi = hash(key) % _tables.size();Node *ptr = _tables[hashi];while (ptr){if (get(ptr->_data) == key)return iterator(ptr, this);ptr = ptr->_next;}return end();}bool Erase(const K &key){Hash hash;GetKey get;size_t hashi = hash(key) % _tables.size();Node *prv = nullptr;Node *ptr = _tables[hashi];while (ptr){if (get(ptr->_data) == key){if (prv == nullptr)_tables[hashi] = ptr->_next;elseprv->_next = ptr->_next;delete ptr;return true;}else{prv = ptr;ptr = ptr->_next;}}return false;}size_t GetNextPrime(size_t index){static const int num = 28;static const unsigned long prime[num] ={53, 97, 193, 389, 769,1543, 3079, 6151, 12289, 24593,49157, 98317, 196613, 393241, 786433,1572869, 3145739, 6291469, 12582917, 25165843,50331653, 100663319, 201326611, 402653189, 805306457,1610612741, 3221225473, 4294967291};size_t i = 0;for (i = 0; i < num; ++i){if (prime[i] > index)return prime[i];}return prime[i];}pair<iterator, bool> Insert(const T &data){GetKey get;iterator it = Find(get(data));if (it != end())return make_pair(it, false);Hash hash;if (_n == _tables.size()){size_t newsize = _tables.size() == 0 ? 10 : _tables.size() * 2;vector<Node *> newtables(newsize, nullptr);for (auto &ptr : _tables){while (ptr){size_t hashi = hash(get(ptr->_data)) % newtables.size();Node *next = ptr->_next;ptr->_next = newtables[hashi];newtables[hashi] = ptr;ptr = next;}}_tables.swap(newtables);}size_t hashi = hash(get(data)) % _tables.size();Node *newnode = new Node(data);newnode->_next = _tables[hashi];_tables[hashi] = newnode;++_n;return make_pair(iterator(newnode, this), false);}size_t MaxBucketSize(){size_t max = 0;for (size_t i = 0; i < _tables.size(); ++i){auto ptr = _tables[i];size_t size = 0;while (ptr){++size;ptr = ptr->_next;}printf("[%ld] -> %ld\n", i, size);if (size > max)max = size;}return max;}};
}
Unordered_Map.h
#pragma once
#include "HashTable.h"namespace ape
{template <class K, class V, class Hash = HashFunc<K>>class unordered_map{public:struct MapGetKey{const K &operator()(const pair<K, V> &pair){return pair.first;}};private:public:ChainAddressing::HashTable<K, pair<const K, V>, MapGetKey, Hash> _ht;public:typedef typename ChainAddressing::HashTable<K, pair<const K, V>, MapGetKey, Hash>::iterator iterator;typedef typename ChainAddressing::HashTable<K, pair<const K, V>, MapGetKey, Hash>::const_iterator const_iterator;iterator begin(){return _ht.begin();}iterator end(){return _ht.end();}const_iterator begin() const{return _ht.begin();}const_iterator end() const{return _ht.end();}pair<iterator, bool> insert(const pair<K, V> &pair){return _ht.Insert(pair);}V &operator[](const K &key){pair<iterator, bool> pair = insert(make_pair(key, V()));return pair.first->second;}iterator find(const K &key){return _ht.Find(key);}bool erase(const K &key){return _ht.Erase(key);}};void test_unordered_map1(){unordered_map<int, int> m;m.insert(make_pair(1, 1));m.insert(make_pair(3, 3));m.insert(make_pair(2, 2));unordered_map<int, int>::iterator it = m.begin();while (it != m.end()){cout << it->first << ":" << it->second << endl;++it;}cout << endl;}void test_unordered_map2(){string s[] = {"西瓜", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉", "梨"};unordered_map<string, int> um;for (auto &e : s){um[e]++;}for (auto &pair : um){cout << pair.first << ":" << pair.second << endl;}}class Date{friend struct HashDate;friend ostream &operator<<(ostream &_cout, const Date &d);public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}bool operator<(const Date &d) const{return (_year < d._year) || (_year == d._year && _month < d._month) || (_year == d._year && _month == d._month && _day < d._day);}bool operator>(const Date &d) const{return (_year > d._year) || (_year == d._year && _month > d._month) || (_year == d._year && _month == d._month && _day > d._day);}bool operator==(const Date &d) const{return _year == d._year && _month == d._month && _day == d._day;}private:int _year;int _month;int _day;};ostream &operator<<(ostream &_cout, const Date &d){_cout << d._year << "-" << d._month << "-" << d._day;return _cout;}struct HashDate{size_t operator()(const Date &d){size_t value = 0;value += d._year;value *= 131;value += d._month;value *= 131;value += d._day;value *= 131;return value;}};void test_unordered_map4(){Date d1(2023, 10, 1);Date d2(2023, 10, 5);Date d3(2023, 10, 2);Date d4(2023, 10, 2);Date d5(2023, 10, 2);Date d6(2023, 10, 1);Date a[] = {d1, d2, d3, d4, d5, d6};unordered_map<Date, int, HashDate> um;for (auto e : a){um[e]++;}for (auto &pair : um){cout << pair.first << ":" << pair.second << endl;}}void test_unordered_map5(){unordered_map<int, int> m;srand(time(NULL));for (int i = 0; i < 1000000; ++i){m.insert(make_pair(rand(), rand()));}size_t max = m._ht.MaxBucketSize();cout << max << endl;}
}
Unordered_Set.h
#pragma once
#include "HashTable.h"namespace ape
{template <class K, class Hash = HashFunc<K>>class unordered_set{public:struct SetGetKey{const K &operator()(const K &key){return key;}};private:ChainAddressing::HashTable<K, K, SetGetKey, Hash> _ht;public:typedef typename ChainAddressing::HashTable<K, K, SetGetKey, Hash>::const_iterator iterator;typedef typename ChainAddressing::HashTable<K, K, SetGetKey, Hash>::const_iterator const_iterator;iterator begin(){return _ht.begin();}iterator end(){return _ht.end();}const_iterator begin() const{return _ht.begin();}const_iterator end() const{return _ht.end();}pair<iterator, bool> insert(const K &key){return _ht.Insert(key);}iterator find(const K &key){return _ht.Find(key);}bool erase(const K &key){return _ht.Erase(key);}};void print(const unordered_set<int> &s){unordered_set<int>::const_iterator it = s.begin();while (it != s.end()){cout << *it << " ";++it;}cout << endl;}void test_unordered_set(){int a[] = {3, 33, 2, 13, 5, 12, 1002};unordered_set<int> s;for (auto e : a)s.insert(e);s.insert(54);s.insert(107);unordered_set<int>::iterator it = s.begin();while (it != s.end()){cout << *it << " ";++it;}cout << endl;for (auto e : s)cout << e << " ";cout << endl;print(s);}
}
main.cc
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <array>
#include <time.h>
#include <queue>
#include <stack>
#include <string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <functional>
#include <assert.h>
using namespace std;#include "HashTable.h"
#include "Unordered_Map.h"
#include "Unordered_Set.h"int main()
{ape::test_unordered_map5();return 0;
}