hash table(全域散列法实现的哈希表)

hash table(全域散列法实现的哈希表)

利用每次重建哈希表时随机生成散列函数


#ifndef C11LEARN_HASHUNIVERSAL_H
#define C11LEARN_HASHUNIVERSAL_H
#include "Chain.h"
#include "../tools/random.h"
template<typename T>
class HashUniversal
{
protected:
    Chain<T>** array;
    int capacity;
    long long large_prime_numbers;
    long long a;
    long long b;
public:
    HashUniversal(int capacity = 1<<10,long long large_prime_numbers = 100001651);
    HashUniversal(const HashUniversal<T>& hashUniversal);
    const HashUniversal<T>& operator=(const HashUniversal<T>& hashUniversal);
    ~HashUniversal();
    T & operator[](int key);
    bool remove(int key);

protected:
    virtual int hashing(int key);
    void insert(Chain<T>* node);
    Chain<T>*search(int key);
    void clear();
    void copy(const HashUniversal<T> & hashUniversal);
    bool remove(Chain<T>* node);
};
template<typename T>
HashUniversal<T>::HashUniversal(int capacity,long long large_prime_numbers):capacity(capacity),large_prime_numbers(large_prime_numbers){
    array = new Chain<T>*[this->capacity];
    a = random_include_left_right(1ll,this->large_prime_numbers-1);
    b = random_include_left_right(0ll,this->large_prime_numbers-1);
}
template<typename T>
HashUniversal<T>::HashUniversal(const HashUniversal<T>& hashUniversal)
{
    capacity = hashUniversal.capacity;
    a = hashUniversal.a;
    b = hashUniversal.b;
    array = new Chain<T>*[this->capacity];
    large_prime_numbers = hashUniversal.large_prime_numbers;
    copy(hashUniversal);
}
template<typename T>
const HashUniversal<T>& HashUniversal<T>::operator=(const HashUniversal<T>& hashUniversal){
    if(this == &hashUniversal) return *this;
    clear();
    delete[] array;
    capacity = hashUniversal.capacity;
    a = hashUniversal.a;
    b = hashUniversal.b;
    array = new Chain<T>*[this->capacity];
    large_prime_numbers = hashUniversal.large_prime_numbers;
    copy(hashUniversal);
    return *this;
}
template<typename T>
HashUniversal<T>::~HashUniversal(){
    clear();
    if(array!= nullptr)
    {
        delete [] array;
        array = nullptr;
    }
}
template<typename T>
T & HashUniversal<T>::operator[](int key){
    Chain<T>* node = search(key);
    if(node == nullptr)
    {
        node = new Chain<T>();
        node->key = key;
        insert(node);
    }
    return node->value;
}
template<typename T>
int HashUniversal<T>::hashing(int key)
{
    return ((a*key+b)%large_prime_numbers)%capacity;
}
template<typename T>
void HashUniversal<T>::insert(Chain<T>* node){
    int pos = hashing(node->key);
    Chain<T>* current = array[pos];
    if(current == nullptr)
    {
        array[pos] = node;
    }
    else
    {
        current->prev = node;
        node->next = current;
    }
}
template<typename T>
Chain<T>* HashUniversal<T>::search(int key){
    int pos = hashing(key);
    Chain<T>* current = array[pos];
    while (current!= nullptr && current->key != key)
        current = current->next;
    return current;
}
template<typename T>
void HashUniversal<T>::clear(){
    Chain<T>* current;
    Chain<T>* next;
    for (int i = 0; i < capacity; ++i) {
        current = array[i];
        while (current!= nullptr)
        {
            next = current->next;
            delete current;
            current = next;
        }
    }
}
template<typename T>
void HashUniversal<T>::copy(const HashUniversal<T> & hashUniversal){
    Chain<T>* current;
    Chain<T>* prev;
    for (int i = 0; i < capacity; ++i) {
        prev = nullptr;
        current = hashUniversal.array[i];
        while (current!= nullptr)
        {
            prev = current;
            current = current->next;
        }
        while (prev!= nullptr)
        {
            Chain<T>* node = new Chain<T>();
            node->key = prev->key;
            node->value = prev->value;
            insert(node);
            prev = prev->prev;
        }
    }
}
template<typename T>
bool HashUniversal<T>::remove(int key){
    Chain<T>* node = search(key);
    if(node == nullptr)
    {
        return false;
    }
    return remove(node);
}
template<typename T>
bool HashUniversal<T>::remove(Chain<T>* node){
    if(node == nullptr) return false;
    if(node->prev == nullptr)
    {
        int pos = hashing(node->key);
        array[pos] = node->next;
        if(node->next!= nullptr)
        {
            node->prev = nullptr;
        }
    }
    else
    {
        node->prev->next = node->next;
        if(node->next!= nullptr)
        {
            node->next->prev = node->prev;
        }
    }
    delete node;
    node = nullptr;
    return true;
}
#endif //C11LEARN_HASHUNIVERSAL_H

辅助类
1⃣️Chain链接地址
2⃣️random_include_left_right链接地址

测试代码

	HashUniversal<string> hashUniversal;
    hashUniversal[2] = "hello";
    hashUniversal[123456] = "world";
    cout << hashUniversal[2] << endl;
    cout << hashUniversal[123456] << endl;
    HashUniversal<string> hashUniversal1 = hashUniversal;
    cout << hashUniversal1[2] << endl;
    cout << hashUniversal1[123456] << endl;
    HashUniversal<string> hashUniversal2;
    hashUniversal2 = hashUniversal;
    cout << hashUniversal2[2] << endl;
    cout << hashUniversal2[123456] << endl;
    cout<<hashUniversal2.remove(123456)<<endl;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值