参考文献
https://cloud.tencent.com/developer/article/1021497
侵权,请联系本人删除
节点定义
template<class Key, class Value>
class HashNode
{
public:
Key _key;
Value _value;
HashNode *next;
HashNode(Key key, Value value)
{
_key = key;
_value = value;
next = NULL;
}
~HashNode()
{
}
HashNode& operator=(const HashNode& node)
{
key = node.key;
value = node.key;
next = node.next;
return *this;
}
};
哈希表的定义
template <class Key, class Value, class HashFunc, class EqualKey>
class HashMap
{
public:
HashMap(int size);
~HashMap();
bool insert(const Key& key, const Value& value);
bool del(const Key& key);
Value& find(const Key& key);
Value& operator [](const Key& key);
private:
HashFunc hash; //仿函数functor
EqualKey equal; //仿函数functor
typedef HashNode<Key, Value> HashNode_t;
vector<HashNode_t*> _buckets;
Value ValueNULL;
size_t _size;//节点的个数
};
//构造函数
template <class Key, class Value, class HashFunc, class EqualKey>
HashMap<Key, Value, HashFunc, EqualKey>::HashMap(int size) : _buckets(size)
{
hash = HashFunc();
equal = EqualKey();
}
查找
template <class Key, class Value, class HashFunc, class EqualKey>
Value& HashMap<Key, Value, HashFunc, EqualKey>::find(const Key& key)
{
unsigned index = hash(key) % _size;
if (table[index] == NULL)
return -1;
HashNode<Key, Value> * node = table[index];
while (node)
{
if (node->_key == key)
return node->_value;
node = node->next;
}
}
插入
//insert函数
template <class Key, class Value, class HashFunc, class EqualKey>
bool HashMap<Key, Value, HashFunc, EqualKey>::insert(const Key& key, const Value& value)
{
int index = hash(key)%_size;//确定桶号
HashNode<Key, Value> * p = _buckets[index];
//先查找是否存在
while(p) {
if (p->key == key) {
p->value = value;
return;
}
}
//判断是否需要rehash,参考VC++的实现
if (_size == m_buckets.size()) { //元素个数 = 桶的数目
rehash();
}
//不存在,创建新节点
HashNode<Key, Value> * node = new HashNode<Key, Value>(key,value);
_size++;
//重新计算桶号
index = hash(key)%_size;
//新节点指向原来的头节点
node->next = table[index];
//新节点成为头节点
table[index] = node;
return true;
}
rehash过程
void rehash()
{
//先确定下一个大小,参考VC++的实现
if (_size < 516) {
_size *= 8;
} else {
_size *= 2;
}
size_t old_size = _buckets.size();
vector<HashNode*> tmp;
for (size_t i=0; i < old_size; i++) { //遍历每一个桶
HashNode* p = _buckets[i];//每一条链表的头节点
while(p) { //遍历整体链表
size_t new_index = hashFunc(key) % _size;
HashNode* next = p->next; //缓存next节点
//将p插入到新的hash表上的链表头
p->next = tmp[new_index];//新的节点指向链表头
tmp[new_index] = p; //该节点成为新的节点
p = next;
}
}
_buckets.swap(tmp);
}
删除
template <class Key, class Value, class HashFunc, class EqualKey>
bool HashMap<Key, Value, HashFunc, EqualKey>::del(const Key& key)
{
unsigned index = hash(key) % _size;
HashNode<Key, Value> * node = table[index];
HashNode<Key, Value> * prev = NULL; //删除的时候,需要改变前一个节点的指向
while (node)
{
if (node->_key == key)
{
if (prev == NULL) //删除的是头节点
{
table[index] = node->next;
}
else
{
prev->next = node->next; //跳过该节点
}
delete node;
return true;
}
prev = node;
node = node->next;
}
return false;
}
关于仿函数
class EqualKey
{
public:
bool operator()(const string & A, const string & B)
{
if (A.compare(B) == 0)
return true;
else
return false;
}
};