• 手写哈希表


    也就是 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--;
            }
        }
    };
    
    个性签名:时间会解决一切
  • 相关阅读:
    while 循环 。。
    数据运算,运算符
    字符串常用操作
    列表常用操作
    三级菜单
    杂七杂八
    简单的登陆程序001
    猜年龄游戏
    实现密文输入密码
    使用urllib2打开网页的三种方法
  • 原文地址:https://www.cnblogs.com/lfri/p/15690362.html
Copyright © 2020-2023  润新知