手写哈希表

也就是 leetcode 706. 设计哈希映射

采用拉链法,定义一组链表头,相同哈希值的放在同一个链表
不管是查找、插入还是删除,都需要遍历一遍对应的链表 (可以用二叉树或跳表优化)

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;

struct HashNode{
    int key;
    int val;
    HashNode *next;
    HashNode(int k, int v):key(k),val(v),next(NULL){}
};

struct HashMap{
    static const int M = 6007;

    HashNode* head[M];
    int count;  // 节点编号

    HashMap(){
        count = 0;
        for(int i = 0; i < M; i++){
            head[i] = new HashNode(-1, -1);
        }
    }

    void put(int key, int value){  // 添加或更新
        int hash = key % M;
        HashNode *p = head[hash]->next, *pre = head[hash];
        while(p != NULL){
            if(p->key == key){
                p->val = value;
                return;
            }
            pre = p;
            p = p->next;
        }
        pre->next = new HashNode(key, value);
        count++;
    }

    int get(int key){
        int hash = key % M;
        HashNode *p = head[hash]->next;
        while(p != NULL){
            if(p->key == key){
                return p->val;
            }
            p = p->next;
        }
        return -1;
    }

    void remove(int key){
        int hash = key % M;
        HashNode *p = head[hash]->next;
        HashNode *pre = head[hash];
        while(p != NULL){
            if(p->key == key){
                pre->next = p->next;
                delete p;
                count--;
                return;
            }
            pre = p;
            p = p->next;
        }
    }
};


int main() {
    HashMap hm;
    hm.put(1, 1);
    hm.put(2, 2);
    hm.put(3, 3);
    cout << hm.get(1) << endl;
    cout << hm.get(2) << endl;
    cout << hm.get(3) << endl;

    hm.remove(1);
    cout << hm.get(1) << endl;

    hm.put(2, 10);
    cout << hm.get(2) << endl;
}

还有一种开放定址法,当发生碰撞时,寻找下一个空闲单元,这要求负载因子比较小(0.75以下)

冲突处理四种方法(开放定址法,分离链接法,再哈希法,建立公共溢出区)
开放定址法四种方法(线性探测法,平方探测法,双散列探测法,再散列)
参考 https://cloud.tencent.com/developer/article/1672781

这里使用线性探测法,也就是顺序往下变量

点击查看代码
struct HashMap2{
    static const int M = 6007;

    HashNode* head[M];
    int count;  // 节点编号

    HashMap2(){
        count = 0;
        for(int i = 0; i < M; i++){
            head[i] = new HashNode(-1, -1);
        }
    }

    void put(int key, int value){  // 添加或更新
        int hash = key % M;
        while(head[hash]->key != key && head[hash]->key != -1){
            if(head[hash]->key == key){
                head[hash]->val = value;
                return;
            }
            hash = (hash + 1) % M;
        }
        head[hash]->key = key;
        head[hash]->val = value;
        count++;
    }

    int get(int key){
        int hash = key % M;
        while(head[hash]->key != key && head[hash]->key != -1){
            hash = (hash + 1) % M;
        }
        if(head[hash]->key == key){
            return head[hash]->val;
        }
        return -1;
    }

    void remove(int key){
        int hash = key % M;
        while(head[hash]->key != key && head[hash]->key != -1){
            hash = (hash + 1) % M;
        }
        if(head[hash]->key == key){
            // int val = head[hash]->val;
            head[hash]->key = -1;
            count--;
        }
    }
};
posted @ 2021-12-14 22:28  Rogn  阅读(80)  评论(0编辑  收藏  举报