HashMap

来源:互联网 发布:盛势网络剧百度云资源 编辑:程序博客网 时间:2024/05/27 20:39
#ifndef HASHMAP_H#define HASHMAP_H#include "stdlib.h"template<class K, class V> class HashMap;/*=============================================================================================== HashNode===============================================================================================*/template<class K, class V>class HashNode{friend class HashMap<K, V>;public:    K&              Key() { return key; }    V&              Value() { return value; }    private:    HashNode<K,V>*  next;    K               key;    V               value;};/*=============================================================================================== HashMap ===============================================================================================*/template<class K, class V>class HashMap{public:    typedef HashNode<K, V>  Node;    HashMap(int bucketSize = 16);    ~HashMap();        void                    Clear();        V*                      GetPtr(K& key);    bool                    Get(K& key, V& value);    void                    Set(K& key, V& value);    bool                    HasKey(K& key);    void                    Remove(K& key);    Node*                   First();    Node*                   Next(Node* it);private:    Node**                  buckets;    size_t                  bucketSize;    size_t                  num;        size_t                  GetHash(K& key);};/*===============================================================================================*/template<class K, class V>HashMap<K, V>::HashMap(int bucketSize_){    num = 0;    bucketSize = bucketSize_;    buckets = new Node*[bucketSize];    memset(buckets, 0, bucketSize * sizeof(Node*));}template<class K, class V>HashMap<K, V>::~HashMap(){    Clear();    delete[] buckets;}template<class K, class V>void HashMap<K, V>::Clear(){    size_ti;    Node*   node;    Node*   next;        for (i = 0; i < bucketSize; i++)    {        for (node = buckets[i]; node; node = next)        {            next = node->next;            delete node;        }        buckets[i] = NULL;    }    num = 0;}template<class K, class V>V* HashMap<K, V>::GetPtr(K& key){    size_t  hash;    Node*   node;        hash = GetHash(key);    for (node = buckets[hash]; node; node = node->next)    {        if (node->key == key)            return &node->value;    }        return NULL;}template<class K, class V>bool HashMap<K, V>::Get(K& key, V& value){    size_t  hash;    Node*   node;        hash = GetHash(key);    for (node = buckets[hash]; node; node = node->next)    {        if (node->key == key)        {            value = node->value;            return true;        }    }        return false;}template<class K, class V>void HashMap<K, V>::Set(K& key, V& value){    size_t  hash;    Node*   node;        hash = GetHash(key);    for (node = buckets[hash]; node; node = node->next)    {        if (node->key == key)        {            node->value = value;            return;        }    }        node = new Node;    node->key = key;    node->value = value;        node->next = buckets[hash];    buckets[hash] = node;    num++;        // TODO resize if too small    return;}template<class K, class V>bool HashMap<K, V>::HasKey(K& key){    if (GetPtr(key))        return true;            return false;}template<class K, class V>void HashMap<K, V>::Remove(K& key){    size_t  hash;    Node*   node;    Node*   next;    Node**  prev;        hash = GetHash(key);    prev = &buckets[hash];    for (node = buckets[hash]; node; node = next)    {        next = node->next;        if (node->key == key)        {            *prev = next;            delete node;            num--;            break;        }        prev = &node->next;    }        // TODO resize if too big}template<class K, class V>HashNode<K, V>* HashMap<K, V>::First(){    size_t  i;        for (i = 0; i < bucketSize; i++)    {        if (buckets[i])            return buckets[i];    }        return NULL;}template<class K, class V>HashNode<K, V>* HashMap<K, V>::Next(Node* it){    size_t  i;    size_t  hash;        if (it->next)        return it->next;    hash = GetHash(it->key);    for (i = hash + 1; i < bucketSize; i++)    {        if (buckets[i])            return buckets[i];    }        return NULL;}template<class K, class V>size_t HashMap<K, V>::GetHash(K& key){    return Hash(key) % bucketSize;}#endif