模拟链地址法解决哈希冲突

哈希函数简单采用 mod求余,当遇到哈希值相同时,在对应位置构造链表。

#include <iostream>
#include <memory>
#include <vector>

constexpr int SIZE = 11;

template<typename T>
struct Node {
    std::shared_ptr<Node<T>> next;
    T key;

    Node() : next(nullptr), key(0) {}

    Node(const T &key_) : next(nullptr), key(key_) {}

    Node(Node<T> *ptr) { this->next = std::shared_ptr<Node<T>>(ptr); }

    Node(const T &key_, Node<T> *next_) : next(std::make_shared<Node<T>>(next_)), key(key_) {}
};

template<typename T>
class HashTable {
    using NodePtr = std::shared_ptr<Node<T>>;
public:
    HashTable() { table = std::make_shared<std::vector<NodePtr>>(SIZE, std::make_shared<Node<T>>()); }

    ~HashTable() = default;

    [[nodiscard]] auto cul_hash_code(const T &key) const { return key % SIZE; }

    void insert(T key) {
        auto pos = cul_hash_code(key);
        NodePtr newNode = std::make_shared<Node<T>>(key);
        //链地址法插入避免哈希碰撞
        if (table->at(pos)->key != 0){
            NodePtr ptr = table->at(pos);
            while (ptr->next)
                ptr = ptr->next;
            ptr->next = newNode;
        } else{
            table->at(pos) = newNode;
        }
    }

    bool isFind(const T &key) {
        T pos = cul_hash_code(key);
        if (table->at(pos)->key == key)
            return true;
        if (table->at(pos)->next){
            NodePtr ptr = table->at(pos)->next;
            while (ptr->next && ptr->next->key != key)
                ptr = ptr->next;
            return (ptr->key == key);
        } else
            return false;
    }

private:
    std::shared_ptr<std::vector<NodePtr>> table;
};

int main() {
    HashTable<int> test;
    test.insert(11);
    test.insert(22);
    test.insert(15);
    test.insert(100);
    std::cout << test.isFind(11);



    return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值