🏆个人主页:企鹅不叫的博客
🌈专栏
- C语言初阶和进阶
- C项目
- Leetcode刷题
- 初阶数据结构与算法
- C++初阶和进阶
- 《深入理解计算机操作系统》
- 《高质量C/C++编程》
- Linux
⭐️ 博主码云gitee链接:代码仓库地址
⚡若有帮助可以【关注+点赞+收藏】,大家一起进步!
💙系列文章💙
【C++高阶数据结构】并查集
【C++高阶数据结构】图
文章目录
- 💙系列文章💙
- 💎一、概念
- 💎二、OJ
💎一、概念
缓存空间满了之后,更新数据,我要进入,谁出去呢?
LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法。,将最近最少被使用的算法替换出去。(包括读和写)
💎二、OJ
LRU缓存
思路:要调整_LRUList中key的位置到头部,更新顺序
但是我们不知道数据在哪里,只能遍历查找,这个就变成了O(N)
我们找到了数据,我们还需要知道在链表中的位置
所以我们下面用了unorder_map<int,iterator>作为映射,记录当前的key在我们链表中对应的位置
然后用一个list<int,int>来记录我们题目要求的<key,value>class LRUCache { public: LRUCache(int capacity) :_capacity(capacity){ } int get(int key) { //返回_hashmap中存key的迭代器 auto ret=_hashMap.find(key); //如果存在 if(ret !=_hashMap.end()) { //更新key对应的值的位置 //ret的second是对应的值在链表里面的迭代器的位置 LtIter it=ret->second; //splice 转移节点 _LRUList.splice(_LRUList.begin(),_LRUList,it); //ret->second找到的是在链表中的迭代器的位置再->second就是找到第二个元素也就是存的具体的数据 return ret->second->second; } else { return -1; } } void put(int key, int value) { //1、新增 //2、更新 auto ret=_hashMap.find(key); //如果当前的缓存中并没有存过这个ret if(ret ==_hashMap.end()) { //如果满了,就需要先删除LRU的数据 if(_capacity==_hashMap.size()) { //根据题目的示例,我们需要删除尾部的数据 pair<int,int> back=_LRUList.back(); //根据back.first也就是键值在map中删除 _hashMap.erase(back.first); //删除链表的最后一个节点 _LRUList.pop_back(); } //将新的键值添加到我们的链表最前面 _LRUList.push_front(make_pair(key,value)); //map中存的是key值和对应的在链表中的迭代器 _hashMap[key]=_LRUList.begin(); } //如果当前的缓存中已经存过了这个ret else{ //更新key对应的值的位置 //找到这个key值在链表中对应的位置 LtIter it=ret->second; //更新这个key对应的键值 it->second=value;//更新 //splice 转移节点 //将这个刚刚访问过的结点转移到链表的头部 _LRUList.splice(_LRUList.begin(),_LRUList,it); } } private: //hash保证查找更新是O(1) typedef list<pair<int,int>>::iterator LtIter; unordered_map<int,LtIter>_hashMap; //LRU 假设尾部的数据就是最近最少用 list<pair<int,int>> _LRUList; //最大容量 size_t _capacity; };