Hash-table(用除法散列法实现)

Hash-table(用除法散列法实现)

关键字只支持int型,初学者版本
用链表解决冲突问题


#ifndef C11LEARN_HASHDIVISION_H
#define C11LEARN_HASHDIVISION_H
#include "Chain.h"
template<typename T>
class HashDivision
{
protected:
    int capacity;
    Chain<T>**array;
public:
    HashDivision(int capacity = 701);
    HashDivision(const HashDivision<T> &hashDivision);
    const HashDivision<T> & operator =(const HashDivision<T> &hashDivision);
    T& operator[](int key);
    const T operator[](int key) const;
    Chain<T>* search(int key);
    bool insert(Chain<T>* node);
    bool remove(Chain<T>* node);
    virtual ~HashDivision();

protected:
    virtual int hashing(int index);
    void clear();
    void copy(const HashDivision<T> &hashDivision);
};
template<typename T>
HashDivision<T>::HashDivision(int capacity):capacity(capacity){
    array = new Chain<T>* [this->capacity];
}
template<typename T>
HashDivision<T>::~HashDivision(){
    clear();
    delete [] array;
    array = nullptr;
}
template<typename T>
void HashDivision<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>
HashDivision<T>::HashDivision(const HashDivision<T> &hashDivision){
    capacity = hashDivision.capacity;
    array = new Chain<T>* [capacity];
    copy(hashDivision);
}
template<typename T>
const HashDivision<T> & HashDivision<T>::operator =(const HashDivision<T> &hashDivision){
    if(this == &hashDivision) return *this;
    clear();
    delete [] array;
    capacity = hashDivision.capacity;
    array = new Chain<T>* [capacity];
    copy(hashDivision);
    return *this;
}
template<typename T>
void HashDivision<T>::copy(const HashDivision<T> &hashDivision){
    Chain<T>* current;
    Chain<T>* prev;
    for (int i = 0; i < capacity; ++i) {
        prev = nullptr;
        current = hashDivision.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>
T& HashDivision<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>
const T HashDivision<T>::operator[](int key) const{
    Chain<T>* node = search(key);
    if(node == nullptr)
    {
        throw "no find this key";
    }
    return node->value;
}
template<typename T>
Chain<T>* HashDivision<T>::search(int key)
{
    int hash_code = hashing(key);
    Chain<T>* current = array[hash_code];
    while (current!= nullptr && current->key != key)
    {
        current =current->next;
    }
    return current;
}
template<typename T>
int HashDivision<T>::hashing(int index){
    return index % capacity;
}
template<typename T>
bool HashDivision<T>::insert(Chain<T>* node){
    if(node == nullptr) return false;
    int hash_code = hashing(node->key);
    Chain<T>* current = array[hash_code];
    if(current == nullptr)
    {
        array[hash_code] = node;
    }
    else
    {
        node->next = current;
        current->prev = node;
        array[hash_code] = node;
    }
    return true;
}
template<typename T>
bool HashDivision<T>::remove(Chain<T>* node){
    if(node == nullptr) return false;
    if(node->prev == nullptr)
    {
        int hash_code = hashing(node->key);
        array[hash_code] = node->next;
    }
    else
    {
        node->prev->next = node->next;
        if(node->next!= nullptr)
            node->next->prev = node->prev;
    }
    delete node;
    node = nullptr;
    return true;
}

#endif //C11LEARN_HASHDIVISION_H

辅助类
Chain代码链接

测试代码

    HashDivision<string> hashDivision;
    hashDivision[2] = "hello";
    hashDivision[5] = "world";
    cout<<hashDivision[2]<<endl;
    cout<<hashDivision[5]<<endl;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
散列表线性探测是一种解决散列冲突的方,其中散列函数是将键映射到散列表中的索引位置。除留余数是一种常见的散列函数,它可以将键转换为一个整数,然后使用模运算将其映射到散列表中的索引位置。 以下是使用除留余数实现散列表线性探测的示例代码: ```c++ #include <iostream> #include <cstring> using namespace std; const int SIZE = 10; //散列表大小 const int EMPTY = -1; //空位置标记 class HashTable { private: int* table; //散列表 int hash(int key); //散列函数 public: HashTable(); void insert(int key); void remove(int key); void display(); }; //构造函数,初始化散列HashTable::HashTable() { table = new int[SIZE]; memset(table, EMPTY, SIZE * sizeof(int)); } //散列函数,除留余数 int HashTable::hash(int key) { return key % SIZE; } //插入键到散列表中 void HashTable::insert(int key) { int index = hash(key); //计算散列值 int i = index; do { if (table[i] == EMPTY) { //如果位置为空 table[i] = key; //插入键 return; } i = (i + 1) % SIZE; //线性探测 } while (i != index); //回到起始位置,散列表已满 cout << "散列表已满,插入失败!" << endl; } //从散列表中删除键 void HashTable::remove(int key) { int index = hash(key); //计算散列值 int i = index; do { if (table[i] == key) { //如果找到键 table[i] = EMPTY; //删除键 return; } i = (i + 1) % SIZE; //线性探测 } while (i != index); //回到起始位置,未找到键 cout << "未找到键,删除失败!" << endl; } //显示散列表中的键 void HashTable::display() { for (int i = 0; i < SIZE; i++) { if (table[i] != EMPTY) { cout << table[i] << " "; } } cout << endl; } int main() { HashTable ht; ht.insert(3); ht.insert(7); ht.insert(11); ht.insert(22); ht.insert(31); ht.display(); ht.remove(11); ht.remove(7); ht.display(); ht.insert(33); ht.insert(44); ht.insert(55); ht.insert(66); ht.display(); return 0; } ``` 在这个示例中,我们使用除留余数作为散列函数,将键映射到散列表中的索引位置。如果该位置已经被占用,则使用线性探测寻找下一个可用位置。当散列表已满时,插入操作将失败。删除操作将从散列表中删除键,并将其位置标记为空。显示操作将输出散列表中的所有键。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值