LRU的原理与实现(java)

news2024/11/19 21:55:41

介绍

LRU的英文全称为Least Recently Used,即最近最少使用。它是一种内存数据淘汰算法,当添加想要添加数据而内存不足时,它会优先将最近一段时间内使用最少的数据淘汰掉,再将数据添加进来。

原理

LRU的原理在介绍中就已经基本说明过了,就是在内存不够用时把最近最少使用的数据淘汰掉,

那么它为什么会这么进行淘汰呢?其主要思想是最近时间内使用的比较多的数据数据在后面的使用中就大概率还会被被使用,而最近使用比较少的数据在后面被使用的概率就比较低。使用这样的淘汰算法,在访问内存时就可以提高内存的命中率,提高整体系统的速度。

下面来举个例子。假设内存中只能存4个数据。我们依次添加了1,2,3,4这4个数据,在添加完后我访问了3和1,随后我继续添加数据,加入一个5,那么此时淘汰的数据为2,因为1和3最近已经使用过了,2时最近一段时间内使用最少的数据。流程如下:

实现

想要使用程序来实现一个简单的LRU算法可以使用单链表。将一个单链表看成我们的内存,每次有数据进来时就在头部添加进来,淘汰时就将单链表尾部的最后一个节点淘汰。当每次访问时就把访问的节点移动到头节点。

首先定义链表节点的结构

    //定义单链表
    public static class Node{
        int val;
        Node next;
        Node(){};
        Node(int val){
            this.val=val;
        };
        Node(int val,Node next){
            this.val = val;
            this.next = next;
        }
    }

随后定义链表的最大容量,和链表的根节点和当前链表中的节点数

    public static int size = 4;
    public static int curSize = 0;
    public static Node root=new Node(0);

再编写向链表添加节点的方法

分为三种情况

情况一:链表未满,那么这就将该节点插入到链表的头部,并将curSize加一。

情况二:添加的节点时链表已满,此时需要我们将链表的最后一个节点淘汰掉,然后该节点插入头部。

    /**
     * 向链表中添加
     * @param val
     */
    public static void LRUAdd(int val){
        if(curSize==0){
            Node node = new Node(val);
            root.next = node ;
            curSize++;
        }
        //链表已满
        else if(curSize==size){
            Node node = new Node(val);
            node.next = root.next;
            root.next = node;
            Node pre = null;
            Node cur = root;
            while (cur.next!=null){
                pre = cur;
                cur=cur.next;
            }
            pre.next = null;
        }else {
            Node node = new Node(val);
            node.next = root.next;
            root.next = node;
            curSize++;
        }
    }

随后编写访问节点的方法,访问某节点时会将该节点直接移动到链表头部。

    public static void LRUGet(int val){
        Node node = root.next;
        Node pre = root;
        while(node!=null){
            if(node.val==val){
                break;
            }
            pre = node;
            node=node.next;
        }
        if(node.next==null){
            Node node1 = new Node();
            node1.next = node;
            node.next = root.next;
            root.next = node;
            pre.next = null;

        }else {
            pre.next = node.next;
            node.next = root.next;
            root.next = node;
        }
        node.toString();
    }

测试例子中的数据:

先添加12345这5个数据,再访问3和2,最后再添加6

可以看到我们成功实现了LRU算法

完成代码

public class Lru {

    public static int size = 4;
    public static int curSize = 0;
    public static Node root=new Node(0);

    public static void main(String[] args) {
        LRUAdd(1);
        LRUAdd(2);
        LRUAdd(3);
        LRUAdd(4);
        LRUAdd(5);
        show();
        LRUGet(3);
        show();
        LRUGet(2);
        show();
        LRUAdd(6);
        show();
    }

    //定义单链表
    public static class Node{
        int val;
        Node next;
        Node(){};
        Node(int val){
            this.val=val;
        };
        Node(int val,Node next){
            this.val = val;
            this.next = next;
        }
    }

    /**
     * 向链表中添加
     * @param val
     */
    public static void LRUAdd(int val){
        if(curSize==0){
            Node node = new Node(val);
            root.next = node ;
            curSize++;
        }
        //链表已满
        else if(curSize==size){
            Node node = new Node(val);
            node.next = root.next;
            root.next = node;
            Node pre = null;
            Node cur = root;
            while (cur.next!=null){
                pre = cur;
                cur=cur.next;
            }
            pre.next = null;
        }else {
            Node node = new Node(val);
            node.next = root.next;
            root.next = node;
            curSize++;
        }
    }

