您的位置:首页 > 其它

LRU Cache

2016-03-30 14:10 141 查看
Descripiton:

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the

following operations: get and set.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise

return -1.

set(key, value) - Set or insert the value if the key is not already present. When the cache reached its

capacity, it should invalidate the least recently used item before inserting a new item.

分析:

为了使查找、插入和删除都有较高的性能,我们使用一个双向链表 (std::list) 和一个哈希表

(std::unordered_map),因为:

• 哈希表保存每个节点的地址,可以基本保证在 O(1) 时间内查找节点

• 双向链表插入和删除效率高,单向链表插入和删除时,还要查找节点的前驱节点

具体实现细节:

• 越靠近链表头部,表示节点上次访问距离现在时间最短,尾部的节点表示最近访问最少

• 访问节点时,如果节点存在,把该节点交换到链表头部,同时更新 hash 表中该节点的地址

• 插入节点时,如果 cache 的 size 达到了上限 capacity,则删除尾部节点,同时要在 hash 表中删

除对应的项;新节点插入链表头部。

#include <iostream>
#include <unordered_map>
#include <list>

using namespace std;

struct cacheNode
{
int key;
int val;
cacheNode(int k,int v):key(k),val(v) {}
};

class LRUcache
{
public:
LRUcache(int capacity)
{
this->capacity = capacity;
}

int getKey(int key);

void setKey(int key, int value);

private:
list<cacheNode> cacheList;
unordered_map<int,list<cacheNode>::iterator> cacheMap;
int capacity;

};

int LRUcache::getKey(int key)
{
if (cacheMap.find(key) == cacheMap.end())
return -1;
//move the current node to the head ,and update address in map
cacheList.splice(cacheList.begin(),cacheList,cacheMap[key]);
cacheMap[key] = cacheList.begin();

return cacheMap[key]->val;
}

void LRUcache::setKey(int key, int value)
{
if (cacheMap.find(key) == cacheMap.end())  //insert
{
if (cacheList.size() == capacity)   //delete the tail node
{
cacheMap.erase(cacheList.back().key);
cacheList.pop_back();
}
cacheList.push_front(cacheNode(key,value));
cacheMap[key] = cacheList.begin();
}
else    // update the node ,and move the node to head
{
cacheMap[key]->val = value;
cacheList.splice(cacheList.begin(),cacheList,cacheMap[key]);
cacheMap[key] = cacheList.begin();
}

}

int main()
{
int key,val = 0;
int capacity = 5;
LRUcache lrucache(capacity);

lrucache.setKey(1,10);
lrucache.setKey(2,20);
lrucache.setKey(3,30);
lrucache.setKey(4,40);

cout<<"(1,"<<lrucache.getKey(1)<<")"<<"  ";
cout<<"(2,"<<lrucache.getKey(2)<<")"<<"  ";
cout<<"(3,"<<lrucache.getKey(3)<<")"<<"  ";
cout<<"(4,"<<lrucache.getKey(4)<<")"<<endl;

lrucache.setKey(5,50);
lrucache.setKey(6,60);

cout<<"(5,"<<lrucache.getKey(5)<<")"<<"  ";
cout<<"(6,"<<lrucache.getKey(6)<<")"<<endl;

lrucache.setKey(2,100);
cout<<"(2,"<<lrucache.getKey(2)<<")"<<endl;
cout<<"(1,"<<lrucache.getKey(1)<<")"<<"  ";     //already deleted ,return -1

return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: