首页 > 编程语言 >LRU缓存算法设计

LRU缓存算法设计

时间:2024-07-06 15:55:12浏览次数:23  
标签:Node map 缓存 删除 int 算法 LRU key public

LRU 缓存算法的核⼼数据结构就是哈希链表双向链表哈希表的结合体。这个数据结构⻓这样:
在这里插入图片描述
创建的需要有两个方法,一个是get方法,一个是put方法。

在这里插入图片描述

在这里插入图片描述

一些问题:为什么需要使用双向链表呢?因为删除链表的本身,需要得到他的前一个节点。如果使用单链表,效率就会很低,这边是使用的空间换取效率。

//Node 节点类
public class Node {
    public  int key,val;
    public Node pre,next;
    public Node(int key,int val){
        this.key=key;
        this.val=val;
    }

}



public class DoubleList {
    //头和尾
    public   Node head,tail;
    public int size;
    public DoubleList(){
        //两个哨兵
        head=new Node(0,0);
        tail=new Node(0,0);
        head.next=tail;
        tail.pre=head;
        size=0;
    }
    public  void addLast(Node x){
        //添加到末尾去
        //在tail之前插入一个 
        x.pre=tail.pre; //
        x.next=tail;
        tail.pre.next=x;
        tail.pre=x;
        size++;
    }
    public void remove(Node x) {
        //双链表删除一个节点  x.pre.next=x.next;
        x.pre.next = x.next;
        x.next.pre = x.pre;
        size--;
    }
    // 删除链表中第⼀个节点,并返回该节点,时间 O(1)
    public Node removeFirst() {
        if (head.next == tail)
            return null;
        Node first = head.next;
        remove(first);
        return first;
    }
    public int size() { return size; }
}


缓存设计的代码:


import java.util.HashMap;

public class LRUCache {
    // key -> Node(key, val)
    private HashMap<Integer, Node> map;
    // Node(k1, v1) <-> Node(k2, v2)...
    private DoubleList cache;
    // 最⼤容量
    private int cap; //最大容量

    public LRUCache(int capacity) {
        this.cap = capacity;
        map = new HashMap<>();
        cache = new DoubleList();
    }

    private void makeRecently(int key) {
        Node x = map.get(key); //变为最近的    删除 然后添加进来
        // 先从链表中删除这个节点
        cache.remove(x);
        // 重新插到队尾
        cache.addLast(x);
    }
    private void addRecently(int key, int val) {
        Node x = new Node(key, val);
        // 链表尾部就是最近使⽤的元素
        cache.addLast(x);
        // 别忘了在 map 中添加 key 的映射
        map.put(key, x);
    }
    private void deleteKey(int key) {
        Node x = map.get(key);
        // 从链表中删除
        cache.remove(x);
        // 从 map 中删除
        map.remove(key);  //mp中也要删除
    }
    private void removeLeastRecently() {  //删除最久没有使用的
        // 链表头部的第⼀个元素就是最久未使⽤的
        Node deletedNode = cache.removeFirst();
        // 同时别忘了从 map 中删除它的 key
        int deletedKey = deletedNode.key;
        map.remove(deletedKey);
    }
    public int get(int key) {
        if (!map.containsKey(key)) {
            return -1;
        }
        // 将该数据提升为最近使⽤的
        makeRecently(key); //修改
        return map.get(key).val;
    }
    public void put(int key, int val) {
        //如果之前含有  删除 并添加
        if (map.containsKey(key)) {
            // 删除旧的数据
            deleteKey(key);
            // 新插⼊的数据为最近使⽤的数据
            addRecently(key, val);
            return;
        }
   //如果慢了 那么删除
        if (cap == cache.size()) {
            // 删除最久未使⽤的元素
            removeLeastRecently();
        }
        // 添加为最近使⽤的元素
        addRecently(key, val);
    }
}

一些算法的设计思路:,变为最近的。首先得到这个点,然后删除这个点。
在这里插入图片描述
添加到最近来 就需要new出来这个节点,然后加入到最后去。
在这里插入图片描述
删除 首先先得到,再从链表中删除掉。不要忘记hashmap中也是需要删除的。
在这里插入图片描述
如果满了,需要删除掉最早的那个节点。
在这里插入图片描述

test测试结果
在这里插入图片描述
通过测试发现 2已经被移除去了。

标签:Node,map,缓存,删除,int,算法,LRU,key,public
From: https://blog.csdn.net/ngczx/article/details/140229679

