LRU:最近最少使用缓存,实现 LRUCache 类:
- LRUCache(int capacity) :以正整数作为容量capacity,初始化LRU缓存。
- int get(int key):如果关键字 key 存在于缓存中,则返回关键字的值,否则返回-1。
- void put(int key, int value):如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value。如果插入操作导致关键字数量超过 capacity ,则应该逐出最久未使用的关键字。
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。
总是希望最近使用的、最频繁使用的数据存储在比较靠前的位置。于是,LRU 缓存要具备以下特点:
插入某个数据时,它应该被放到 Cache 的最前面
查询某个数据之后,它应该被挪到 Cache 的最前面
插入数据时,如果 Cache 的容量不够时,把 Cache 尾部的数据移出
一个常见的LRU缓存的实现思路是使用哈希表和双向链表结合的方法:
哈希表:
存储键和指向其在双向链表中节点的指针,用于O(1)时间复杂度内查找键。双向链表
: 存储键值对,链表的顺序由元素的使用顺序决定。最近使用的元素被放置在链表的前端,而最少使用的元素则被放置在链表的尾端。
如果考虑线程安全性,就需要用到锁,C++中的mutex,配合std::lock_guard使用。
#include<iostream>
#include <string.h>
#include<mutex>
namespace _LRU{
// 设计一个不限类型的线程安全的LRU,还不让使用STL
template<typename K, typename V>
class Node{
public:
K key;
V value;
Node* prev;
Node* next;
Node(K k, V v):key(k),value(v),prev(nullptr),next(nullptr){
}
};
template<typename K, typename V>
class LRUCache{
public:
LRUCache(int cap) : capacity(cap),size(0){
head = new Node<K,V>(K(),V()