    //访问节点
    public static void LRUGet(int val){
        Node node = root.next;
        Node pre = root;
        while(node!=null){
            if(node.val==val){
                break;
            }
            pre = node;
            node=node.next;
        }
        if(node.next==null){
            Node node1 = new Node();
            node1.next = node;
            node.next = root.next;
            root.next = node;
            pre.next = null;

        }else {
            pre.next = node.next;
            node.next = root.next;
            root.next = node;
        }
        node.toString();
    }
    public static void show(){
        Node node = root.next;
        System.out.println("当前链表为:");
        while(node!=null){
            System.out.print(node.val+" ");
            node = node.next;
        }
        System.out.println("");
    }

}

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

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

相关文章

C++之类和对象(上)

目录 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 4.类的访问限定符及封装 4.1访问限定符 4.2 类的两种定义方式 第一种: 第二种: 4.3封装 5.类的实例化 6.类对象模型 1.面向过程和面向对象初步认识 C语言是面向过程的,…

华为汽车的“计算+通信”电子电气架构

文章目录 整车结构 硬件平台 软件平台 总结展望 整车EEA(电子电气架构),按照博世提出的演进路径,大致可以划分为四个阶段:分布式模块阶段、区域控制阶段、中央计算阶段、云计算阶段。示例如下: 本文选取…

Java8 进阶

Java8 进阶 文章目录 Java8 进阶什么是函数式接口&#xff1f;public interface Supplierpublic interface Consumerpublic interface Predicatepublic interface FunctionJava8 特性总结&#xff1a;一、Function<T, R>二、Consumer<T>三、Supplier<T>四、P…

BUUCTF:BUU UPLOAD COURSE 1[WriteUP]

构造一句话PHP木马 <?php eval(system($_POST[shell])); ?> 利用eval函数解析$shell的值使得服务器执行system命令 eval函数是无法直接执行命令的&#xff0c;只能把字符串当作php代码解析 这里我们构造的木马是POST的方式上传&#xff0c;那就用MaxHacKBar来执行 …

分布式锁实战

4、分布式锁 4.1 、基本原理和实现方式对比 分布式锁&#xff1a;满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心思想就是让大家都使用同一把锁&#xff0c;只要大家使用的是同一把锁&#xff0c;那么我们就能锁住线程&#xff0c;不让线程进行&#x…

springBoot--阿里云短信验证

阿里云短信验证 前言阿里云短信服务免费领取100条短信服务1、开通短信服务2、申请签名3、申请模板4、通过子用户获取账号的AccessKey ID 和AccessKey Secret5、使用教程 前言 在我们平时登录中短信验证吗验证在当今是必不可少的&#xff0c;下面是基于阿里云开发的短信验证操作…

【Qt 学习笔记】详解Qt中的信号和槽

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 详解Qt中的信号与槽 文章编号&#xff1a;Qt 学习笔记 / 12 文章目录…

【数据结构】ArrayList详解

目录 前言 1. 线性表 2. 顺序表 3. ArrayList的介绍和使用 3.1 语法格式 3.2 添加元素 3.3 删除元素 3.4 截取部分arrayList 3.5 其他方法 4. ArrayList的遍历 5.ArrayList的扩容机制 6. ArrayList的优缺点 结语 前言 在集合框架中&#xff0c;ArrayList就是一个…

代码随想录第19天

654. 最大二叉树 已解答 中等 相关标签 相关企业 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前缀上 构建左子树。递归地在最大值 右边 的 子数组后缀…

Mac 配置 Aria2

文章目录 1. Aria2 安装1.1 安装 brew1.2 安装 Aria2 2. 配置 Aria22.1 创建配置文件 aria2.conf 和空对话文件 aria2.session2.2 编辑配置文件 aria2.conf 3. 开机启动设置3.1 创建用户启动文件3.2 管理自启动项 4. 配置 BT tracker 自动更新4.1 XIU2/TrackersListCollection …

通义灵码-ai编码

