问题
实现LRU算法.
代码
hash_map + double linked list实现
每次访问key处的内存时,先在hash_map 中查找cache中地址,
1,如果找到,就在cache中进行内存操作,在结束时,将key指向的节点移动到双向链表头部。
2,如果写入时没有找到, 就在double linked list 头部加入一个节点,如果此时没有可用空间,则先要将链表最后一个节点释放。
class Node{
public:
Node():key(-1),val(0),pre(0),next(0){}
int key, val;
int pre, next;
};
class LRUCache{
public:
LRUCache(int capacity) {
dl = new Node[capacity+1];
dl[0].next = 0;
dl[0].pre = 0;
fnptr = 1;
for (int i=1; i< capacity; ++i)
dl[i].next = i+1;
dl[capacity].next = 0;
}
~LRUCache(){delete dl;}
void useNode(int ptr)
{
dl[dl[ptr].pre].next = dl[ptr].next;
dl[dl[ptr].next].pre = dl[ptr].pre;
dl[ptr].next = dl[0].next;
dl[dl[0].next].pre = ptr;
dl[0].next = ptr;
dl[ptr].pre = 0;
}
void freeLast()
{
int del = dl[0].pre;
dl[dl[del].pre].next = 0;
dl[0].pre = dl[del].pre;
dl[del].next = fnptr;
fnptr = del;
keyToNodePtr.erase(dl[del].key);
}
void addOne(int key, int val)
{
if (fnptr == 0)
freeLast();
int now = fnptr;
fnptr = dl[fnptr].next;
dl[now].key = key;
dl[now].val = val;
keyToNodePtr[key] = now;
dl[now].next = dl[0].next;
dl[dl[0].next].pre = now;
dl[0].next = now;
dl[now].pre = 0;
}
int get(int key) {
if (keyToNodePtr.count(key))
{
int ptr = keyToNodePtr[key];
useNode(ptr);
return dl[ptr].val;
}
return -1;
}
void set(int key, int value) {
if (keyToNodePtr.count(key))
{
int ptr = keyToNodePtr[key];
dl[ptr].val = value;
useNode(ptr);
}else{
addOne(key, value);
}
}
private:
Node *dl; // double linked list;
int fnptr; // free node ptr
unordered_map<int, int> keyToNodePtr;
};