【数据结构与算法】LRU Cache

news2024/11/16 16:48:56

🌠作者:@阿亮joy.
🎆专栏:《数据结构与算法要啸着学》
🎇座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根
在这里插入图片描述


目录

    • 👉LRU Cache👈
      • 什么是LRU Cache
      • LRU Cache的实现
      • LRU 缓存
    • 👉总结👈

👉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)。

在这里插入图片描述

LRU 缓存

在这里插入图片描述

splice 函数可以转移链表中的节点

在这里插入图片描述

哈希表能够保证查找和更新 key 值对应的 value 的时间复杂度为 O(1),也就是能保证 get。那关键点是如何保证 LRU 呢?如果 key 值在哈希表中,那么就 key 值就是最经常访问的值,需要将它放到双向链表的头部(假设双向链表尾部的数据是最近最少用的数据)。因为我们并不知道 key 值在双向链表中的位置,那就无法做到 O(1) 的时间复杂度将 key 值放到链表的头部。那如何解决呢?我们做到的是找到 key 值,就能够找到 key 值在双向链表中的位置。那么我们可以让哈希表存的是 key 值和 key 值在双向链表中的位置(迭代器),双向链表存储是键值对pair<key, value>,这样就能够保证 LRU Cache 了(通过 splice 来调整 key 值在链表中的位置)。

在这里插入图片描述

class LRUCache 
{
public:
    LRUCache(int capacity) 
        : _capacity(capacity)
    {}
    
