C++ hashmap實現

目錄

 

1 hashmap原理

 

2 代碼實現 


1 hashmap原理

hashmap和map的區別。hashmap底層使用hashtable來實現,手動實現通過array + 鏈表,鏈表上保存相同key的節點,需要實現hash映射函數以及比較函數。

 

2 代碼實現 

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

// define node info
template <class KEY, class VALUE>
class HashNode {
public:
    KEY _key;
    VALUE _value;
    HashNode *next;
    HashNode(KEY key, VALUE value) {
        _key = key;
        _value = value;
        next = NULL;
    }
    ~HashNode(){}
    HashNode& operator= (const HashNode &node) {
        _key = node._key;
        _value = node._value;
        next = node.next;
        return *this;
    }
};

// class hashmap
template <class KEY, class VALUE, class HASHFUNC, class EQUAL>
class HashMap {
public:
    HashMap(int capacity);
    bool insert(const KEY &key, const VALUE &value);
    VALUE& find(const KEY &key);
    bool del(const KEY &key);
    ~HashMap();
    VALUE& operator[] (const KEY &key);

private:
    int _size;
    HashNode<KEY, VALUE> **hash_array;
    HASHFUNC hash;
    EQUAL equal;
    VALUE valuenull;
};

// generate hashcode
class HASHFUNC {
public:
    int operator() (const string& key) {
        int hash = 0;
        for (int i = 0; i < key.size(); ++i) {
            hash = hash << 7^key[i];
        }
        return (hash & 0x7FFFFFFF);
    }
};

// key equal
class EQUAL {
public:
    bool operator() (const string &A, const string &B) {
        if (A.compare(B) == 0) {
            return true;
        } else {
            return false;
        }
    }
};

template <class KEY, class VALUE, class HASHFUNC, class EQUAL>
HashMap<KEY, VALUE, HASHFUNC, EQUAL>::HashMap(int capacity): _size(capacity), hash(), equal()  {
    hash_array = new HashNode<KEY, VALUE> *[capacity];
    for (int i = 0; i < capacity; ++i) {
        hash_array[i] = NULL;
    }
}

template <class KEY, class VALUE, class HASHFUNC, class EQUAL>
bool HashMap<KEY, VALUE, HASHFUNC, EQUAL>::insert(const KEY &key, const VALUE &value) {
    int hashcode = hash(key) % _size;
    HashNode<KEY, VALUE> *new_node = new HashNode<KEY, VALUE>(key, value);
    new_node->next = hash_array[hashcode];
    hash_array[hashcode] = new_node;

    return true;
}

template <class KEY, class VALUE, class HASHFUNC, class EQUAL>
VALUE& HashMap<KEY, VALUE, HASHFUNC, EQUAL>::find(const KEY &key) {
    int hashcode = hash(key) % _size;
    HashNode<KEY, VALUE> *cur_node = hash_array[hashcode];
    while (cur_node) {
        if (equal(cur_node->_key, key)) {
            return cur_node->_value;
        } else {
            cur_node = cur_node->next;
        }
    }

    return valuenull;
}

template <class KEY, class VALUE, class HASHFUNC, class EQUAL>
VALUE& HashMap<KEY, VALUE, HASHFUNC, EQUAL>::operator[] (const KEY &key) {
    return find(key);
}

template <class KEY, class VALUE, class HASHFUNC, class EQUAL>
bool HashMap<KEY, VALUE, HASHFUNC, EQUAL>::del(const KEY &key) {
    int hashcode = hash(key) % _size;
    HashNode<KEY, VALUE> *cur_node = hash_array[hashcode];
    HashNode<KEY, VALUE> *pre_node = NULL;
    while (cur_node) {
        if (equal(cur_node->_key, key) && pre_node == NULL) {
            hash_array[hashcode] = cur_node->next;
            delete cur_node;
            cur_node = NULL;
            return true;
        } else if (equal(cur_node->_key, key) && pre_node != NULL) {
            pre_node->next = cur_node->next;
            delete cur_node;
            cur_node = NULL;
            return true;
        } else {
            pre_node = cur_node;
            cur_node = cur_node->next;
        }
    }

    return false;
}

template <class KEY, class VALUE, class HASHFUNC, class EQUAL>
HashMap<KEY, VALUE, HASHFUNC, EQUAL>::~HashMap() {
    for (int i = 0 ;i < _size; ++i) {
        HashNode<KEY, VALUE> *cur_node = hash_array[i];
        while (cur_node) {
            HashNode<KEY, VALUE> *temp = cur_node;
            cur_node = cur_node->next;
            delete temp;
            temp = NULL;
        }
    }
    delete hash_array;
}

int main() {
    HashMap<string, string, HASHFUNC, EQUAL> hashmap(5);
    hashmap.insert("hello", "world");
    hashmap.insert("hello1", "world");
    hashmap.insert("hello2", "world");
    cout << hashmap.find("hello").c_str() << endl;
    cout << hashmap.del("hello1") << endl;
    cout << hashmap["hello2"] << endl;

    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章