LRU Cache:设计并实现一个LRU的缓存。
为了较快的命中缓存,一般对键值key进行散列运算,但是找到最近最少使用项需要O(N)的时间。为了较快的找到最近最少使用项,可以基于最近使用的频率,对缓存行进行排序,但是这又导致无法快速找到某一缓存行。
所以我们应该同时使用上述两种数据结构,使用链表将缓存行串起来,同时利用散列表进行查找。当缓存满时,剔除链表中最后的一项,每当访问或者添加新的缓存行时,将命中项移动到链表头部。
class LRUCache {
private:
struct CacheLine
{
int key, value;
shared_ptr<CacheLine> prev, next;
CacheLine(int k, int v) : key(k), value(v){}
};
size_t MaxCapacity;
unordered_map<int, shared_ptr<CacheLine>> Cache;
shared_ptr<CacheLine> Head, Tail;
public:
LRUCache(int capacity) {
MaxCapacity = static_cast<size_t>(capacity);
Head = make_shared<CacheLine>(CacheLine(0, 0));
Tail = make_shared<CacheLine>(CacheLine(0, 0));
Head->next = Tail;
Tail->prev = Head;
}
int get(int key) {
auto iter = Cache.find(key);
if(iter != Cache.end()){
shared_ptr<CacheLine> cl = iter->second;
cl->prev->next = cl->next;
cl->next->prev = cl->prev;
cl->prev = Head;
cl->next = Head->next;
Head->next->prev = cl;
Head->next = cl;
return cl->value;
}
else return -1;
}
void put(int key, int value) {
if(get(key) != -1){
Cache[key]->value = value;
}
else{
if(Cache.size() == MaxCapacity){
int EvictedKey = Tail->prev->key;
Cache.erase(EvictedKey);
shared_ptr<CacheLine> last = Tail->prev;
last->prev->next = Tail;
Tail->prev = last->prev;
last = nullptr;
}
shared_ptr<CacheLine> first = make_shared<CacheLine>(key, value);
first->next = Head->next;
first->prev = Head;
Head->next->prev = first;
Head->next = first;
Cache[key] = first;
}
}
};
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache* obj = new LRUCache(capacity);
* int param_1 = obj->get(key);
* obj->put(key,value);
*/
本文介绍了一种高效实现LRU(最近最少使用)缓存的方法,通过结合链表和散列表的数据结构,实现了快速查找和更新最近最少使用的项。在缓存满时,能快速剔除最不常用的项,保持缓存的有效性和高性能。
1815

被折叠的 条评论
为什么被折叠?



