最近想自己写个lru缓存练练手,于是乎就从最基本的hashmap开始着手,原本打算用容器机制来实现的,后来想想直接用模板能省不少力,不过每个溢出链表的空间多了不少。
#include <cstdlib>
#include <iostream>
#include <string>
#define HASHSIZE 4096
using namespace std;
template<class T>
class HashMap
{
private:
struct hlist_node
{
hlist_node *next, **prev;
string key;
T* value;
hlist_node(hlist_node* next_in = 0, hlist_node** prev_in = 0, string key_in = "", T* value_in = 0):next(next_in), prev(prev_in), key(key_in), value(value_in){}
~hlist_node(){}
};
struct hlist_head
{
hlist_node *first;
hlist_head():first(0){}
~hlist_head(){}
};
hlist_head* map;
int size;
long hash(const string &str);
public:
HashMap(int h_size = HASHSIZE):size(h_size){map = new hlist_head[h_size];}
~HashMap(){delete []map;}
void insert(const string key, T* data);
void remove(const string &key);
T* search(const string &key);
};
template<class T>
T* HashMap<T>::search(const string &key)
{
hlist_node* node = map[hash(key) % size].first;
while( 0 != node)
{
if(node -> key == key)
return node -> value;
node = node -> next;
}
return 0;
}
template<class T>
void HashMap<T>::insert(const string key, T* data)
{
//insert a key-value pair
hlist_node* node = new hlist_node();
hlist_node* first = map[hash(key) % size].first;
if(first)
first->prev = &node->next;
map[hash(key) % size].first = node;
node -> prev = &map[hash(key) % size].first;
node -> key = key;
node -> value = data;
}
template<class T>
void HashMap<T>::remove(const string &key)
hlist_node* node = map[hash(key) % size].first;
while(0 != node)
{
if(node -> key == key)
{
struct hlist_node * next = node -> next;
struct hlist_node ** prev = node -> prev;
*prev = next;
if(next)
next -> prev = prev;
delete node;
return;
}
node = node -> next;
}
return;
}
template<class T>
long HashMap<T>::hash(const string &str)
{
//BKD hash algorithm
long seed = 131;
long hash = 0;
for(int i = 0; i < str.length(); i++)
{
hash = (hash * seed) + str[i];
}
return hash;
}
int main()
{
HashMap<int> testhash ;
int t1 = 10;
int t2 = 11;
string s1 = "aaa";
string s2 = "bbb";
a.insert(s1, &t1);
a.insert(s2, &t2);
//a.remove(s1);
int * tmp = a.search(s1);
cout<<*tmp<<endl;
return 0;
}