手撸Hash表实现 key-value 的插入查询删除遍历

huaru科技笔试做到用伪代码手写map的实现,可以选择使用hash表和红黑树,一个大嘴巴子。。。

Hash表

没有冲突情况

  • 直接使用vector
  • 除留取余
//散列函数 + 除留取余法 + 链式地址法
#include<iostream>
#include<string>
#include<cstdlib>
#include<vector>
using namespace std;


template<class K, class V>
class Hash{
public:
    struct Node{
        K key;
        V val;
        Node* next;
        Node(const K& _key = K(),const V& _val = V()):key(_key),val(_val),next(nullptr){}
        //Node(const K& _key,const V& _val):key(_key),val(_val),next(nullptr){}
    };
    //static const int capacity = 101;//表的大小,不够扩容
    int currentsize;
    vector<Node> hashtable;

public:
    int hashFunction(const K& key) const{

        int sum = 0;
        int index;

        for (size_t i = 0; i < key.size(); ++i)
        {
            sum += static_cast<int>(key[i]);
        }

        index = sum % hashtable.size(); //除留取余
        /*
        cout << "key[0] = " << key[0] << endl;
        cout << "key[0] = " << static_cast<int>(key[0]) << endl;
        cout << "key[1] = " << key[1] << endl;
        cout << "key[2] = " << key[2] << endl;
        cout << "sum = " << sum << endl;
        cout << "index = " << index << endl << endl;
        */
        return index;
    }

    Hash(int _capacity = 101) :hashtable(_capacity), currentsize(0) {}
    ~Hash(){}
    void insert(const K& key, const V& val) {
        int hashcode = hashFunction(key);
       
        hashtable[hashcode] = Node(key, val);
        ++currentsize;
    }
    V query(const K& key) const 
    {
        int hashcode = hashFunction(key);
        if (hashtable[hashcode].key == key) {
            return hashtable[hashcode].val;
        }
        else {
            return V();
        }
    }
    void erase(const K& key) {
        int hashcode = hashFunction(key);
        if (hashtable[hashcode].key != K()) {
            cout << "delete Node " << hashtable[hashcode].key << ":" << hashtable[hashcode].val << endl;
            hashtable[hashcode] = Node();
        }
        else {
            cout << "delete Nothing. "<<endl;
        }
    }
    void printtable() {
        for (size_t i = 0; i < hashtable.size(); i++) {
            if (hashtable[i].key != K()) {
                cout << hashtable[i].key << ": " << hashtable[i].val << endl;
            }
        }
    }
};

int main(){

    // 创建一个 HashMap  并开辟内存
    Hash<string, int>* hm =new Hash<string, int>();
    hm->insert("hua1", 1);
    hm->insert("hua2", 2);
    hm->insert("hua3", 3);
    hm->insert("hua4", 4);
    hm->insert("hua5", 5);
    
    cout << hm->query("hua1") << endl;
    cout << hm->query("hua2") << endl;
    cout << hm->query("hua3") << endl;
    cout << hm->query("hua4") << endl;
    cout << hm->query("hua5") << endl;
    hm->printtable();
    hm->erase("hua4");
    hm->printtable();
    delete  hm;
    return 0;

}


存在冲突

  • vector
  • 除留取余
  • 桶(拉链法)

没写完,erase和遍历没写
没写迭代器
有待改进,先酱汁

//散列函数 + 除留取余法 + 链式地址法
#include<iostream>
#include<string>
#include<cstdlib>
#include<vector>
using namespace std;


