赞
踩
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.哈希表的实现
闭散列的实现:
- #include <iostream>
- #include <vector>
- #include <string>
- //usng namespace std;
- using std::cout;
- using std:: endl;
- using std::cin;
- //闭散列
- namespace open_address
- {
- //处理不是整形的字符
- template<class T>
- struct DefaultHashFunc
- {
- size_t operator()(const T& t)
- {
- return size_t(value(t));
-
- }
- };
- //特殊化处理字符串
- template<>
- struct DefaultHashFunc<string>
- {
- const size_t operator()(const string& t)
- {
- //KeyofT value;
- size_t num=1;
- for (auto e : t)
- {
- num *= 131;
- num +=e;
- }
- return num;
-
- }
- };
- //枚举三种状态
- enum State
- {
- Empty,
- Exist,
- Delete
- };
- //哈希节点
- template<class T>
- struct HashDateNode
- {
- private:
- T _kv;
- State _state=Empty;
- };
- //哈希表
- template<class K, class T,class KeyofT,class DefaultHashFunc>
- class HashTable
- {
- typedef HashDateNode<T> Node;
- HashTable()//初始化,开辟10个空间
- {
- _Date.resize(10);
- }
- //插入数值
- bool insert(const T& Date)
- {
-
- DefaultHashFunc Func;//处理字符串问题
- KeyofT value;//处理set和map的数值问题函数
- //扩容
- if (n * 10 > _Date.size() * 7)//负载因子
- {
- int newsize = _Date.size() * 2;
- vector<Node*> newHT;
- newHT.resize(newsize);//开辟空间
- for (int i = 0; i < _Date.size(); i++)
- {
- if (_Date._state == Exist)//讲旧数据写入新空间中
- {
- newHT.insert(KetofT(_Date));
- }
- _Date.swap(newHT._Date);//交换数据
- }
- }
- //插入哈希表
- size_t hashi =Func(value(Date))% _Date.size();
- while (_Date[hashi]._state == Exist)//存在就++
- {
- ++hashi;
- hashi %= _Date.size();
- }
- _Date[hashi]._kv = Date;
- _Date[hashi]._state = Exist;
- n++;//存放个数加一
- return true;
- }
- //查找函数
- vector<Node*> Find(const K& t)
- {
-
- DefaultHashFunc Func;
- KeyofT value;
- size_t hashi = Func(value(t)) % _Date.size();
- while (_Date[hashi]._state != Empty)
- {
- if (_Date[hashi]._state == Exist
- && value(_Date[hashi]) == t)
- {
- return _Date[hashi];
- }
-
- ++hashi;
- hashi %= _Date.size();
- }
-
- return nullptr;
-
- }
- //删除
- bool erash(const K& key)
- {
-
- vector<Node*> ret = Find(key);//查找是否存在
- if (ret)
- {
- ret._state= Exist;
- n--;
- return true;
- }
- return false;
- }
-
- private:
- vector<Node*> _Date;//数据
- size_t n;//存储有效个数
- };
- }
开散列的实现
- #include <iostream>
- #include <string>
- #include <vector>
- using namespace std;
- //处理字符
- template<class T>
- struct DefaultHashFunc
- {
- size_t operator()(const T& t)
- {
- return size_t(t);
- }
- };template<>
- struct DefaultHashFunc<string>
- {
- size_t operator()(const string& t)
- {
- size_t num = 0;
- for (auto e : t)
- {
- num *= 131;
- num += e;
- }
- return num;
- }
- };
- //哈希桶,闭散列
- namespace hash_bucket
- {
- template<class T>
- struct HashDateNode
- {
- T _Date;
- HashDateNode<T>* _next;
-
- HashDateNode(const T& Date)
- :_Date(Date)
- ,_next(nullptr)
- {}
- };
-
- template<class K, class T, class KeyofT, class HashFunc>
- class HashDate;//前置声明
-
- //迭代器
- //template<class K,class T,class KeyofT ,class HashFunc>//旧版
- template<class K, class T, class Ptr, class Ref, class KeyofT, class HashFunc>//新版
- struct HashIterator
- {
- typedef HashDateNode<T> Node;
-
- typedef HashIterator<K,T, Ptr, Ref,KeyofT, HashFunc> Self;
- typedef HashIterator<K, T, T*, T&, KeyofT, HashFunc> iterator;
-
- Node* _node;
- const HashDate<K, T, KeyofT, HashFunc>* _pht; //设置位const ,防止普通类型无法转化为const类型
-
- //初始化
- /*const HashIterator(Node* node, HashDate<K, T, KeyofT, HashFunc>* pht)
- :_node(node)
- , _pht(pht)
- {}*/
-
- //const初始化
- HashIterator(Node* node, const HashDate<K, T, KeyofT, HashFunc>* pht)
- :_node(node)
- , _pht(pht)
- {}
-
-
- // 普通迭代器时,他是拷贝构造
- // const迭代器时,他是构造函数
- HashIterator(const iterator& it)//防止set类型的const类型与非const类型的转换(模板不同)
- :_node(it._node)
- , _pht(it._pht)
- {}
-
-
- Ref operator*()
- {
- return _node->_Date;
- }
- Ptr operator->()
- {
- return &_node->_Date;
- }
- bool operator!=(const Self& s)
- {
- return _node != s._node;
- }
- bool operator==(const Self& s)
- {
- return _node == s._node;
- }
- Self& operator++()
- {
- if (_node->_next)
- {
- _node = _node->_next;
- }
- else
- {
- HashFunc Func;
- KeyofT value;
- size_t hashi = Func(value(_node->_Date)) % _pht->_table.size(); //该用仿函数
- //从下一个哈希桶查找
- hashi++;
- while (hashi < _pht->_table.size())
- {
- if (_pht->_table[hashi])//不为空
- {
- _node = _pht->_table[hashi];
- return *this;
- }
- else//为空
- {
- ++hashi;
- }
- }
- _node = nullptr;
- }
- return *this;
- }
-
- };
-
- template<class K, class T, class KeyofT, class HashFunc = DefaultHashFunc<K>>
- class HashDate
- {
- typedef HashDateNode<T> Node;
-
- //
- //友元
- template<class K, class T, class Ptr, class Ref, class KeyofT, class HashFunc>
- friend struct HashIterator;//可以使用迭代器
-
- public:
- typedef HashIterator<K, T, T*, T&, KeyofT, HashFunc> iterator;
- typedef HashIterator<K, T, const T*, const T&, KeyofT, HashFunc> const_iterator;
-
- iterator begin()
- {
- for (size_t i = 0; i < _table.size(); i++)
- {
- Node* cur = _table[i];
- if (cur)
- {
- return iterator(cur,this);
- }
- }
-
- return iterator(nullptr, this);
- }
-
- const_iterator begin() const
- {
- for (size_t i = 0; i < _table.size(); i++)
- {
- Node* cur = _table[i];
- if (cur)
- {
- return iterator(cur, this);
- }
- }
-
- return iterator(nullptr, this);
- }
-
- iterator end()
- {
- return iterator(nullptr, this);
- }
-
-
- const_iterator end() const
- {
- return iterator(nullptr, this);
- }
- HashDate()
- {
- _table.resize(10, nullptr);
- }
-
- ~HashDate()
- {
- for (size_t i = 0; i < _table.size(); i++)
- {
- Node* cur = _table[i];
- while (cur)
- {
- Node* next = cur->_next;
- delete cur;
- cur = next;
- }
-
- _table[i] = nullptr;
- }
- }
-
- pair<iterator,bool> Insert(const T& date)
- {
-
- KeyofT value;
- HashFunc Func;
- iterator it = Find(value(date));
- //it!=end()
- if(it != end())
- {
- return make_pair(it,false);
- }
-
- if (n == _table.size())//扩容
- {
- int newsize = _table.size() * 2;
- vector<Node*> newHash;
- newHash.resize(newsize);
- for (size_t i = 0; i < _table.size(); i++)//旧数据
- {
- Node* cur = _table[i];
- while (cur)
- {
- Node* next = cur->_next;
- size_t hashi = Func(value(cur->_Date))% newsize;
- cur->_next = newHash[hashi];
- newHash[hashi] = cur;
- cur = next;
- }
- _table[i] = nullptr;
- }
- _table.swap(newHash);//交换数据
- }
- //插入
- size_t hashi = Func(value(date))% _table.size();//改变
- //Node* cur = _table[hashi];
- //尾插
- //Node* newNode = new Node(date);
- //while (cur)
- //{
- // cur = cur->_next;
- //}
- //cur = newNode;
- //头插
- Node* newNode = new Node(date);//新节点
- newNode->_next = _table[hashi];//头结点
- _table[hashi] = newNode;//尾节点
-
- n++;
- return make_pair(iterator(newNode,this),true);
- }
-
-
- //查找
- iterator Find(const K& key)//Find为K类型的只用一个数值,T类型的在map中为pair<K,T>类型
- {
- HashFunc Func;
- KeyofT value;
- size_t hashi = Func(key) % _table.size();
- //size_t hashi = Func(value(key)) % _table.size();//不能使用这个
- Node* cur = _table[hashi];
- while (cur)
- {
- if (value(cur->_Date) == key)//?
- {
- return iterator(cur,this);
- }
- cur = cur->_next;
- }
- return iterator(nullptr,this);
- }
-
- //删除
- bool Erase(const K& key)
- {
- HashFunc Func;
- KeyofT value;
- iterator ret=Find(key);
- if (ret == end())
- return true;
- size_t x = Func(value(key))% _table.size();
- Node* cur = _table[x];
- Node* prev = nullptr;
- while (cur)
- {
- if (value(cur->_Date) == key)
- {
- if (prev == nullptr)
- {
- _table[x] = cur->_next;
- }
- else
- {
- prev->_next = cur->_next;
- }
-
- }
- prev = cur;
- cur = cur->_next;
- delete cur;
- return true;
- }
- return false;
- }
- //打印
- void Print()
- {
- for (int i = 10; i < _table.size(); i++)
- {
- Node* cur = _table[i];
- while (cur)
- {
- std::cout << cur->_Date.first<<" " << cur->_Date.second <<" " << std::endl;
- cur = cur->_next;
- }
- }
- std::cout << std::endl;
- }
-
- private:
- vector<Node*> _table; //存储数据
- size_t n=0; //记录容器中的个数
- };
- }
4.Unorderset和Unordermap的实现
4.1 Unorderset
- #pragma once
- #include "HashTable.h"
- using namespace hash_bucket;
- //using namespace open_address;
-
-
- template<class K>
- class Unorderset
- {
- struct SetKeyofT
- {
- const K& operator()(const K& k)
- {
- return k;
- }
- };
- public:
- typedef typename hash_bucket::HashDate<K, K, SetKeyofT>::const_iterator iterator;
- typedef typename hash_bucket::HashDate<K, K, SetKeyofT>::const_iterator const_iterator;
-
- //typedef typename hash_bucket::HashDate<K, K, SetKeyofT> Hash;
- public:
- const_iterator begin() const
- {
- return _ht.begin();
- }
- const_iterator end() const
- {
- return _ht.end();
- }
- pair<iterator, bool> insert(const K& k)
- {
- return _ht.Insert(k);
- }
- iterator find(const K& kk)
- {
- return _ht.Find(kk);
- }
- bool erase(const K& kk)
- {
- return _ht.Erase(kk);
- }
- private:
- HashDate<K, K, SetKeyofT> _ht;
- };
4.2 Unordermap
- #pragma once
- #include "HashTable.h"
- using namespace hash_bucket;
- template<class K,class T>
- class Unordermap
- {
- struct MapkeyofT
- {
- const K& operator()(const pair<const K, T>& kt)
- {
- return kt.first;
- }
- };
- public:
- typedef typename hash_bucket::HashDate<K, pair<const K, T>, MapkeyofT>::iterator iterator;//普通迭代器
- typedef typename hash_bucket::HashDate<K, pair<const K, T>, MapkeyofT>::const_iterator const_iterator;//const迭代器
- //typedef typename hash_bucket::HashDate<K, pair<K, T>, MapkeyofT> Hash;
- 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,T>& kt)
- {
- return _ht.Insert(kt);
- }
- //查找
- iterator find(const K& kk)
- {
- return _ht.Find(kk);
- }
- //重载[]
- T& operator[](const K& kk)
- {
- pair<iterator, bool> ret = insert(make_pair(kk, T()));
- return ret.first->second;
- }
- //删除
- bool eraser(const K& kk)
- {
- return _ht.Erase(kk);
- }
- private:
- HashDate<K, pair<const K, T>, MapkeyofT> _ht;
- };
4.3 完整代码
Ps:具体实现中建议分开写
- #pragma once
- #include "HashTable.h"
- using namespace hash_bucket;
- using namespace open_address;
-
- //set实现
- template<class K>
- class Unorderset
- {
- struct SetKeyofT
- {
- const K& operator()(const K& k)
- {
- return k;
- }
- };
- public:
- typedef typename hash_bucket::HashDate<K, K, SetKeyofT>::const_iterator iterator;
- typedef typename hash_bucket::HashDate<K, K, SetKeyofT>::const_iterator const_iterator;
-
- //typedef typename hash_bucket::HashDate<K, K, SetKeyofT> Hash;
- public:
- const_iterator begin() const
- {
- return _ht.begin();
- }
- const_iterator end() const
- {
- return _ht.end();
- }
- pair<iterator, bool> insert(const K& k)
- {
- return _ht.Insert(k);
- }
- iterator find(const K& kk)
- {
- return _ht.Find(kk);
- }
- bool erase(const K& kk)
- {
- return _ht.Erase(kk);
- }
- private:
- HashDate<K, K, SetKeyofT> _ht;
- };
-
- //map实现
- template<class K,class T>
- class Unordermap
- {
- struct MapkeyofT
- {
- const K& operator()(const pair<const K, T>& kt)
- {
- return kt.first;
- }
- };
- public:
- typedef typename hash_bucket::HashDate<K, pair<const K, T>, MapkeyofT>::iterator iterator;//普通迭代器
- typedef typename hash_bucket::HashDate<K, pair<const K, T>, MapkeyofT>::const_iterator const_iterator;//const迭代器
- //typedef typename hash_bucket::HashDate<K, pair<K, T>, MapkeyofT> Hash;
- 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,T>& kt)
- {
- return _ht.Insert(kt);
- }
- //查找
- iterator find(const K& kk)
- {
- return _ht.Find(kk);
- }
- //重载[]
- T& operator[](const K& kk)
- {
- pair<iterator, bool> ret = insert(make_pair(kk, T()));
- return ret.first->second;
- }
- //删除
- bool eraser(const K& kk)
- {
- return _ht.Erase(kk);
- }
- private:
- HashDate<K, pair<const K, T>, MapkeyofT> _ht;
- };
- //底层实现
- #pragma once//防止头文件重复引用
- #include <iostream>
- #include <vector>
- #include <string>
- using namespace std;
-
-
- //处理不是整形的字符
- template<class T>
- struct DefaultHashFunc
- {
- size_t operator()(const T& t)
- {
- return size_t(value(t));
-
- }
- };
- //特殊化处理字符串
- template<>
- struct DefaultHashFunc<string>
- {
- const size_t operator()(const string& t)
- {
- //KeyofT value;
- size_t num=1;
- for (auto e : t)
- {
- num *= 131;
- num +=e;
- }
- return num;
-
- }
- };
- //开散列
- namespace open_address
- {
-
- //枚举三种状态
- enum State
- {
- Empty,
- Exist,
- Delete
- };
- //哈希节点
- template<class T>
- struct HashDateNode
- {
- private:
- T _kv;
- State _state=Empty;
- };
- //哈希表
- template<class K, class T,class KeyofT,class DefaultHashFunc>
- class HashTable
- {
- typedef HashDateNode<T> Node;
- HashTable()//初始化,开辟10个空间
- {
- _Date.resize(10);
- }
- //插入数值
- bool insert(const T& Date)
- {
-
- DefaultHashFunc Func;//处理字符串问题
- KeyofT value;//处理set和map的数值问题函数
- //扩容
- if (n * 10 > _Date.size() * 7)//负载因子
- {
- int newsize = _Date.size() * 2;
- vector<Node*> newHT;
- newHT.resize(newsize);//开辟空间
- for (int i = 0; i < _Date.size(); i++)
- {
- if (_Date._state == Exist)//讲旧数据写入新空间中
- {
- newHT.insert(KetofT(_Date));
- }
- _Date.swap(newHT._Date);//交换数据
- }
- }
- //插入哈希表
- size_t hashi =Func(value(Date))% _Date.size();
- while (_Date[hashi]._state == Exist)//存在就++
- {
- ++hashi;
- hashi %= _Date.size();
- }
- _Date[hashi]._kv = Date;
- _Date[hashi]._state = Exist;
- n++;//存放个数加一
- return true;
- }
- //查找函数
- vector<Node*> Find(const K& t)
- {
-
- DefaultHashFunc Func;
- KeyofT value;
- size_t hashi = Func(value(t)) % _Date.size();
- while (_Date[hashi]._state != Empty)
- {
- if (_Date[hashi]._state == Exist
- && value(_Date[hashi]) == t)
- {
- return _Date[hashi];
- }
-
- ++hashi;
- hashi %= _Date.size();
- }
-
- return nullptr;
-
- }
- //删除
- bool erash(const K& key)
- {
-
- vector<Node*> ret = Find(key);//查找是否存在
- if (ret)
- {
- ret._state= Exist;
- n--;
- return true;
- }
- return false;
- }
-
- private:
- vector<Node*> _Date;//数据
- size_t n;//存储有效个数
- };
- }
-
- //哈希桶,闭散列
- namespace hash_bucket
- {
- template<class T>
- struct HashDateNode
- {
- T _Date;
- HashDateNode<T>* _next;
-
- HashDateNode(const T& Date)
- :_Date(Date)
- ,_next(nullptr)
- {}
- };
-
- template<class K, class T, class KeyofT, class HashFunc>
- class HashDate;//前置声明
-
- //迭代器
- //template<class K,class T,class KeyofT ,class HashFunc>//旧版
- template<class K, class T, class Ptr, class Ref, class KeyofT, class HashFunc>//新版
- struct HashIterator
- {
- typedef HashDateNode<T> Node;
-
- typedef HashIterator<K,T, Ptr, Ref,KeyofT, HashFunc> Self;
- typedef HashIterator<K, T, T*, T&, KeyofT, HashFunc> iterator;
-
- Node* _node;
- const HashDate<K, T, KeyofT, HashFunc>* _pht; //设置位const ,防止普通类型无法转化为const类型
-
- //初始化
- /*const HashIterator(Node* node, HashDate<K, T, KeyofT, HashFunc>* pht)
- :_node(node)
- , _pht(pht)
- {}*/
-
- //const初始化
- HashIterator(Node* node, const HashDate<K, T, KeyofT, HashFunc>* pht)
- :_node(node)
- , _pht(pht)
- {}
-
-
- // 普通迭代器时,他是拷贝构造
- // const迭代器时,他是构造函数
- HashIterator(const iterator& it)//防止set类型的const类型与非const类型的转换(模板不同)
- :_node(it._node)
- , _pht(it._pht)
- {}
-
-
- Ref operator*()
- {
- return _node->_Date;
- }
- Ptr operator->()
- {
- return &_node->_Date;
- }
- bool operator!=(const Self& s)
- {
- return _node != s._node;
- }
- bool operator==(const Self& s)
- {
- return _node == s._node;
- }
- Self& operator++()
- {
- if (_node->_next)
- {
- _node = _node->_next;
- }
- else
- {
- HashFunc Func;
- KeyofT value;
- size_t hashi = Func(value(_node->_Date)) % _pht->_table.size(); //该用仿函数
- //从下一个哈希桶查找
- hashi++;
- while (hashi < _pht->_table.size())
- {
- if (_pht->_table[hashi])//不为空
- {
- _node = _pht->_table[hashi];
- return *this;
- }
- else//为空
- {
- ++hashi;
- }
- }
- _node = nullptr;
- }
- return *this;
- }
-
- };
-
- template<class K, class T, class KeyofT, class HashFunc = DefaultHashFunc<K>>
- class HashDate
- {
- typedef HashDateNode<T> Node;
-
- //
- //友元
- template<class K, class T, class Ptr, class Ref, class KeyofT, class HashFunc>
- friend struct HashIterator;//可以使用迭代器
-
- public:
- typedef HashIterator<K, T, T*, T&, KeyofT, HashFunc> iterator;
- typedef HashIterator<K, T, const T*, const T&, KeyofT, HashFunc> const_iterator;
-
- iterator begin()
- {
- for (size_t i = 0; i < _table.size(); i++)
- {
- Node* cur = _table[i];
- if (cur)
- {
- return iterator(cur,this);
- }
- }
-
- return iterator(nullptr, this);
- }
-
- const_iterator begin() const
- {
- for (size_t i = 0; i < _table.size(); i++)
- {
- Node* cur = _table[i];
- if (cur)
- {
- return iterator(cur, this);
- }
- }
-
- return iterator(nullptr, this);
- }
-
- iterator end()
- {
- return iterator(nullptr, this);
- }
-
-
- const_iterator end() const
- {
- return iterator(nullptr, this);
- }
- HashDate()
- {
- _table.resize(10, nullptr);
- }
-
- ~HashDate()
- {
- for (size_t i = 0; i < _table.size(); i++)
- {
- Node* cur = _table[i];
- while (cur)
- {
- Node* next = cur->_next;
- delete cur;
- cur = next;
- }
-
- _table[i] = nullptr;
- }
- }
-
- pair<iterator,bool> Insert(const T& date)
- {
-
- KeyofT value;
- HashFunc Func;
- iterator it = Find(value(date));
- //it!=end()
- if(it != end())
- {
- return make_pair(it,false);
- }
-
- if (n == _table.size())//扩容
- {
- int newsize = _table.size() * 2;
- vector<Node*> newHash;
- newHash.resize(newsize);
- for (size_t i = 0; i < _table.size(); i++)//旧数据
- {
- Node* cur = _table[i];
- while (cur)
- {
- Node* next = cur->_next;
- size_t hashi = Func(value(cur->_Date))% newsize;
- cur->_next = newHash[hashi];
- newHash[hashi] = cur;
- cur = next;
- }
- _table[i] = nullptr;
- }
- _table.swap(newHash);//交换数据
- }
- //插入
- size_t hashi = Func(value(date))% _table.size();//改变
- //Node* cur = _table[hashi];
- //尾插
- //Node* newNode = new Node(date);
- //while (cur)
- //{
- // cur = cur->_next;
- //}
- //cur = newNode;
- //头插
- Node* newNode = new Node(date);//新节点
- newNode->_next = _table[hashi];//头结点
- _table[hashi] = newNode;//尾节点
-
- n++;
- return make_pair(iterator(newNode,this),true);
- }
-
-
- //查找
- iterator Find(const K& key)//Find为K类型的只用一个数值,T类型的在map中为pair<K,T>类型
- {
- HashFunc Func;
- KeyofT value;
- size_t hashi = Func(key) % _table.size();
- //size_t hashi = Func(value(key)) % _table.size();//不能使用这个
- Node* cur = _table[hashi];
- while (cur)
- {
- if (value(cur->_Date) == key)//?
- {
- return iterator(cur,this);
- }
- cur = cur->_next;
- }
- return iterator(nullptr,this);
- }
-
- //删除
- bool Erase(const K& key)
- {
- HashFunc Func;
- KeyofT value;
- iterator ret=Find(key);
- if (ret == end())
- return true;
- size_t x = Func(value(key))% _table.size();
- Node* cur = _table[x];
- Node* prev = nullptr;
- while (cur)
- {
- if (value(cur->_Date) == key)
- {
- if (prev == nullptr)
- {
- _table[x] = cur->_next;
- }
- else
- {
- prev->_next = cur->_next;
- }
-
- }
- prev = cur;
- cur = cur->_next;
- delete cur;
- return true;
- }
- return false;
- }
- //打印
- void Print()
- {
- for (int i = 10; i < _table.size(); i++)
- {
- Node* cur = _table[i];
- while (cur)
- {
- std::cout << cur->_Date.first<<" " << cur->_Date.second <<" " << std::endl;
- cur = cur->_next;
- }
- }
- std::cout << std::endl;
- }
-
- private:
- vector<Node*> _table; //存储数据
- size_t n=0; //记录容器中的个数
- };
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。