高阶数据结构之LRU Cache

news2024/9/27 7:22:49

文章目录

  • 什么是LRU Cache?
  • LRU Cache的实现
    • JDK中自带的数据结构
    • 模拟实现LRU Cache(双向链表+哈希表)

什么是LRU Cache?

        LRU的全称是“Least Recently Used”的缩写,表示最近最少的使用,是一种Cache替换算法;而Cache其实就类似与我们所说的缓存,Cache的容量是有限的,当容量用完之后,如果又有新的内容需要添加进来的时候,就需要挑选并舍弃原有的部分内容,进而腾出空间来存放新的内容。
        总而言之,LRU Cache的替换原则就是将最近最少使用的内容替换掉。

LRU Cache的实现

        实现LRU Cache的方法和思路有很多,但是要保持高效的put和get,比如说要使时间复杂度为O(1)的话,那么只有一种方法(本章所总结的)— 使用双向链表和哈希表实现(最高效、最经典),原因是使用双向链表可以实现任意位置的插入和删除都保持在O(1)的时间复杂度,使用哈希表可以作为缓存,对其进行增删改查的时间复杂度也是保持在O(1)的。

JDK中自带的数据结构

        在自己模拟实现LRU Cache之前,先来简单总结一下JDK中自带的实现LRU Cache的数据结构。

        JDK中,需要使用util包下的LinkedHashMap类。
在这里插入图片描述
        基于插入顺序:这其实就相当于一个单调队列,并没有将最近访问的元素放到双向链表的最后。
        基于访问顺序:一般情况下都是使用这种,原因是这种才是真正意义上的LRU Cache。

LRU Cache的类型题:LRU缓存

class LRUCache extends LinkedHashMap<Integer, Integer>{
    public int capacity;

    public LRUCache(int capacity) { 
        super(capacity, 0.75f, true);
        this.capacity = capacity;
    }
    
    public int get(int key) {
        return super.getOrDefault(key, -1);
    }
    
    public void put(int key, int value) {
        super.put(key, value);
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
        return size() > capacity;
    }
}

模拟实现LRU Cache(双向链表+哈希表)

import java.util.HashMap;
import java.util.Map;

public class MyLRUCache {
    static class DLinkNode{
        public int key;
        public int value;
        public DLinkNode prev;
        public DLinkNode next;

        public DLinkNode(){

        }

        public DLinkNode(int key, int value){
            this.key = key;
            this.value = value;
        }
    }

    public DLinkNode head;  //双向链表的头结点
    public DLinkNode tail;  //双向链表的尾结点
    public int usedSize;  //当前链表中的有效节点个数
    public Map<Integer, DLinkNode> map;
    public int capacity;  //容量

    public MyLRUCache(int capacity){
        this.head = new DLinkNode();
        this.tail = new DLinkNode();
        this.map = new HashMap<>();
        this.capacity = capacity;
        head.next = tail;
        tail.prev = head;
    }

    //存储元素
    public void put(int key, int val){
        //查找key是否被存储过
        DLinkNode node = map.get(key);
        if(node == null){
            DLinkNode dLinkNode = new DLinkNode(key, val);
            map.put(key, dLinkNode);
            addToTail(dLinkNode);
            usedSize++;
            if(usedSize > capacity){
                map.remove(head.next.key);
                removeNode(head.next);
                usedSize--;
            }
        }else{
            node.value = val;
            moveToTail(node);
        }
    }

    //将当前节点移到尾巴节点
    private void moveToTail(DLinkNode node) {
        removeNode(node);
        addToTail(node);
    }

    //删除指定节点
    private void removeNode(DLinkNode node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    //添加节点到链表的尾部
    private void addToTail(DLinkNode node) {
        tail.prev.next = node;
        node.prev = tail.prev;
        node.next = tail;
        tail.prev = node;
    }

    //访问元素
    public int get(int key){
        DLinkNode node = map.get(key);
        if(node == null){
            return -1;
        }else{
            moveToTail(node);
            return node.value;
        }
    }
}

