📅  最后修改于: 2023-12-03 15:21:35.383000             🧑  作者: Mango
LRU Cache 是 Least Recently Used(最近最少使用)缓存的缩写。LRU Cache 是一种缓存策略,通过删除最近最少使用的条目来腾出空间。
使用 LRU Cache 的目的是在需要缓存数据时,保留最常使用的数据,同时删除不常使用的数据,保持缓存的大小不变。这样可以提高性能,减少内存资源的浪费。
实现 LRU Cache 的数据结构通常由哈希表和双向链表组成。其中哈希表用于快速查找数据,双向链表用于维护数据的顺序。
哈希表中存储的数据结构为:
class Node {
public:
int key, val;
Node* prev;
Node* next;
Node(int _key, int _val):key(_key), val(_val), prev(nullptr), next(nullptr){}
};
其中 key 表示节点的键,val 表示节点的值,prev 和 next 分别表示前驱和后继节点指针。
双向链表的数据结构为:
class DoubleLinkedList {
private:
Node* head;
Node* tail;
int size;
public:
DoubleLinkedList():size(0){
head = new Node(0, 0);
tail = new Node(0, 0);
head->next = tail;
tail->prev = head;
}
void moveToTail(Node* node){
node->prev->next = node->next;
node->next->prev = node->prev;
node->next = tail;
node->prev = tail->prev;
tail->prev->next = node;
tail->prev = node;
size++;
}
Node* removeHead(){
Node* removeNode = head->next;
head->next = removeNode->next;
removeNode->next->prev = head;
size--;
return removeNode;
}
int getSize(){
return size;
}
};
其中 head 和 tail 分别表示双向链表的头结点和尾结点。moveToTail() 方法将一个节点移到表尾,removeHead() 方法删除表头节点,getSize() 方法返回双向链表的长度。
LRU Cache 类的设计如下:
class LRUCache {
private:
unordered_map<int, Node*> cache;
DoubleLinkedList linkedList;
int capacity;
public:
LRUCache(int capacity): capacity(capacity){}
int get(int key){
auto it = cache.find(key);
if(it == cache.end()){
return -1;
}
linkedList.moveToTail(it->second);
return it->second->val;
}
void put(int key, int value){
auto it = cache.find(key);
if(it != cache.end()){
it->second->val = value;
linkedList.moveToTail(it->second);
return;
}
if(linkedList.getSize() == capacity){
cache.erase(linkedList.removeHead()->key);
}
Node* node = new Node(key, value);
cache[key] = node;
linkedList.moveToTail(node);
}
};
其中 cache 存储键值与节点的映射关系,linkedList 为双向链表对象,capacity 表示 LRU Cache 的容量。
get() 方法用于获取一个键对应的值,如果存在则将节点移到表尾,如果不存在则返回 -1。
put() 方法用于插入或更新一个键值对。如果键存在,则更新键对应的值,移到表尾,否则插入新节点,如果 LRU Cache 已满则删除表头节点,并从 cache 中删除对应的键。
LRU Cache 的应用场景很多,比如操作系统中的页表、web 应用程序中的数据缓存等。在实际中,对于访问模式较为集中的应用场景,可以使用 LRU Cache 提高性能,更好地利用系统资源。