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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM