目录
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;
}