https://developer.aliyun.com/topic/lingma/activities/202403?taskCode14508&recordIdb1ef3ba27250a5818b1b6ffe418af658#/?utm_contentm_fission_1 「通义灵码 体验 AI 编码&#xff0c;开 AI 盲盒」

sourcetree提交代码出现闪退报错(已解决)

当我在sourcetree提交代码时&#xff0c;点击提交按钮出现闪退关闭&#xff0c;并弹出下面的报错框&#xff0c;报错的图片如下&#xff1a; 那么经过了解&#xff0c;出现这样的报错原因是&#xff0c;git的提交时无法定位提交的人是谁&#xff0c;导致无法提交 那么解决的方…

Allavsoft for Mac v3.27.0.8852注册激活版 优秀的视频下载工具

Allavsoft for Mac是一款功能强大的多媒体下载和转换工具&#xff0c;支持从各种在线视频网站和流媒体服务下载视频、音频和图片。它具备批量下载和转换功能&#xff0c;可将文件转换为多种格式&#xff0c;以适应不同设备的播放需求。此外&#xff0c;Allavsoft还提供视频编辑…

ARM v8 Cortex R52内核 02 程序模型 Programmers Model

ARM v8 Cortex R52内核 02 程序模型 Programmers Model 2.1 关于程序模型 Cortex-R52处理器实现了Armv8-R架构。这包括&#xff1a; 所有的异常级别&#xff0c;EL0-EL2。 每个异常级别下的AArch32执行状态。 T32和A32指令集&#xff0c;其中包括&#xff1a; 浮点运算。 …

电子商务平台中大数据的应用|主流电商平台大数据采集API接口

(一)电商平台物流管理中大数据的应用 电商平台订单详情订单列表物流信息API接口应用 电子商务企业对射频识别设备、条形码扫描设备、全球定位系统及销售网站、交通、库存等管理软件数据进行实时或近实时的分析研究,提高物流速度和准确性。部分电商平台已建立高效的物流配送网…

Ruoyi-vue-pro Vue + nginx 二级目录部署到云服务器

http://www.your-server.com/ 这是一级目录&#xff0c;由于项目多&#xff0c;一般会通过二级域名http://oa.your-server.com/或二级目录http://www.your-server.com/oa来发布&#xff0c;本篇记录一下二级目录发布。先看效果 1、router/index.js配置base export default new …

Open CASCADE学习|在给定的TopoDS_Shape中查找与特定顶点 V 对应的TopoDS_Edge编号

enum TopAbs_ShapeEnum{TopAbs_COMPOUND,TopAbs_COMPSOLID,TopAbs_SOLID,TopAbs_SHELL,TopAbs_FACE,TopAbs_WIRE,TopAbs_EDGE,TopAbs_VERTEX,TopAbs_SHAPE}; 这段代码定义了一个名为 TopAbs_ShapeEnum 的枚举类型&#xff0c;它包含了表示不同几何形状类型的常量。这些常量通常…

5G网络架构及技术(二):OFDM一

ToDo: 等把这些讲义看完后得单开一个文章整理思维导图   该部分由于内容比较重要&#xff0c;OFDM是5G物理层的基础&#xff0c;但学习时直接跳到5G OFDM去看它的那些参数设置感觉没什么意义&#xff0c;还得从发展的角度进行学习&#xff0c;先从最先用到OFDM的WiFi协议开始…

最新版两款不同版SEO超级外链工具PHP源码

可根据个人感觉喜好自行任意选择不同版本使用&#xff08;版V1或版V2&#xff09; 请将zip文件全部解压缩即可访问&#xff01; 源码全部开源&#xff0c;支持上传二级目录访问 #已更新增加大量高质量外链&#xff08;若需要增加修改其他外链请打开txt文件&#xff09; #修…

隐私计算实训营学习八:隐语SCQL的开发实践

文章目录 一、SCQL使用集成最佳实践1.1 SCQL使用流程1.2 SCQL部署1.3 SCQL使用示例 二、SCQL工作原理三、使用SecretNote上手体验SCQL 一、SCQL使用集成最佳实践 1.1 SCQL使用流程 SCQL使用&#xff1a; SCQL 开放 API 供⽤户使⽤/集成。可以使⽤SCDBClient上⼿体验(类似与My…