您的位置:首页 > 娱乐 > 明星 > 新乡优化_哪里有软件培训班_网络销售推广平台_企业网搭建

新乡优化_哪里有软件培训班_网络销售推广平台_企业网搭建

2025/1/6 17:32:16 来源:https://blog.csdn.net/AAlykk/article/details/143746566  浏览:    关键词:新乡优化_哪里有软件培训班_网络销售推广平台_企业网搭建
新乡优化_哪里有软件培训班_网络销售推广平台_企业网搭建

> 作者:დ旧言~
> 座右铭:松树千年终是朽,槿花一日自为荣。

> 目标:了解什么是LRU Cache,并能简单的模拟实现。

> 毒鸡汤:有些事情,总是不明白,所以我不会坚持。早安!

> 专栏选自:数据结构

> 望小伙伴们点赞👍收藏✨加关注哟💕💕

​一、什么是LRU Cache

LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法。 什么是
Cache?狭义的Cache指的是位于CPU和主存间的快速RAM, 通常它不像系统主存那样使用
DRAM技术,而使用昂贵但较快速的SRAM技术。 广义上的Cache指的是位于速度相差较大的两种
硬件之间, 用于协调两者数据传输速度差异的结构。除了CPU与主存之间有Cache, 内存与硬盘
之间也有Cache,乃至在硬盘与网络之间也有某种意义上的Cache── 称为Internet临时文件夹或
网络内容缓存等。

Cache的容量有限,因此当Cache的容量用完后,而又有新的内容需要添加进来时, 就需要挑选
并舍弃原有的部分内容,从而腾出空间来放新内容。LRU Cache 的替换原则就是将最近最少使用
的内容替换掉。
其实,LRU译成最久未使用会更形象, 因为该算法每次替换掉的就是一段时间内
最久没有使用过的内容。

二、LRU Cache的实现

概念:

实现LRU Cache的方法和思路很多,但是要保持高效实现O(1)的put和get,那么使用 双向链表和 哈希表 的搭配是最高效和经典的。使用双向链表是因为双向链表可以实现任意位置O(1)的插入和删除,使用哈希表是因为哈希表的增删查改也是O(1)。

说明:

  • 保证查找和更新 key值对应的value的时间复杂度为O(1), 也就是保证了get,但是不能保证LRU,因为无法从哈希表中知道知道key值在双向链表中的位置,因此无法用O(1)的时间复杂度来将key值放到链表的头部。
  • 我们可以让哈希表中存储key值和key值在双向链表中的位置,因此可以让哈希表中存储key值和key值在双向链表中的位置——迭代器,双向链表存储的是键值对pair<key, value>,这样就可以保证 LRU Cache了。

代码实现:

class LRUCache {
public:LRUCache(int capacity):_capacity(capacity){}int get(int key) {auto ret = _hashMap.find(key);if(ret != _hashMap.end()){//更新key的位置// 1. erase + push_front 更新迭代器, 原迭代器失效// 2. splice 将节点转移到头部ListIterator it = ret->second;_LRUList.splice(_LRUList.begin(), _LRUList, it);return it->second;}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> LRUData = _LRUList.back();_hashMap.erase(LRUData.first);_LRUList.pop_back();}_LRUList.push_front(make_pair(key, value));_hashMap[key] = _LRUList.begin();}else // 更新{// 更新key对应的值ListIterator it = ret->second;it->second = value;//更新key对应值的位置——splice 将节点转移到头部_LRUList.splice(_LRUList.begin(), _LRUList, it);}}
private:typedef list<pair<int, int>>::iterator ListIterator;//哈希表——查找和更新的时间复杂度为O(1),哈希表中存储的是//key和key在_LRUList中的位置(迭代器)unordered_map<int, ListIterator> _hashMap;list<pair<int,int>> _LRUList;size_t _capacity; //容量
};

三、LRU Cache的OJ

LRU缓存. - 力扣(LeetCode)

class LRUCache {
public:LRUCache(int capacity):_capacity(capacity){}int get(int key) {auto ret = _hashMap.find(key);if(ret != _hashMap.end()){//更新key的位置// 1. erase + push_front 更新迭代器, 原迭代器失效// 2. splice 将节点转移到头部ListIterator it = ret->second;_LRUList.splice(_LRUList.begin(), _LRUList, it);return it->second;}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> LRUData = _LRUList.back();_hashMap.erase(LRUData.first);_LRUList.pop_back();}_LRUList.push_front(make_pair(key, value));_hashMap[key] = _LRUList.begin();}else // 更新{// 更新key对应的值ListIterator it = ret->second;it->second = value;//更新key对应值的位置——splice 将节点转移到头部_LRUList.splice(_LRUList.begin(), _LRUList, it);}}
private:typedef list<pair<int, int>>::iterator ListIterator;//哈希表——查找和更新的时间复杂度为O(1),哈希表中存储的是//key和key在_LRUList中的位置(迭代器)unordered_map<int, ListIterator> _hashMap;list<pair<int,int>> _LRUList;size_t _capacity; //容量
};

四、结束语 

今天内容就到这里啦,时间过得很快,大家沉下心来好好学习,会有一定的收获的,大家多多坚持,嘻嘻,成功路上注定孤独,因为坚持的人不多。那请大家举起自己的小手给博主一键三连,有你们的支持是我最大的动力💞💞💞,回见。

​​ 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com