LRU是Least Recently Used算法的简称,在linux的内存页框管理里面用到。LeetCode上排名第一的就是这个算法。
有一个cache,大小固定,采用双向链表存储,哈希表用来检索。当有数据时,放到链表尾。如果大小溢出,则删除头节点。
读取链表中的数据,有的话则返回值,同时将该数据的节点放置在尾结点。
##Code##
<!-- lang: cpp -->
struct LRUStruct
{
int key;
int value;
LRUStruct *pre;
LRUStruct *next;
LRUStruct(int k=0,int v=0,LRUStruct *p=NULL,LRUStruct *n=NULL):key(k),value(v),pre(p),next(n){}
};
struct HeadTail
{
LRUStruct head;
LRUStruct tail;
HeadTail(LRUStruct h,LRUStruct t):head(h),tail(t){}
};
class LRUCache{
public:
int size;
unordered_map<int,LRUStruct*> keyMap;
HeadTail ht;
LRUCache(int capacity):ht(LRUStruct(),LRUStruct())
{
size=capacity;
}
int get(int key) {
if((keyMap.empty()) || (!keyMap.count(key))) return -1;
LRUStruct *ls=keyMap[key];
ls->pre->next=ls->next;
ls->next->pre=ls->pre;
insertTail(ls);
return ls->value;
}
void set(int key, int value) {
if (keyMap.empty())
{
LRUStruct *ls=new LRUStruct(key,value);
ht.head.next=ls;
ls->pre=&ht.head;
ht.tail.pre=ls;
ls->next=&ht.tail;
keyMap[key]=ls;
return;
}
if (keyMap.count(key))
{
LRUStruct *ls=keyMap[key];
ls->value=value;
ls->pre->next=ls->next;
ls->next->pre=ls->pre;
insertTail(ls);
}
else
{
if(keyMap.size()<size)
{
LRUStruct *ls=new LRUStruct(key,value);
insertTail(ls);
keyMap[key]=ls;
}
else
{
LRUStruct *p_tmp = ht.head.next;
keyMap.erase(p_tmp->key);
deleteHead();
LRUStruct *ls = new LRUStruct(key,value);
insertTail(ls);
keyMap[key] = ls;
delete p_tmp;
}
}
}
void insertTail(LRUStruct *ls)
{
ls->pre=ht.tail.pre;
ht.tail.pre->next=ls;
ls->next=&ht.tail;
ht.tail.pre=ls;
}
void deleteHead()
{
ht.head.next=ht.head.next->next;
ht.head.next->pre=&ht.head;
}
};
##Reference##
[1].http://blog.youkuaiyun.com/beiyeqingteng/article/details/7010411
[2].http://blog.youkuaiyun.com/zqpgood/article/details/6781195
[3].http://www.2cto.com/kf/201401/274774.html