完整代码请前往GitHub—>点我啊
HashBucket.hpp
#pragma once
#include
#include"Common.hpp"
template<class T>
struct HashNode {
HashNode(const T& data = T())
:_pNext(nullptr)
,_data(data)
{}
HashNode<T>* _pNext;
T _data;
};
template<class T, class KorV, class DF = DFStr>
class HashBucket;
template<class T, class KorV,class DF = DFStr>
struct Iterator {
typedef HashNode<T> Node;
typedef Iterator<T, KorV, DF> Self;
Iterator(Node* pNode = nullptr, HashBucket<T, KorV, DF>* ht = nullptr)
:_pNode(pNode)
,_ht(ht)
{}
T& operator*() {
return _pNode->_data;
}
T* operator->() {
return &(_pNode->_data);
}
Self& operator++() {
Next();
return *this;
}
Self operator++(int) {
Self tmp(_pNode);
Next();
return tmp;
}
bool operator==(Self& t) {
return _pNode == t._pNode;
}
bool operator!=(Self& t) {
return _pNode != t._pNode;
}
void Next() {
if (_pNode->_pNext) {
_pNode = _pNode->_pNext;
}
else {
size_t addr = _ht->HashFunc(_pNode->_data);
for (int i = addr + 1; i < _ht->_arr.size(); ++i) {
if (_ht->_arr[i]) {
_pNode = _ht->_arr[i];
return;
}
}
_pNode = nullptr;
}
}
Node* _pNode;
HashBucket<T, KorV, DF>* _ht;
};
template<class T, class KorV, class DF>
class HashBucket {
public:
typedef HashNode<T> Node;
typedef HashBucket<T, KorV, DF> Self;
typedef Iterator<T, KorV, DF> iterator;
friend struct Iterator<T, KorV, DF>;
public:
HashBucket(size_t size = 11)
:_size(0)
{
_arr.resize(size);
}
~HashBucket() {
Clear();
}
std::pair<iterator, bool> Insert(const T& data) {
CheckCapacity();
size_t addr = HashFunc(data);
//查找是否有重复节点
Node* ptr = _arr[addr];
while (ptr) {
if (KorV()(ptr->_data) == KorV()(data))
return make_pair(iterator(ptr, this), false);
ptr = ptr->_pNext;
}
ptr = new Node(data);
ptr->_pNext = _arr[addr];
_arr[addr] = ptr;
++_size;
return make_pair(iterator(ptr, this), true);
}
size_t Erase(const T& data) {
size_t addr = HashFunc(data);
Node* ptr = _arr[addr];
Node* pre = nullptr;
while (ptr) {
if (ptr->_data == data) {
if (!pre) //删除头结点
_arr[addr] = ptr->_pNext;
else //删除中间节点
pre->_pNext = ptr->_pNext;
delete ptr;
--_size;
return 1;
}
else {
pre = ptr;
ptr = ptr->_pNext;
}
}
return 0;
}
iterator find(const T& data) const{
size_t addr = HashFunc(data);
Node* ptr = _arr[addr];
while (ptr) {
if (KorV()(ptr->_data) == KorV()(data))
return iterator(ptr, this);
ptr = ptr->_pNext;
}
return iterator(nullptr, this);
}
size_t size() const{
return _size;
}
bool empty()const {
return _size == 0;
}
iterator begin() {
for (int i = 0; i < _arr.size(); ++i) {
if (_arr[i]) {
return iterator(_arr[i], this);
}
}
return iterator(nullptr, this);
}
iterator end() {
return iterator(nullptr, this);
}
void Clear() {
for (size_t i = 0; i < _arr.size(); ++i) {
Node* ptr = _arr[i];
while (ptr) {
_arr[i] = ptr->_pNext;
delete ptr;
ptr = _arr[i];
}
}
_size = 0;
}
size_t bucket_count() const{
return _arr.size();
}
size_t bucket_size(size_t n) const{
if (n >= _arr.size())
return 0;
size_t count = 0;
Node* ptr = _arr[n];
while (ptr) {
++count;
ptr = ptr->_pNext;
}
return count;
}
size_t bucket(const T& data) {
return HashFunc(data);
}
void Swap(Self& t) {
_arr.swap(t._arr);
std::swap(_size, t._size);
}
private:
void CheckCapacity() { //扩容
if (_size == _arr.size()) {
size_t newSize = GetNextPrime(_arr.size());
Self newBucket(newSize);
for (size_t i = 0; i < _arr.size(); ++i) {
Node* ptr = _arr[i];
while (ptr) {
size_t addr = newBucket.HashFunc(ptr->_data);
_arr[i] = ptr->_pNext;
ptr->_pNext = newBucket._arr[addr];
newBucket._arr[addr] = ptr;
++newBucket._size;
ptr = _arr[i];
}
}
Swap(newBucket);
}
}
size_t HashFunc(const T data) const{
return DF()(KorV()(data)) % _arr.size();
}
private:
std::vector<Node*> _arr;
size_t _size;
};
Unordered_map.hpp
#pragma once
#include"HashBucket.hpp"
template<class K,class V>
class Unordered_map {
typedef std::pair<K, V> ValueType;
typename typedef HashBucket<ValueType, KORV>::iterator iterator;
struct KORV
{
const K& operator()(const ValueType& data)const {
return data.first;
}
};
public:
Unordered_map(size_t size = 11)
:_ht(size)
{}
iterator begin(){
return _ht.begin();
}
iterator end(){
return _ht.end();
}
bool empty()const {
return _ht.empty();
}
size_t size()const {
return _ht.size();
}
std::pair<iterator,bool> insert(const ValueType& data){
return _ht.Insert(data);
}
size_t erase(const K& key){
return _ht.Erase(ValueType(key,V()));
}
iterator find(const K& key) const{
return _ht.find(ValueType(key, V()));
}
void clear() {
_ht.Clear();
}
void swap(const Unordered_map<K,V>& m) {
_ht.Swap(m._ht);
}
V& operator[](const K& k) {
return (*(insert(ValueType(k, V())).first)).second;
}
size_t buck_count()const {
return _ht.bucket_count();
}
size_t buck_size(size_t n)const {
return _ht.bucket_size(n);
}
size_t bucket(const K& k) {
return _ht.bucket(ValueType(k, V()));
}
private:
HashBucket<ValueType, KORV> _ht;
};
Unordered_set.hpp
#pragma once
#include"HashBucket.hpp"
template<class K>
class Unordered_set {
typedef K ValueType;
typename typedef HashBucket<ValueType, KORV>::iterator iterator;
struct KORV
{
const ValueType& operator()(const ValueType& data)const {
return data;
}
};
public:
Unordered_set(size_t size = 11)
:_ht(size)
{}
iterator begin() {
return _ht.begin();
}
iterator end() {
return _ht.end();
}
bool empty()const {
return _ht.empty();
}
size_t size()const {
return _ht.size();
}
std::pair<iterator, bool> insert(const ValueType& data) {
return _ht.Insert(data);
}
size_t erase(const ValueType& key) {
return _ht.Erase(key);
}
iterator find(const ValueType& key) const {
return _ht.find(key);
}
void clear() {
_ht.Clear();
}
void swap(const Unordered_set<K>& m) {
_ht.Swap(m._ht);
}
size_t buck_count()const {
return _ht.bucket_count();
}
size_t buck_size(size_t n)const {
return _ht.bucket_size(n);
}
size_t bucket(const ValueType& k) {
return _ht.bucket(k);
}
private:
HashBucket<ValueType, KORV> _ht;
};