之前在学习操作系统内存管理的时候接触过LRU,但是也没想过用C++来模拟LRU缓存机制,可是在刷题的时候,碰到了这一题(leetcode第146题:
链接: https://leetcode-cn.com/problems/lru-cache/,觉得很有意思,而且用C++11模拟实现的代码可以说很优雅,所以写篇博文,纪念一下!
LRU算法的理念
LRU即Least Recently Used的缩写,最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。
大致理念就是:
如果某数据项被访问,则推断该数据项再次被访问的几率很大,于是把数据项移动到最容易访问到的位置,如链表头;
如果需要插入某数据项,先检查设定的内存有没有满,满了就删除链表尾部的数据项(也就是很久都没有被访问的数据项),再在链表头部插入该数据项,如果内存没满,就直接在链表头插入数据项。
分析
选择std::list和std::unordered_map作为基础的数据结构,哈希表能保证O(1)的时间内查找节点,而双链表的插入、删除效率高,保证了LRU的查找、插入、删除操作都有较高的性能。
具体细节
1 越靠近链表头,说明该数据项越近被访问,越靠近链表尾,该数据项离上次访问时间越久;
2 访问数据项时,如果数据项存在,则把该数据项移动到链表头,同时更新哈希表中的该数据项的地址;
3 插入数据项时,如果设定的内存值已经满了,则把链表尾,及离上次访问最久的数据项删除,同时在哈希表中删除这一项,数据项插入链表头。
接下来是把上面思路翻译成代码:
class LRUCache {
private:
struct cachenode{
int key;
int value;
cachenode(int k,int v