        以上代码仅供参考。

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

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

相关文章

机器学习和深度学习综述

机器学习和深度学习综述 1. 人工智能、机器学习、深度学习的关系 近些年人工智能、机器学习和深度学习的概念十分火热&#xff0c;但很多从业者却很难说清它们之间的关系&#xff0c;外行人更是雾里看花。在研究深度学习之前&#xff0c;先从三个概念的正本清源开始。概括来说…

2022-2-23作业

一、通过操作Cortex-A7核&#xff0c;串口输入相应的命令&#xff0c;控制LED灯进行工作 1.例如在串口输入led1on,开饭led1灯点亮 2.例如在串口输入led1off,开饭led1灯熄灭 3.例如在串口输入led2on,开饭led2灯点亮 4.例如在串口输入led2off,开饭led2灯熄灭 5.例如在串口输…

关于性能测试,你不可不知的内容

目录 1、性能测试概述 2、常见的性能测试指标 2.1、并发 2.2、响应时间 2.3、事务 2.3.1、事务响应时间 2.3.2、每秒事务通过数&#xff08;TPS&#xff09; 2.4、点击率 2.5、吞吐量 2.6、资源利用率 3、性能测试分类 3.1、一般性能测试 3.2、负载测试 3.3、压力…

虹科Dimetix激光测距仪在锯切系统中的应用

HK-Dimetix激光测距仪——锯切系统应用 许多生产设施&#xff0c;例如金属服务中心&#xff0c;使用切割锯将每个客户的订单切割成一定长度。定长切割过程通常涉及卷尺和慢跑锯的传送带。但更简单的替代方法是使用虹科Dimetix非接触式激光距离传感器。 为了切断大长度的棒材&…

Day898.Join语句执行流程 -MySQL实战

Join语句执行流程 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于Join语句执行流程的内容。 在实际生产中&#xff0c;关于 join 语句使用的问题&#xff0c;一般会集中在以下两类&#xff1a; 不让使用 join&#xff0c;使用 join 有什么问题呢&#xff1f;如果有…

1+1>2 ?多数据源关联分析系列…

数据表连接的 join 操作&#xff0c;相信大家都不陌生吧&#xff1f;在数据分析时&#xff0c;经常需要对多个不同的数据源进行关联操作&#xff0c;因此各类数据库的 SQL 语言都包含了丰富的 join 语句&#xff0c;以支持批计算关联。而在金融的业务场景中&#xff0c;流数据实…

系统崩溃如何恢复数据?4步,教您快速抢救丢失的数据

电脑保存着很多个人文件和数据&#xff0c;如果碰到电脑系统崩溃&#xff0c;可能会导致文件无法访问&#xff0c;甚至我们的数据会发生丢失的情况。系统崩溃如何恢复数据&#xff1f;我们先来了解下Windows操作系统发生崩溃的常见原因&#xff1a;一次性打开太多软件&#xff…

AG9300方案替代|替代AG9300设计Type-C转VGA方案|CS5260设计原理图

AG9300方案替代|替代AG9300设计Type-C转VGA方案|CS5260设计原理图 安格 AG9300是一款实现USB TYPE-C到VGA数据的单片机解决方案转换器。ALGOLTEK AG9300支持USB Type-C显示端口交替模式&#xff0c;AG9300可以将视频和音频流从USB Type-C接口传输到VGA端口。在AG9300&#xff0…

LeetCode 707. 设计链表

LeetCode 707. 设计链表 难度&#xff1a;middle\color{orange}{middle}middle 题目描述 设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性&#xff1a;valvalval 和 nextnextnext。valvalval 是当前节点的值&#xff0c;nextnextnext 是指向下…

FastCGI sent in stderr: "PHP message: PHP Fatal error

服务器php7.2卸载安装7.4之后,打开网站一直无法访问,查看nginx错误日志发现一直报这个错误:2023/02/23 11:12:55 [error] 4735#0: *21 FastCGI sent in stderr: &#xff02;PHP message: PHP Fatal error: Uncaught ReflectionException: Class translator does not exist in …

OpenGL超级宝典学习笔记:原子计数器

前言 本篇在讲什么 本篇为蓝宝书学习笔记 原子计数器 本篇适合什么 适合初学Open的小白 本篇需要什么 对C语法有简单认知 对OpenGL有简单认知 最好是有OpenGL超级宝典蓝宝书 依赖Visual Studio编辑器 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#…

比特数据结构与算法(第四章_中)堆的分步构建

不清楚堆的概念和性质公式可以先到上一篇看看链接&#xff1a;比特数据结构与算法&#xff08;第四章_上&#xff09;树和二叉树和堆的概念及结构_GR C的博客-CSDN博客堆的逻辑结构是完全二叉树&#xff0c;物理&#xff08;存储&#xff09;结构是数组1.完整Heap.h和以前学的数…

计算机网络概述 第一部分

前言 为了准备期末考试&#xff0c;同时也是为了之后复习方便&#xff0c;特对计算机网络的知识进行了整理。本篇内容大部分是来源于我们老师上课的ppt。而我根据自己的理解&#xff0c;将老师的PPT整理成博文的形式以便大家复习查阅&#xff0c;同时对于一些不是很清楚的地方…

centos7搭建svn配置

基本概述 Apache Subversion&#xff08;简称SVN&#xff0c;svn&#xff09;&#xff0c;一个开放源代码的版本控制系统&#xff0c;相较于RCS、CVS&#xff0c;它采用了分支管理系统&#xff0c;它的设计目标就是取代CVS。互联网上很多版本控制服务已从CVS转移到Subversion。…

【Vue3源码】第五章 ref的原理 实现ref

【Vue3源码】第五章 ref的原理 实现ref 上一章节我们实现了reactive 和 readonly 嵌套对象转换功能&#xff0c;以及shallowReadonly 和isProxy几个简单的API。 这一章我们开始实现 ref 及其它配套的isRef、unRef 和 proxyRefs 1、实现ref 接受一个内部值&#xff0c;返回一…

3款实用又强的软件,值得收藏,不妨试试

1、白描 白描是一款高效准确的OCR文字识别、翻译与文件扫描软件&#xff0c;文字识别、表格识别转Excel、识别后翻译、文件扫描等功能&#xff0c;都非常方便&#xff0c;免费使用无任何广告。白描可以自动识别文档边界&#xff0c;生成清晰的扫描件&#xff0c;高效批量处理文…

Java8 Stream流Collectors.toMap当key重复时报异常(IllegalStateException)

一、问题 在使用Collectors.toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper)&#xff08;两个参数的&#xff09;时&#xff0c;如果 key 有重复&#xff0c;则会报异常&#xff08;IllegalStateException…

