哈希桶
#include
#include
using namespace std;
template<class V>
struct HashNode{
V _val;
HashNode<V>* _next;
HashNode(const V& val)
:_val(val)
, _next(nullptr)
{
}
};
template<class K, class V, class KeyOfValue, class HashFun=HashFun<K>>
class HashTable;
template<class K, class V, class KeyOfValue, class HashFun = HashFun<K>>
struct Hashiterator{
typedef Hashiterator<K, V, KeyOfValue, HashFun> Self;
typedef HashTable<K, V, KeyOfValue, HashFun> HT;
typedef HashNode<V> Node;
Node* _node;
HT* _hptr;
Hashiterator(Node* node, HT* hptr)
:_node(node)
, _hptr(hptr)
{
}
V& operator*(){
return _node->_val;
}
V* operator->(){
return &_node->_val;
}
bool operator!=(const Self& it){
return _node != it._node;
}
Self& operator++(){
if (_node->_next){
_node = _node->_next;
}
else{
KeyOfValue kov;
HashFun hfun;
size_t idx = hfun(kov(_node->_val)) % _hptr->_ht.size();
++idx;
for (; idx < _hptr->_ht.size(); ++idx){
if (_hptr->_ht[idx]){
_node = _hptr->_ht[idx];
break;
}
}
if (idx == _hptr->_ht.size()){
_node = nullptr;
}
}
return *this;
}
};
template<class K,class V,class KeyOfValue,class HashFun>
class HashTable{
public:
typedef HashNode<V> Node;
typedef Hashiterator<K, V, KeyOfValue, HashFun> iterator;
template<class K, class V, class KeyOfValue, class HashFun>
friend struct Hashiterator;
HashTable(int n = 10)
:_ht(n)
, _size(0)
{
}
iterator begin(){
for (size_t i = 0; i < _ht.size(); ++i){
if (_ht[i]){
return iterator(_ht[i], this);
}
}
return iterator(nullptr, this);
}
iterator end(){
return iterator(nullptr, this);
}
pair<iterator, bool> insert(const V& val){
checkCapacity();
KeyOfValue kov;
HashFun hfun;
int idx = hfun(kov(val)) % _ht.size();
Node* cur = _ht[idx];
while (cur){
if (kov(cur->_val) == kov(val)){
return make_pair(iterator(cur, this), false);
}
cur = cur->_next;
}
cur = new Node(val);
cur->_next = _ht[idx];
_ht[idx] = cur;
++_size;
return make_pair(iterator(cur, this), true);
}
size_t GetNextPrime(size_t prime)
{
const int PRIMECOUNT = 28;
const size_t primeList[PRIMECOUNT] =
{
53ul, 97ul, 193ul, 389ul, 769ul,
1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
1610612741ul, 3221225473ul, 4294967291ul
};
size_t i = 0;
for (; i < PRIMECOUNT; ++i)
{
if (primeList[i] > primeList[i])
return primeList[i];
}
return primeList[i];
}
void checkCapacity(){
if (_size == _ht.size()){
int newc = _size == 0 ? 10 : 2 * _size;
vector<Node*> newht(newc);
KeyOfValue kov;
HashFun hfun;
for (size_t i = 0; i < _ht.size(); ++i){
Node* cur = _ht[i];
while (cur){
Node* next = cur->_next;
int idx = hfun(kov(cur->_val)) % newht.size();
cur->_next = newht[idx];
newht[idx] = cur;
cur=next;
}
_ht[i] = nullptr;
}
swap(_ht, newht);
}
}
Node* Find(const K& key){
KeyOfValue kov;
HashFun hfun;
int idx = key % _ht.size();
Node* cur = _ht[idx];
while (cur){
if hfun((kov(cur->_val)) == key){
return cur;
}
cur = cur->_next;
}
return nullptr;
}
bool Erase(const K& key){
KeyOfValue kov;
HashFun hfun;
int idx = key % _ht.size();
Node* cur = _ht[idx];
if (!cur){
return false;
}
else if (cur->_next == nullptr){
delete cur;
_ht[idx] = nullptr;
return true;
}
else{
Node* prev = cur;
cur = cur->_next;
while (cur){
if (hfun(kov(cur->_val)) == key){
Node* tmp = cur;
cur = cur->_next;
prev->_next = tmp->_next;
return true;
}
}
}
return false;
}
private:
vector<Node*> _ht;
int _size;
};
template <class K>
struct Hashfun{
size_t operator()(const K& key){
return key;
}
};
struct Hashfunstring
{
size_t operator()(const string& key){
size_t hash = 0;
for (const auto& ch : key){
hash = hash * 131 + ch;
}
return hash;
}
};
template<>
struct Hashfun<string>
{
size_t operator()(const string& key){
size_t hash = 0;
for (const auto& ch : key){
hash = hash * 131 + ch;
}
return hash;
}
};
class A{
public:
int _a;
string _b;
double _d;
bool operator==(const A& a){
return _a == a._a && _b == a._b && _d == a._d;
}
};
struct HashfunA{
size_t operator()(const A& a){
return a._a ;
}
};
template <class K>
struct HashFun
{
size_t operator()(const K& key){
return key;
}
};
map和set
template <class K,class V>
class Map{
struct MapKeyOfValue
{
const K& operator()(const pair<K, V>& val){
return val.first;
}
};
public:
typedef typename HashTable<K, pair<K, V>, MapKeyOfValue>::iterator iterator;
pair<iterator, bool> insert(const pair<K, V>& val){
return _ht.insert(val);
}
iterator begin(){
return _ht.begin();
}
iterator end(){
return _ht.end();
}
V& operator[](const K& key){
pair<iterator, bool> ret = _ht.insert(make_pair(key, V()));
return ret.first->second;
}
bool earse(const K& key){
return _ht.Erase(key);
}
private:
HashTable<K, pair<K, V>, MapKeyOfValue> _ht;
};
template <class K>
class Set{
struct SetKeyOfValue
{
const K& operator()(const K& val){
return val;
}
};
public:
typedef typename HashTable<K, K, SetKeyOfValue>::iterator iterator;
pair<iterator, bool> insert(const K& val){
return _ht.insert(val);
}
iterator begin(){
return _ht.begin();
}
iterator end(){
return _ht.end();
}
bool earse(const K& val){
return _ht.Erase(val);
}
private:
HashTable<K, K, SetKeyOfValue> _ht;
};
void test(){
Map<int, int> s;
s.insert(make_pair(1, 1));
s[1] = 5;
s[5] = 10;
s[15] = 15;
s[4] = 4;
s.earse(1);
for (auto& e : s){
cout << e.first << " " << e.second << endl;
}
}
int main(){
test();
system("pause");
return 0;
}
线性探测
#include
#include
using namespace std;
enum STATE
{
EXIST,
DELETE,
EMPTY
};
template<class K, class V>
struct HashNode
{
pair<K, V> _kv;
STATE _state = EMPTY;
};
template<class K, class V>
class HashTable
{
public:
typedef HashNode<K, V> Node;
HashTable(size_t n = 10)
:_hTable(n)
, _size(0)
{
}
bool insert(const pair<K, V>& kv)
{
Checkcapacity();
int idx = kv.first % _hTable.size();
while (_hTable[idx]._state != EMPTY)
{
if (_hTable[idx]._state == EXIST&&kv.first == _hTable[idx]._kv.first)
{
return false;
}
++idx;
if (idx == _hTable.size())
{
idx = 0;
}
}
_hTable[idx]._kv = kv;
_hTable[idx]._state = EXIST;
++_size;
return true;
}
void Checkcapacity(){
if (_hTable.size() == 0 || _size * 10 / _hTable.size() > 7){
int newc = _hTable.size() == 0 ? 10 : 2 * _hTable.size();
HashTable<K, V> newht(newc);
for (size_t i = 0; i < _hTable.size(); ++i){
if (_hTable[i]._state == EXIST){
newht.insert(_hTable[i]._kv);
}
}
Swap(newht);
}
}
void Swap(HashTable<K, V> h){
swap(_hTable, h._hTable);
}
Node* find(const K& key){
int idx = key % _hTable.size();
while (_hTable[idx]._state != EMPTY)
{
if (_hTable[idx]._state == EXIST&&key == _hTable[idx]._kv.first)
{
return &_hTable[idx];
}
++idx;
if (idx == _hTable.size())
{
idx = 0;
}
}
return nullptr;
}
bool erase(const K& key){
Node* node = find(key);
if (node){
node->_state = DELETE;
return true;
}
return false;
}
private:
vector<Node> _hTable;
size_t _size;
};