template<class K, class V>
class Hash {
public:
    struct Node {
        K key;
        V val;
        Node* next;
        Node(const K& _key = K(), const V& _val = V()) :key(_key), val(_val), next(nullptr) {}
        Node(const K& _key,const V& _val,Node * _next):key(_key),val(_val),next(_next){}
    };
    //static const int capacity = 101;//表的大小,不够扩容
    int currentsize;
    vector<Node*> hashtable;

public:
    int hashFunction(const K& key) const {

        int sum = 0;
        int index;

        for (size_t i = 0; i < key.size(); ++i)
        {
            sum += static_cast<int>(key[i]);
        }

        index = sum % hashtable.size(); //除留取余
        /*
        cout << "key[0] = " << key[0] << endl;
        cout << "key[0] = " << static_cast<int>(key[0]) << endl;
        cout << "key[1] = " << key[1] << endl;
        cout << "key[2] = " << key[2] << endl;
        cout << "sum = " << sum << endl;
        cout << "index = " << index << endl << endl;
        */
        return index;
    }

    Hash(int _capacity = 101) :hashtable(_capacity), currentsize(0) {
        for (int i = 0; i < _capacity; i++) {
            hashtable[i] = nullptr;
        }
    }
    ~Hash() {}
    void insert(const K& key, const V& val) {
        int hashcode = hashFunction(key);
        if (hashtable[hashcode] == nullptr) {
            hashtable[hashcode] = new Node(key, val);
            ++currentsize;
            return;
        }
        
        Node* p = hashtable[hashcode];
        while (p->next != nullptr) {
            //如果key相同,就要覆盖
            if (key == p->key && hashFunction(key) == hashFunction(p->key)) {
                p->val = val;
                return;
            }
            p = p->next;
        }

        Node *tmp = new Node(key, val, hashtable[hashcode]);
        hashtable[hashcode] = tmp;
        ++currentsize;
        return;
    }
    V query(const K& key) const
    {
        int hashcode = hashFunction(key);
        if (hashtable[hashcode] == nullptr) return V();
        Node* p = hashtable[hashcode];
        while (p!=nullptr) {
            if (key == p->key && hashFunction(key) == hashFunction(p->key)) {
                return p->val;
            }
            p = p->next;
        }
        return V();
    }
    void erase(const K& key) {
        int hashcode = hashFunction(key);
        if (hashtable[hashcode].key != K()) {
            cout << "delete Node " << hashtable[hashcode].key << ":" << hashtable[hashcode].val << endl;
            hashtable[hashcode] = Node();
        }
        else {
            cout << "delete Nothing. " << endl;
        }
    }
};

int main() {

    // 创建一个 HashMap  并开辟内存
    Hash<string, int>* hm = new Hash<string, int>();
    hm->insert("hua1", 1);
    hm->insert("hua2", 2);
    hm->insert("hua3", 3);
    hm->insert("hua4", 4);
    hm->insert("hua5", 5);

    cout << hm->query("hua1") << endl;
    cout << hm->query("hua2") << endl;
    cout << hm->query("hua3") << endl;
    cout << hm->query("hua4") << endl;
    cout << hm->query("hua5") << endl;

    delete  hm;
    return 0;

}

在面试老师的指点下,告诉我用指针数组来写,于是乎,先贴一个demo

#include<iostream>
#include<string>
#incldue<vector>
using namespace std;

template<class K,class V>
class Hash{
public:
    struct Node{
        K key;
        V val;
        Node* next;
        Node(const K& _key = K(),const V& _val = V()):key(_key),val(_val),next(nullptr){}
        
    };
    int currentsize;
    vector<Node*> hashtable;
    int hashfunc(const &key){
    
    }
    Hash(int size = 100):currentsize(0),hashtable(size){
        for(int i=0;i<size;++i){
            hashtable[i]=nullptr;
        }
    }
    ~Hash(){}
    void insert(K &key,V &val){
        int hashcode = hashfunc(key)
        if(hashtable[hashcode]==nullptr){
            Node * tmp = new Node(key,val);
            hashtable[hashcode]=   tmp;
        }else{
            Node* cur = hashtable[hashcode];
            while(cur->next!=nullptr){
                cur = cur->next;
            }
            Node *tmp = new Node(key,val);
            cur->next = tmp;  
        }
    }
};

posted @ 2022-10-02 15:54  PiaYie  阅读(30)  评论(0编辑  收藏  举报