工赋开发者社区 | (案例)中译语通:差别化纺纱柔性智慧工厂

中译语通&#xff1a;差别化纺纱柔性智慧工厂01应用成效中译语通科技股份有限公司是一家大数据和人工智能高科技公司。在机器翻译、跨语言大数据、产业链科技、科研数据分析、数字城市和工业互联网等领域拥有自主研发的先进系统平台&#xff0c;能够为全球企业级用户提供全方位…

[oeasy]python0091_仙童公司_八叛逆_intel_8080_altair8800_牛郎星

编码进化 个人电脑 计算机 通过电话网络 进行连接 极客 利用技术 做一些有趣的尝试 极客文化 是 认真研究技术的 文化 计算机 不再是 高校和研究机构高墙里面的 神秘事物而是 生活中常见的 家用电器 ibm 蓝色巨人脚步沉重 dec 小型机不断蚕食低端市场甚至组成网络干掉大型机…

【仔细理解】计算机视觉基础1——特征提取之Harris角点

Harris角点是图像特征提取中最基本的方法&#xff0c;本篇内容将详细分析Harris角点的定义、计算方法、特点。 一、Harris角点定义 在图像中&#xff0c;若以正方形的小像素窗口为基本单位&#xff0c;按照上图可以将它们划分三种类型如下&#xff1a; 平坦区域&#xff1a;在任…