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 表中删
除对应的项;新节点插入链表头部。
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; }
相关文章推荐
- linux基本知识1
- 判断访问浏览器客户端类型(pc,mac,ipad,iphone,android)
- session机制详解以及session的相关应用
- JS操作cookie以及本地存储(sessionStorage 和 localStorage )
- MFC更改控件的背景和字体颜色
- ARM指令集—SWP指令
- js判断输入是否为空
- Error: java lang OutOfMemoryError Java heap space 解决
- AtomicInteger在实际项目中的应用
- 整理常用iOS的第三方框架
- 全栈工程师眼中的HTTP
- 软件测试-----Graph Coverage作业
- 抽象类和抽象函数
- 自学鸟哥linux服务-samba文件共享服务
- Eclipse下Base64中文编码问题
- 排序算法
- 64. Minimum Path Sum
- jQuery 停止动画
- 【按键】[独立按键] - 3:三击 以及 N击
- Android项目中如何用好构建神器Gradle?