当前位置: 首页 > news >正文

高阶数据结构学习——LRU Cache

文章目录

  • 1、了解LRU Cache(Least Recently Used缩写)
  • 2、代码实现


1、了解LRU Cache(Least Recently Used缩写)

Cache是缓存,在磁盘和内存之间,内存和寄存器之间都存在,CPU和内存之间存在三级缓存,是一个三层结构。缓存用于两个速度不一致的硬件之间,提高效率用。缓存空间有限,满了以后,新数据要进入,旧数据应当怎么办?操作系统中有个热数据概念,意思是经常被使用的数据,可能放进缓存就被拿出来,再次放进后又被拿出来使用,对应的,也有很少被使用的,也就是LRU的意思,缓存满了后,新数据进来,这些很少被使用的就出去。

设计一个LRU Cache不难,设计一个高效的,任意操作都是O(1)的LRU Cache不简单,但只有这样才能满足要求。LRU Cache最主要的操作是get和put,这两个接口必须以O(1)的时间复杂度进行。

2、代码实现

看一个题

146. LRU 缓存

在这里插入图片描述
在这里插入图片描述

看在不在,可以看地址是否在缓存中。整个操作有查找,更新,新增。虽然可以用unordered_map作为缓存,做到查找,更新都O(1),但如何找到LRU?这涉及到顺序问题,还有时间问题,这里的解决办法就是用vector或list来控制LRU,比如list,在这个list里,让处于尾部就是最久未被使用的,用一个数据就把它提到头部,list<pair<int, int>> _LRUList。但这两个结合还是做不到O(1)。因为更新时无法做到O(1),更新时可以直接修改map里的数据,但在list中更新时需要先找到这个数据再放到头部,所以不是O(1)。

以上问题的解决办法是找到key时,就同时找到key对应存储数据在list中的位置。把map中value的类型换成list的迭代器,这样map[key]中存的就是一个指针,指向list中的对应的元素,如果要使用这个数据时就用指针把它拿出来,然后头插即可。

private:typedef list<pair<int, int>>::iterator LtIter;unordered_map<int, LtIter> _hashMap;list<pair<int, int>> _LRUList;
class LRUCache {
public:LRUCache(int capacity) :_capacity(capacity){}int get(int key) {auto ret = _hashMap.find(key);if(ret != _hashMap.end()){//更新key对应值的位置LtIter it = ret->second;//方案1: erase + push_front 更新迭代器,原迭代器失效//方案2: list的splice接口可以转移节点_LRUList.splice(_LRUList.begin(), _LRUList, it);return ret->second->second;//第一个second对应迭代器,第二个second对应list的pair}else{return -1;}}void put(int key, int value) {//1、新增//2、更新auto ret = _hashMap.find(key);if(ret == _hashMap.end())//新增{if(_capacity == _hashMap.size()){pair<int, int> back = _LRUList.back();_hashMap.erase(back.first);_LRUList.pop_back();  }_LRUList.push_front(make_pair(key, value));_hashMap[key] = _LRUList.begin();}else//更新{LtIter it = ret->second;it->second = value;_LRUList.splice(_LRUList.begin(), _LRUList, it);}}
private:typedef list<pair<int, int>>::iterator LtIter;unordered_map<int, LtIter> _hashMap;list<pair<int, int>> _LRUList;size_t _capacity;
};

结束。

http://www.lryc.cn/news/217628.html

相关文章:

  • 代码冲突解决
  • c/c++程序的内存开辟时 的内存情况
  • 【linux常用命令+vi编辑器_2023.11.3】
  • okhttp post请求 header post参数加密遇到的两个问题
  • 什么是Webpack的loader和plugin?它们的作用是什么?
  • ESXi for ARM 最新下载地址
  • 2. 网络之网络编程
  • 工作数字化的中国历程 | 从 OA 到 BPM 到数字流程自动化
  • 6-1 二叉排序树查找操作
  • 服务上千家企业,矩阵通2.0重磅上线,全链路管理新媒体矩阵
  • 【代码随想录】算法训练计划11
  • Jmeter之JSR223
  • c++23中的新功能之十八新增的属性
  • 动手学深度学习:1.线性回归从0开始实现
  • 【计算机网络】应用层
  • python 深度学习 解决遇到的报错问题9
  • 能源管理系统为什么选择零代码开发平台?
  • 【LeetCode】剑指 Offer Ⅱ 第8章:树(12道题) -- Java Version
  • 利用maven的dependency插件将项目依赖从maven仓库中拷贝到一个指定的位置
  • 在Flask中实现文件上传七牛云中并下载
  • 【Linux】centOS7安装配置及Linux的常用命令---超详细
  • 【ES专题】ElasticSearch搜索进阶
  • 【iOS免越狱】利用IOS自动化WebDriverAgent实现自动直播间自动输入
  • Python基础入门例程28-NP28 密码游戏(列表)
  • 乌班图 Linux 系统 Ubuntu 23.10.1 发布更新镜像
  • Java金字塔、空心金字塔、空心菱形
  • 前端 | (十四)canvas基本用法 | 尚硅谷前端HTML5教程(html5入门经典)
  • 206.反转链表
  • SpringBoot项目从resources目录读取文件
  • SQL实现根据时间戳和增量标记IDU获取最新记录和脱IDU标记