首页 > 代码库 > C++:哈希

C++:哈希

1.基本概念

  哈希一般用来快速查找,通过hash函数将输入的键值(key)映射到某一个地址,然后就可以获得该地址的内容。

同样,如果要储存一对值(键值和数据),则也是通过hash函数获得地址来存入。见图例:

技术分享

 

  不过这其中会出现一些问题,最常见的是出现冲突。就是输入不同的key,经过hash之后得到同样的值,也就是在同一个地址要储存不同的data,

例如使用上图的hash,输入的key为1和11得到的地址都是1,则这种就是出现了冲突。

  解决这种冲突的方法有多种,比如线性探测法,折叠法,链表法等等。

2.实例

  下面是一个基于C++的简单的模板类,使用链表法来解决冲突。该hash类的数据结构为:

struct data
    {
        size_t key;
        map_t content;
        bool isEmpty;
        data * next;
        data() :isEmpty(true), next(nullptr){}
    };

  程序:

template<typename map_t>
class MyHash
{
public:
    MyHash() :size(1000)
    {
        store = new data[size];
    }
    MyHash(size_t s) :size(s)
    {
        store = new data[size];
    }
    ~MyHash()
    {
        delete[]store;
    }
public:
    bool insert(size_t key, map_t val);
    bool find(size_t key, map_t & val);
    bool erase(size_t key);
    void print();

private:
    size_t size;
    struct data
    {
        size_t key;
        map_t content;
        bool isEmpty;
        data * next;
        data() :isEmpty(true), next(nullptr){}
    };
    
    data * store;
    size_t hash(size_t key);
};


template<typename map_t>
bool MyHash<map_t>::insert(size_t key, map_t val)
{
    size_t t_k = hash(key);
    if (t_k >= size || t_k < 0)
        return false;
    if (!store[t_k].isEmpty)
    {
        data * temp_ptr = & store[t_k];
        while (temp_ptr->next!=nullptr)
        {
            temp_ptr = temp_ptr->next;
            if (temp_ptr->key == key)
            {
                temp_ptr->content = val;
                return true;
            }
        }
        data *new_ = new data;

        new_->key = key;
        new_->content = val;
        new_->isEmpty = false;
        new_->next = nullptr;
        temp_ptr->next = new_;

        return true;
    }

    data* new_ = new data;
    new_->key = key;
    new_->content = val;
    new_->isEmpty = false;
    new_->next = nullptr;

    store[t_k].next = new_;
    store[t_k].isEmpty = false;
    

    return true;
}
template<typename map_t>
bool MyHash<map_t>::find(size_t key, map_t& val)
{
    size_t t_k = hash(key);
    if (t_k >= size || t_k < 0)
        return false;
    
        data * temp_ptr = &store[t_k];
        while (temp_ptr->next != nullptr)
        {
            temp_ptr = temp_ptr->next;
            if (temp_ptr->key == key)
            {
                val = temp_ptr->content;
                return true;
            }
        }
        return false;
}
template<typename map_t>
bool MyHash<map_t>::erase(size_t key)
{
    size_t t_k = hash(key);
    if (t_k >= size || t_k < 0 || store[t_k].isEmpty)
        return false;

    data * temp_ptr = &store[t_k];
    data * temp_ptr_ = &store[t_k];
    while (temp_ptr->next!=nullptr)
    {
        temp_ptr_ = temp_ptr;
        temp_ptr = temp_ptr->next;
        if (temp_ptr->key == key)
        {
            temp_ptr_->next = temp_ptr->next;
            delete temp_ptr;
            return true;
        }
    }

    return false;
}
template<typename map_t>
void MyHash<map_t>::print()
{
    for (int i = 0; i < size; ++i)
    {
        if (!store[i].isEmpty)
        {
            cout << i << "  : ";

            data * temp_ptr = &store[i];
            while (temp_ptr->next != nullptr)
            {
                temp_ptr = temp_ptr->next;
                cout << " - " << temp_ptr->content;
            }
            cout << endl;
        }
    }
}

template<typename map_t>
size_t MyHash<map_t>::hash(size_t key)
{
    return key%size;
}

 

C++:哈希