LRU(Least Recently Used)是一种常见的缓存淘汰策略,其实现思路如下:
- 使用双向链表和哈希表结合的数据结构。双向链表用于维护数据的访问顺序,越靠近链表头部的节点表示最近访问的数据,越靠近链表尾部的节点表示最久未访问的数据。哈希表用于快速查找数据在链表中的位置。
- 当需要访问某个数据时,首先在哈希表中查找数据是否存在:
- 如果存在,将该节点从链表中移动到链表头部,表示最近访问过。
- 如果不存在,需要进行以下操作:
- 如果缓存已满(达到最大容量),则需要淘汰链表尾部的节点(即最久未访问的节点),同时从哈希表中删除该节点。
- 创建一个新的节点,并将其插入到链表头部,并在哈希表中记录该节点的位置。
- 为了提高访问速度,可以使用哈希表记录每个节点在链表中的位置,这样在访问节点时可以在 O(1) 时间内定位到节点。
#include<iostream>
#include<list>
#include<unordered_map>
using namespace std;
class LRUCache {
private:
int capacity;
unordered_map<int, pair<int, list<int>::iterator>> cache;
list<int> lruList;
public:
LRUCache(int capacity) {
this->capacity = capacity;
}
int get(int key) {
if (cache.find(key) == cache.end()) return -1;
lruList.erase(cache[key].second);
lruList.push_front(cache[key].first);
cache[key].second = lruList.begin();
return cache[key].first;
}
void put(int key, int value) {
if (cache.find(key) != cache.end()) {
lruList.erase(cache[key].second);
}
else if (cache.size() >= capacity) {
cache.erase(lruList.back());
lruList.pop_back();
}
lruList.push_front(key);
cache[key] = {value,lruList.begin()};
}
};
int main() {
LRUCache cache(2);
cache.put(1, 1);
cache.put(2, 2);
cout << cache.get(1) << endl; // 输出: 1
cache.put(3, 3); // 由于缓存容量已满,移除key 2和对应的缓存项
cout << cache.get(2) << endl; // 输出: -1
cache.put(4, 4); // 由于缓存容量已满,移除key 1和对应的缓存项
cout << cache.get(1) << endl; // 输出: -1
cout << cache.get(3) << endl; // 输出: 3
cout << cache.get(4) << endl; // 输出: 4
return 0;
}