LRU缓存算法设计

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 中删除它的 keyint 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已经被移除去了。

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

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

相关文章

[单master节点k8s部署]20.监控系统构建(五)Alertmanager

prometheus将监控到的异常事件发送给Alertmanager&#xff0c;然后Alertmanager将报警信息发送到邮箱等设备。可以从下图看出&#xff0c;push alerts是由Prometheus发起的。 安装Alertmanager config文件 [rootmaster prometheus]# cat alertmanager-cm.yaml kind: ConfigMa…

硕士文凭再耀眼,也没有第一学历刺眼?

在当今社会,教育被视为个人发展和社会进步的重要基石。随着高等教育的普及和竞争的加剧,学历成为了衡量个人能力、决定职业前景的重要标尺。然而,在这一过程中,“第一学历”的概念逐渐凸显,其影响力甚至在某些情况下超越了后续的硕士、博士等更高学历。这一现象引发了广泛…

软件测试与开发流程

软件测试简介 软件测试是对软件进行检测和评估&#xff0c;以确定其是否满足所需结果的过程和方法。它是在规定的条件下对程序进行操作&#xff0c;发现程序错误&#xff0c;从而衡量软件质量&#xff0c;并对其是否满足设计要求进行评估的过程。 与计算机系统操作有关的计算机…

【Linux】JSON和YAML文件格式的相同点和不同点

JSON(JavaScript Object Notation)和YAML(YAML Ain’t Markup Language)都是用于数据表示的文件格式。它们有一些共同点和不同点: 共同点 数据表示:两者都用于表示结构化数据,并且都是人类可读的格式。支持复杂数据结构:都可以表示复杂的数据结构,如对象、数组、字符…

使用Python绘制堆积柱形图

使用Python绘制堆积柱形图 堆积柱形图效果代码 堆积柱形图 堆积柱形图&#xff08;Stacked Bar Chart&#xff09;是一种数据可视化图表&#xff0c;用于显示不同类别的数值在某一变量上的累积情况。每一个柱状条显示多个子类别的数值&#xff0c;子类别的数值在柱状条上堆积在…

刷题小记----Java的一些输入方式

场景1&#xff1a;输入字符串 输入描述&#xff1a; 每个测试输入包含2个字符串 Scanner scan new Scanner(System.in); String str1 scan.nextLine(); String str2 scan.nextLine();场景2&#xff1a;输入数组 输入描述&#xff1a; 输入的第一行为一个正整数n(1 ≤ n ≤ 1…

基于Redis和阻塞队列的 异步秒杀业务

异步前 之前的秒杀业务的查询优惠券、查询订单、减库存、创建订单都要查询数据库&#xff0c;而且有分布式锁&#xff0c;使得整个业务耗时长&#xff0c;对此采用异步操作处理&#xff0c;异步操作类似于餐厅点餐&#xff0c;服务员负责点菜产生订单、厨师负责根据订单后厨做…

[leetcode hot 150]第二十三题,合并K个升序链表

题目&#xff1a; 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 示例 1&#xff1a; 输入&#xff1a;lists [[1,4,5],[1,3,4],[2,6]] 输出&#xff1a;[1,1,2,3,4,4,5,6] 解释&#xff1a…

解析Java中1000个常用类:Dictionary类,你学会了吗?

