纯代码
#pragma once
#include <iostream>
#include <vector>
using namespace std;
struct __HashFuncString
{
size_t operator()(const string &key)
{
size_t hash = 0;
for (size_t i = 0; i < key.size(); ++i)
{
hash += key[i];
}
return hash;
}
};
struct __HashFuncInt
{
size_t operator()(const int &key)
{
return key;
}
};
//利用函数的重载,可以实现对int string类型 用不同的hash算法!!
template <class K>
struct __DefaultHashFunc
{
size_t operator()(const string &key)
{
return HashFuncString(key);
}
size_t operator()(const int &key)
{
return HashFuncInt(key);
}
__HashFuncString HashFuncString;
__HashFuncInt HashFuncInt;
};
template<class K, class V>
struct HashTableNode
{
HashTableNode(K key, V value)
:_key(key)
,_value(value)
,_next(NULL)
{}
K _key;
V _value;
HashTableNode<K, V> *_next;
};
template<class K, class V, class HashFunc = __DefaultHashFunc<K> >
class HashTableBucket
{
typedef HashTableNode<K, V> Node;
public:
HashTableBucket();
HashTableBucket(const HashTableBucket<K, V, HashFunc> &t);
HashTableBucket<K, V, HashFunc>& operator=(HashTableBucket<K, V, HashFunc> t);
~HashTableBucket();
bool Insert(const K& key, const V& value);
HashTableNode<K, V> *Find(const K& key);
bool Remove(const K& key);
friend ostream& operator<< (ostream &os, HashTableBucket<K, V, HashFunc> &t)
{
t.PrintTables();
return os;
}
protected:
size_t _GetNextPrime(size_t size);
void _CheckExpand();
void PrintTables();
protected:
vector<Node*> _tables;
size_t _size;
};
template<class K, class V, class HashFunc>
inline size_t HashTableBucket<K, V, HashFunc>::_GetNextPrime(size_t size)
{
// 使用素数表对齐做哈希表的容量,降低哈希冲突
const int _PrimeSize = 28;
static const unsigned long _PrimeList[_PrimeSize] =
{
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
};
for (size_t i = 0; i < _PrimeSize; ++i)
{
if (_PrimeList[i] > size)
{
return _PrimeList[i];
}
}
return size;
}
template<class K, class V, class HashFunc>
inline void HashTableBucket<K, V, HashFunc>::_CheckExpand()
{
if (_size >= (0.9 * _tables.size()))
{
_tables.resize(_GetNextPrime(_tables.size()));
}
}
template<class K, class V, class HashFunc>
inline HashTableBucket<K, V, HashFunc>::HashTableBucket()
:_size(0)
{
_tables.resize(_GetNextPrime(_tables.size()));
}
template<class K, class V, class HashFunc>
inline HashTableBucket<K, V, HashFunc>::HashTableBucket(const HashTableBucket<K, V, HashFunc>& t)
:_size(0)
{
_tables.resize(t.size());
for (size_t i = 0; i < t._size; ++i)
{
Node *cur = t._tables[i];
while (cur)
{
this->Insert(cur->_key, cur->_value);
cur = cur->_next;
}
}
}
template<class K, class V, class HashFunc>
inline bool HashTableBucket<K, V, HashFunc>::Insert(const K & key, const V & value)
{
_CheckExpand();
int index = HashFunc()(key) % _tables.size();
Node *NewNode = new Node(key, value);
if (_tables[index] == NULL)
{
_tables[index] = NewNode;
}
else
{
NewNode->_next = _tables[index];
_tables[index] = NewNode;
}
++_size;
return true;
}
template<class K, class V, class HashFunc>
inline HashTableNode<K, V>* HashTableBucket<K, V, HashFunc>::Find(const K & key)
{
int index = HashFunc()(key) % _tables.size();
Node *cur = _tables[index];
while (cur)
{
if (cur->_key == key)
{
return cur;
}
cur = cur->_next;
}
}
template<class K, class V, class HashFunc>
inline bool HashTableBucket<K, V, HashFunc>::Remove(const K & key)
{
int index = HashFunc()(key) % _tables.size();
Node *cur = _tables[index];
if (cur == NULL)
{
return false;
}
if (cur->_key == key)
{
_tables[index] = cur->_next;
delete cur;
cur = NULL;
}
while (cur && cur->_next)
{
if (cur->_next->_key == key)
{
Node *del = cur->_next;
cur->_next = del->_next;
delete del;
del = NULL;
_size--;
return true;
}
cur = cur->_next;
}
return false;
}
template<class K, class V, class HashFunc>
inline void HashTableBucket<K, V, HashFunc>::PrintTables()
{
for (size_t i = 0; i < _tables.size(); ++i)
{
Node *cur = _tables[i];
cout << "第" << i << "行: ";
while (cur)
{
cout << cur->_key << " :" << cur->_value << " -->";
cur = cur->_next;
}
cout << "NULL" << endl;
}
}
template<class K, class V, class HashFunc>
inline HashTableBucket<K, V, HashFunc>& HashTableBucket<K, V, HashFunc>::operator=(HashTableBucket<K, V, HashFunc> t)
{
_tables.swap(t);
swap(_size, t._size);
}
template<class K, class V, class HashFunc>
inline HashTableBucket<K, V, HashFunc>::~HashTableBucket()
{
for (size_t i = 0; i < _tables.size(); ++i)
{
Node *cur = _tables[i];
while (cur)
{
Node *del = cur;
cur = cur->_next;
delete del;
}
_tables[i] = NULL;
}
}
转载于:https://blog.51cto.com/zhweizhi/1784078