【一】LRU Cache的相关概念
LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法。 什么是Cache?狭义 的Cache指的是位于CPU和主存间的快速RAM, 通常它不像系统主存那样使用DRAM技术,而使用昂贵但较 快速的SRAM技术。 广义上的Cache指的是位于速度相差较大的两种硬件之间, 用于协调两者数据传输速度 差异的结构。除了CPU与主存之间有Cache, 内存与硬盘之间也有Cache,乃至在硬盘与网络之间也有某种 意义上的Cache── 称为Internet临时文件夹或网络内容缓存等。
Cache的容量是有限的,因此当cache的容量用完之后,而又有新的内容需要添加进来时,就需要挑选并且舍弃原有的部分内容,从而腾出空间来释放新的内容,LRU Cache的替换原则就是将最近最少使用的类容去替换掉,其实LRU Cache翻译成最久未使用会更加的贴合形象,因为该算法每次替换掉的就是一段时间内最久没有使用过的内容。
【二】LRU Cache的模拟实现
struct DLinkedNode
{
int key;
int value;
DLinkedNode* prev;
DLinkedNode* next;
DLinkedNode()
:key(0)
,value(0)
,prev(nullptr)
,next(nullptr)
{}
DLinkedNode(int _key, int _value)
:key(_key)
, value(_value)
, prev(nullptr)
, next(nullptr)
{}
};
class LRUCache {
private:
unordered_map<int, DLinkedNode*> cache;
DLinkedNode* head;
DLinkedNode* tail;
int Size;
int Capacity;
public:
LRUCache(int capacity)
{
this->Capacity = capacity;
this->Size = 0;
this->head = new DLinkedNode();
this->tail = new DLinkedNode();
head->next = tail;
tail->prev = head;
}
int get(int key)
{
if (!cache.count(key)) {
return -1;//如果key不存在,则可以直接返回-1
}
DLinkedNode* node = cache[key];//从哈希表中找到它的为止
moveToHead(node);//将其移动到头节点
return node->value;
}
void put(int key, int value)
{
if (!cache.count(key))
{
//如果这个key不存在,那就创立一个新的节点
DLinkedNode* node = new DLinkedNode(key, value);
//添加进哈希表
cache[key] = node;
//添加到双向链表的头部
addToHead(node);
Size++;
if (Size > Capacity) {
DLinkedNode* removed = removeTail();
cache.erase(removed->key);
//一定要删除,防止内存泄露
delete removed;
Size--;
}
}
else {
//如果key存在,就修改它的val值,然后移动到开头
DLinkedNode* node = cache[key];
node->value = value;
moveToHead(node);
}
}
void addToHead(DLinkedNode* node)
{
node->prev = head;
node->next = head->next;
head->next->prev = node;
head->next->next = node;
}
void removeNode(DLinkedNode* node)
{
node->prev->next = node->next;
node->next->prev = node->prev;
}
void moveToHead(DLinkedNode* node)
{
removeNode(node);//移除这个元素
addToHead(node);//向头节点增加这个元素
}
DLinkedNode* removeTail()
{
DLinkedNode* node = tail->prev;
removeNode(node);
return node;
}
};
【三】LUR Cache实现的基本原理
实现LUR Cache的方式有很多,但是我们采用最简单的方式,就是使用哈希表和双向链表的方式来进行实现,使用双向链表是因为双向链表是可以在任意的位置进行插入和删除,使用哈希表是因为哈希表的增删查改也是O(1)。
以上就是这期的全部内容了,如果觉得还可以的话,请一键三连吧,如果哪里有问题还请位于评论区进行斧正。