    int get(int key) 
    {
        auto ret = _hashMap.find(key);
        // 哈希表中有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())   // 哈希表中没有key
        {
            // 满了,先删除最近最少用的数据
            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对应值的位置
            // 1.erase + push_front 更新迭代器,原迭代器失效
            // 2.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;
    // LRU假设链表尾部的数据是最近最少用的数据
    // _LRUList中存储的是键值对pair
    list<pair<int, int>> _LRUList;
    size_t _capacity;   // 容量
};

在这里插入图片描述

👉总结👈

本篇博客主要讲解了什么是 LRU Cache 以及如何设计 LRU Cache等。那么以上就是本篇博客的全部内容了,如果大家觉得有收获的话,可以点个三连支持一下!谢谢大家!💖💝❣️

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/192792.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年房地产融资模式研究报告

第一章 概况 融资&#xff0c;英文为 Financing&#xff0c;指为支付超过现金或转账的购货款而采取的货币交易手段&#xff0c;或者为取得特定资产而筹集资金所采取的货币手段。融资通常指货币资金的特有者和需求者之间&#xff0c;直接或间接地进行资金融通的活动。 广义的融…

【操作系统】多线程与多进程通信之深入理解【2023.01.31】

基本概念 首先&#xff0c;假设这么一个场景&#xff0c;进程A有线程Thread_A1和线程Thread_A2&#xff0c;进程B有线程Thread_B1和Thread_B2。举个例子&#xff0c;系统中进程的内存是独立的&#xff0c;也就是一台内存为4G的计算机&#xff0c;除了系统占用的1G部分&#xf…

Oracle——分析函数

文章目录前言介绍demo案例测试测试前的准备rank()dense_rank()row_number()前言 分析函数在oracle中比较常见&#xff0c;但用的不多&#xff0c;今天有幸碰见&#xff0c;索性做一次使用的总结说明。 介绍 oracle中的分析函数&#xff0c;常见的有下面的三种&#xff1a; r…

四季度亏损扩大,Meta Reality Labs近4年财报营收汇总

2月2日青亭网报道&#xff0c;Meta今天发布了2022财年第四季度财报、全年财报。根据22年四季度财报信息显示&#xff0c;Reality Labs业务部门营收营收7.27亿美元&#xff0c;同比&#xff08;21年四季度8.77亿美元&#xff09;要下降17.1%&#xff1b;净亏损42.79亿美元&#…

R语言多元数据统计分析在生态环境中的应用

生态环境领域研究中常常面对众多的不同类型的数据或变量&#xff0c;当要同时分析多个因变量&#xff08;y&#xff09;时需要用到多元统计分析&#xff08;multivariate statistical analysis&#xff09;。多元统计分析内容丰富&#xff0c;应用广泛&#xff0c;是非常重要和…

关于java中的BigInteger

文章目录关于BigInteger类BigInteger的构造方法BigInteger方法使用示例算术运算API转换为基本数据类型的方法小结关于BigInteger类 BigInteger类是用于解决整型类型&#xff08;含基本数据类型及对应的包装类&#xff09;无法表示特别大的数组及运算问题。 即使是占用字节数最…

HTB_Weak RSA

文章目录信息收集RSA 算法题目解密信息收集 下载&#xff0c;解压 (密码都是hackthebox) enc后缀的文件是一种加密文件&#xff0c;打开为乱码&#xff0c;key.pub内容如下&#xff0c;是 RSA 加密算法的公钥 -----BEGIN PUBLIC KEY----- MIIBHzANBgkqhkiG9w0BAQEFAAOCAQwAMI…

CISP信息安全认证考试都考什么?

CISP考试是目前热门的信息安全认证考试&#xff0c;很多刚刚开始了解CISP的朋友&#xff0c;比较关心关于CISP考试内容的相关问题&#xff0c;今天就由中培小编带大家一起去看看CISP认证考试究竟都考哪些内容&#xff1f;首先来看一下试卷结构考试时间&#xff1a;120分钟考试题…

CSS图标与链接

目录 如何添加图标 Font Awesome 图标 实例 Bootstrap 图标 实例 Google 图标 实例 为图标添加样式或颜色 设置链接样式 实例 实例 文本装饰 实例 背景色 实例 链接按钮 实例 更多实例 如何添加图标 向 HTML 页面添加图标的最简单方法是使用图标库&#xff0…

【Less】全局样式重复注入问题

// package.json {"less": "^4.1.3","vite": "^3.1.0", }参考&#xff1a; [less/sass]如何避免因公共模块导致生成重复css代码解决 Vue CSS 样式重复载入&#xff0c;为 Vue 添加全局 less 或 sass 基础样式库【不是本篇解决方法&am…

vue3学习笔记之router(router4 + ts)

文章目录Vue Router1. 基本使用router-view2. 路由跳转2.1 router-link2.2 编程式导航2.3 replace3. 路由传参4. 嵌套路由5. 命令视图6. 重定向和别名6.1 重定向6.2 别名7. 路由守卫7.1 全局前置守卫7.2 全局后置守卫案例&#xff1a;加载滚动条8. 路由元信息9. 路由过渡动效10…

瞧不上alert 老古董?使用alert实现一个精美的弹窗

曾几何时alert陪伴了我很多歌日日夜夜&#xff0c;但现在人们越来越追求高端的技术&#xff0c;其实慢慢的我也都快淡忘了前端的世界里还有alert这么一个伟大的成员。 目录 一、为什么抛弃了alert? 1. 不同浏览器的表现 2. 第三方组件的使用 3. 代码意识的控制 二、用al…

2023年浏览器哪个好用速度快,看这一篇就够了

在网络覆盖的社会&#xff0c;不管走到哪里&#xff0c;都能上网浏览新闻、看热点资讯。浏览器是用户上网浏览的必要软件之一&#xff0c;它决定这用户浏览网页的速度和习惯。那么&#xff0c;2023年什么浏览器好用稳定速度快&#xff1f;目前优秀的浏览器有很多&#xff0c;但…

HDFS常用命令汇总

HDFS常用命令汇总一、前言信息二、帮助信息查看1、查看帮助信息2、帮助文档&#xff08;附带命令的详细说明&#xff09;三、常用命令1、创建目录2、查看目录下的内容3、上传文件4、上传并删除源文件5、查看文件内容6、查看文件开头内容7、查看文件末尾内容8、下载文件9、合并下…

ceph中报错“ clock skew detected on mon.ceph2, mon.ceph3”

自己搭建的ceph集群&#xff0c;显示时间不同步:clock skew detected on mon.ceph2, mon.ceph3但是查看chrony进程已经启动&#xff0c;ceph配置文件中,如下参数也已经配置&#xff0c;查看chrony.conf配置文件发现&#xff0c;同步源没有修改过&#xff0c;默认的于是修改ceph…

面试官的几句话,差点让我挂在HTTPS上

面试官的几句话&#xff0c;差点让我挂在HTTPS上 目录&#xff1a;导读 一、HTTP 协议 二、HTTPS 协议 三、使用 HTTP 协议还是 HTTPS 协议呢&#xff1f; 四、HTTP 协议和 HTTPS 协议的区别 作为软件测试&#xff0c;大家都知道一些常用的网络协议是我们必须要了解和掌握…

MySQL jdbc 反序列化分析

0x01 前言听师傅们说这条链子用的比较广泛&#xff0c;所以最近学一学&#xff0c;本来是想配合着 tabby 或是 codeql 一起看的&#xff0c;但是 tabby 的环境搭建一直有问题&#xff0c;耽误了很久时间&#xff0c;所以就直接看了0x02 JDBC 的基础• 本来不太想写这点基础的&a…

敏捷与DevOps的区别,知异同,发准力

​图片来自Robert Martin《敏捷整洁之道》。敏捷DevOps生命之环&#xff0c;由内到外&#xff0c;第一圈&#xff1a;Kent Beck&#xff0c;第二圈&#xff1a;Uncle Bob&#xff0c;第三圈&#xff1a;Mike Cohn。三圈由内到外分别是&#xff1a;编程、工程&#xff08;大致对…

STM32读取24位模数转换(24bit ADC)芯片TM7711数据

STM32读取24位模数转换&#xff08;24bit ADC&#xff09;芯片TM7711数据 TM7711是一款国产低成本24位ADC芯片&#xff0c;常用于与称重传感器配合实现体重计的应用。这里介绍STM32读取TM7711的电路和代码实现。TM7711与HX710A是兼容的芯片&#xff0c;而与HX711在功能上有所不…

B+树的概念

与分块查找和B树类似。 一棵m阶的B树需满足如下条件: 每个分支结点最多有m棵子树非叶子结点的根结点至少有两棵子树&#xff0c;其他结点至少有⌈m/2⌉\lceil m/2\rceil⌈m/2⌉棵子树结点的子树个数与关键字个数相等关键字全部存储在叶子结点中。所有指向对应记录的指针也存储…