在线工具站 推荐一个程序员在线工具站:程序员常用工具(http://cxytools.com),有时间戳、JSON格式化、文本对比、HASH生成、UUID生成等常用工具,效率加倍嘎嘎好用。程序员资料站 推荐一个程序员编程资料站:程序员的成长之路(http://cxyroad.com),收录了一些列的技术教程…

IDEA越用越卡?教你轻松解决IDEA内存占用过高问题

大家好&#xff0c;我是瑶山&#xff0c;最近IDEA越用越卡了&#xff0c;刚刚内存卡爆&#xff0c;带着整个电脑也卡的飞起&#xff0c;只能重启了电脑。 虽然重启后又恢复到了流畅&#xff0c;但是问题还是如鲠在喉&#xff0c;痛定思痛&#xff0c;还是决定处理下&#xff01…

基于SpringBoot+Vue的招生管理系统(带1w+文档)

基于SpringBootVue的招生管理系统(带1w文档&#xff09; 通过招生管理系统的研究可以更好地理解系统开发的意义&#xff0c;而且也有利于发展更多的智能系统&#xff0c;解决了人才的供给和需求的平衡问题&#xff0c;招生管理系统的开发建设&#xff0c;由于其开发周期短&…

WHAT - React useReducer vs Redux

useReducer 和 Redux 都是用于管理应用程序状态的工具&#xff0c;但它们有几点不同之处&#xff1a; useReducer React 内置钩子&#xff1a; useReducer 是 React 提供的一个内置 Hook&#xff0c;用于在函数式组件中管理局部状态。可以通过定义一个 reducer 函数来处理状态…

在 PostgreSQL 中,如何处理大规模的文本数据以提高查询性能?

文章目录 一、引言二、理解 PostgreSQL 中的文本数据类型三、数据建模策略四、索引选择与优化五、查询优化技巧六、示例场景与性能对比七、分区表八、数据压缩九、定期维护十、总结 在 PostgreSQL 中处理大规模文本数据以提高查询性能 一、引言 在当今的数据驱动的世界中&…

555定时器

硬件大杂烩 1. 555定时器内部结构 各引脚定义作用 引脚1: GND (地)&#xff0c;功能&#xff1a;接地&#xff0c;作为低电平(0V)。 引脚2: TRIG (触发)&#xff0c;功能&#xff1a;当此引脚电压降至1/3VCC (或由控制端决定的阈值电压)时&#xff0c;输出端给出高电平。 引…

MyBatis 的知识要点,面试多半会被问到的知识点

1、什么是 MyBatis? MyBatis 是一款优秀的支持自定义 SQL 查询、存储过程和高级映射的持久层框架&#xff0c;消除了 几乎所有的 JDBC 代码和参数的手动设置以及结果集的检索 。 MyBatis 可以使用 XML,或注解进 行配置和映射&#xff0c;MyBatis 通过将参数映射到配置的 SOL,形…

【设计模式之美】策略模式方法论:解耦策略的定义、创建和使用

文章目录 一. 策略的定义-封装策略&#xff0c;面向接口二. 策略的创建-创建策略工厂1. 对于无状态策略2. 对于有状态策略 三. 策略的使用&#xff1a;动态选择四. 避免分支判断-策略的优雅1. 对于无状态的策略2. 对于有状态的策略 策略模式是定义一族算法类&#xff0c;将每个…

雅思词汇及发音积累 2024.7.6

地理方位 1.right 右边 2.left 左边 3.in front of 在前面 4.behind/rear 在后面 5.next to 在旁边 6.at the end of 在末端 7.opposite to 在对面 8.be far from 距离某处很远 9.be nearby 距离某处很近 10.go back/back/back up 向回走 11.go up/down 向上&#xff08;北&…

数据结构(3.3)——栈的链式存储结构

链栈的定义 采用链式存储的栈成为链栈&#xff0c;链栈的优点是便于多个栈共享存储空间和提高其效率&#xff0c;且不存在栈满上溢的情况。通常采用单链表实现。 typedef struct Linknode {int data; // 数据域struct Linknode* next; // 指针域 } LiStack; // 栈类…

常见的块元素、行内元素以及行内块元素,三者有何不同?

在HTML中&#xff0c;元素可以分为块级元素&#xff08;block-level elements&#xff09;、行内元素&#xff08;inline elements&#xff09;和行内块元素&#xff08;inline-block elements&#xff09;。它们之间的主要区别如下&#xff1a; 块级元素&#xff08;block-le…

【CUDA】 由GPGPU控制核心架构考虑CUDA编程中线程块的分配

GPGPU架构特点 由于典型的GPGPU只有小的流缓存&#xff0c;因此一个存储器和纹理读取请求通常需要经历全局存储器的访问延迟加上互连和缓冲延迟&#xff0c;可能高达数百个时钟周期。与CPU通过巨大的工作集缓存而降低延迟不同&#xff0c;GPU硬件多线程提供了数以千计的并行独…