相关文章

  • 代码随想录算法训练营第五十六天 | 98.所有可达路径
    98.所有可达路径题目链接文章讲解邻接矩阵法邻接矩阵使用二维数组来表示图结构。邻接矩阵是从节点的角度来表示图,有多少节点就申请多大的二维数组为了节点标号和下标对其,有n个节点的图申请(n+1)*(n+1)的空间vector<vector<int>>graph(n+1,vector<int>(n+1,0)......
  • 【BP时序预测】基于布谷鸟优化算法CS实现负荷数据预测单输入单输出附matlab代码
    %负荷数据预测单输入单输出(BP时序预测)%使用布谷鸟优化算法实现%假设你已经有了输入数据和对应的输出数据%输入数据应该是一个矩阵,每一行代表一个样本,每一列代表一个特征%输出数据应该是一个列向量,每个元素代表对应样本的输出%设置布谷鸟优化算法参数max_iter=......
  • 调度系统揭秘(下):调度算法与架构设计
    一、调度算法在调度系统中,调度算法常见是以下两种:广度优先深度优先1.1、广度优先:广度优先搜索算法按照任务之间的依赖关系进行逐级遍历,先执行所有直接前置任务,再执行所有直接后继任务,以此类推,直到所有的任务都被遍历和执行完成。其特点如下:执行顺序合理:广度优先搜索保......
  • 代码随想录算法训练营第二天 | 203.移除链表元素 707.设计链表 206.反转链表
    代码随想录算法训练营第二天|203.移除链表元素707.设计链表206.反转链表进入链表章节,就要和虚拟头结点(dummyhead)打交道了,还要注意边界条件和空指针异常移除链表元素题目链接/文章讲解/视频讲解::https://programmercarl.com/0203.%E7%A7%BB%E9%99%A4%E9%93%BE%E8%A1%A......
  • 【中国算力大会分会,SPIE独立出版!AHPCAI前三届已完成EI检索!】2024算法、高性能计算与人
    2024算法、高性能计算与人工智能国际学术会议(AHPCAI2024)定于2024年8月14-16日在中国郑州举行。会议主要围绕算法、高性能计算与人工智能等研究领域展开讨论。会议旨在为从事算法、高性能计算与人工智能研究的专家学者、工程技术人员、技术研发人员提供一个共享科研成果......
  • Linux关于数据库,群集,缓存加速等精捡面试题
    目录第一部分:企业网站架构部署与优化..................................................61.列举几种常见的HTTP状态码?及各种代表的含义?................................62.HTTP请求方法有哪些?请至少列举三种,并简述它们的用途。........................63.HTTP协......
  • 摸鱼大数据——Spark Core——缓存和checkpoint
    1、RDD的缓存当RDD被重复使用,或者计算该RDD比较容易出错,而且需要消耗比较多的资源和时间的时候,我们就可以将该RDD缓存起来。​主要作用:提升Spark程序的计算效率注意事项:RDD的缓存可以存储在内存或者是磁盘上,甚至可以存储在Executor进程的堆外内存中。主要是放在内存......
  • 【matlab】分类回归——智能优化算法优化径向基神经网络
    径向基(RadialBasisFunction,RBF)神经网络一、基本概念径向基函数(RBF):是一个取值仅仅依赖于离原点(或某一中心点)距离的实值函数。在RBF神经网络中,最常用的径向基函数是高斯核函数,其形式为:其中,x​为核函数中心,σ为函数的宽度参数(或方差),控制了函数的径向作用范围。二、网络结......
  • Vue3 对跳转 同一路由传入不同参数的页面分别进行缓存
    1:使用场景   从列表页跳转至不同的详情页面,对这些详情页面分别进行缓存2:核心代码2.1:配置路由文件在路由文件里对需要进行缓存的路由对象添加meta属性 //需要缓存的详情页面路由 {  name:detail,  path:'/myRouter/detail',//路径  compo......
  • VideoPrism——探索视频分析领域模型的算法与应用
    概述论文地址:https://arxiv.org/pdf/2402.13217.pdf视频是我们观察世界的生动窗口,记录了从日常瞬间到科学探索的各种体验。在这个数字时代,视频基础模型(ViFM)有可能分析如此海量的信息并提取新的见解。迄今为止,视频理解领域的研究确实取得了长足进步,但构建真正的基础视频模......