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

数据结构 之 【LRU Cache】(注意list的splice接口函数)

目录

1.什么是LRU Cache

2.LRU Cache的简单实现

成员变量

构造函数

查询数据(get(key))

插入/更新数据(put(key, value))


1.什么是LRU Cache

  • LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法。
  • 什么是 Cache?狭义的Cache指的是位于CPU和主存间的快速RAM, 通常它不像系统主存那样使用 DRAM技术,而使用昂贵但较快速的SRAM技术。 广义上的Cache指的是位于速度相差较大的两种 硬件之间, 用于协调两者数据传输速度差异的结构
  • 除了CPU与主存之间有Cache, 内存与硬盘 之间也有Cache,乃至在硬盘与网络之间也有某种意义上的Cache── 称为Internet临时文件夹或 网络内容缓存等
  • Cache的容量有限,因此当Cache的容量用完后,而又有新的内容需要添加进来时, 就需要挑选 并舍弃原有的部分内容,从而腾出空间来放新内容。LRU Cache 的替换原则就是将最近最少使用 的内容替换掉。其实,LRU译成最久未使用会更形象, 因为该算法每次替换掉的就是一段时间内 最久没有使用过的内容。

2.LRU Cache的简单实现

以讲解这题为切口进行实现

yjy146. LRU 缓存 - 力扣(LeetCode)

  • 成员变量

    //表头元素表示最近最多使用,尾元素表示最近最少使用//链表插入删除O(1),更新LRU效率O(N),先找到,再转移list<pair<int, int>> _LRUlist;typedef list<pair<int, int>>::iterator _Listiterator;unordered_map<int, _Listiterator> _hashMap;//查找更新O(1),LRU不可实现int _capacity;

(1) _capacity表示缓存的容量

(2)

  • 只用unordered_map,查找更新效率为O(1),但是无法记录数据的频率,如果使用引用计数,又需要查找,效率低,难以实现LRU
  • 让链表尾元素表示最近最少使用的数据就可以实现LRU,但是,查找更新的效率为O(N)
  • 所以,_LRUlist存储数据,
    _hashMap实现关键字与链表中关键字对应数据的迭代器一一映射

  • 构造函数

    LRUCache(int capacity) {_capacity = capacity;}

初始化成员变量_capacity 即可

  • 查询数据(get(key)

    int get(int key) {auto it = _hashMap.find(key);//找不到就返回-1if(it == _hashMap.end()) return -1;//找到了,返回之前,更新元素位置_LRUlist.splice(_LRUlist.begin(), _LRUlist, it->second);return it->second->second;}

_hashMap根据关键字key以O(1)的时间效率进行查找,

找不到返回-1,找到了就将数据更新到表头,再返回value值

  • 在 C++ 中,std::list::splice() 是 std::list 的一个高效成员函数,用于在常数时间 O(1) 内移动链表中的元素或整个链表,无需拷贝或析构元素。它通过重新链接链表节点实现
  1. 移动单个节点
    void splice(iterator position, list& other, iterator it);
    • 作用:将 other 链表中的节点 it 移动到当前链表的 position 位置。
    • 要求it 必须是 other 的有效迭代器,position 可以属于 other,但是ji被移动的节点(或范围)不能包含 position 本身(即不能自引用)
  2. 移动整个链表
    void splice(iterator position, list& other);
    • 作用:将 other 链表的所有元素移动到当前链表的 position 位置。
    • 结果other 变为空链表。
  3. 移动一个范围内的节点
    void splice(iterator position, list& other, iterator first, iterator last);
    • 作用:将 other 链表中 [first, last) 范围内的节点移动到当前链表的 position 位置。
    • 注意[first, last) 必须是 other 的有效范围,且不能包含 position 的迭代器(避免自引用)。
  • 插入/更新数据(put(key, value)

void put(int key, int value){auto ret = _hashMap.find(key);//找不到,表头插入,注意删除数据if (ret == _hashMap.end()){//删除数据//头插}else//找到了就更新{}
}

(1)插入、更新数据得先查找

(2)找不到就需要插入数据,但是缓存容量有限,得先考虑删除数据

if (_hashMap.size() == _capacity)
{//链表尾节点元素pair<int, int> back = _LRUlist.back();_hashMap.erase(back.first);_LRUlist.pop_back();
}
  • 将链表尾元素视为最近最少使用的元素,所以删除尾元素
  • 然后头插最新数据
            _LRUlist.push_front(make_pair(key, value));_hashMap[key] = _LRUlist.begin();

(2)找到了就更新value值,同时将数据转移到表头

            ret->second->second = value;_LRUlist.splice(_LRUlist.begin(), _LRUlist, ret->second);

ret->second表示链表中节点的迭代器

http://www.dtcms.com/a/442277.html

相关文章:

  • 专门做封面的网站免费做网站怎么做网站吗
  • 25秋新三上语文1-8单元作文习作指导含填空练习+三年级上册语文各单元习作范文/写作技巧/填空练习+完整电子版可下载打印
  • 拥抱终端:Linux 新手命令行入门指南
  • wordpress 512做网站优化的协议书
  • 设计稿秒出“热力图”:AI预测式可用性测试工作流,上线前洞察用户行为
  • 种完麦子,就往南走
  • 像素时代网站建设手机站设计菏泽网站建设推广
  • python爬虫scrapy框架使用
  • mysql基础操作——库的操作和表的操作
  • 使用springboot2.6、vue2.6以及mysql从0开始搭建个人博客网页
  • MySQL 核心架构解析:从 SQL 层到存储引擎的深度探索
  • 网站建设推广济南兴田德润优惠吗网站推广四个阶段
  • logbuffer 概念及题目
  • 通用定时器的基本介绍与功能概述
  • 洛谷 P14115:[IAMOI R4] 木桶效应 ← 二分
  • Python pip -U参数作用及使用建议
  • python全栈(基础篇)——day03:基础内容(字符串格式化+简单数据类型转换+进制的转换+运算符+实战演示+每日一题)
  • 学网站建设能赚钱吗网上购物哪家质量好
  • 基于ASRPRO的语音对话
  • 女人与狗做网站天津重型网站建设风格
  • 拼图小游戏开发日记 | Day3(已完结)
  • Go 1.25 新特性:正式支持 Git 仓库子目录作为 Go 模块
  • 鸿蒙NEXT Remote Communication Kit:打破设备壁垒,构筑无缝协同体验
  • 那些网站建设的好杭州建站程序
  • 做团购网站企业网站设计调查问卷
  • 基于 RoBERTa + 多策略优化的中文商品名细粒度分类
  • 做翻译兼职的网站是哪个特色的网站建设
  • 山西建设银行招聘网站crm系统的销售管理功能包括
  • 如何在C#中配置ONNX Runtime以确保准确性和目标框位置的正确性?
  • PiscCode使用YOLO识别超大分辨率高清视图实践