LRU缓存机制

题目:运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制。

   它应该支持以下操作: 获取数据 get 和 写入数据 put 。

   获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。

      写入数据 put(key, value) - 如果密钥已经存在,则变更其数据值;如果密钥不存在,则插入该组「密钥/数据值」。

   当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。

示例:  
   LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );

   cache.put(1, 1);
   cache.put(2, 2);
   cache.get(1);       // 返回  1
   cache.put(3, 3);    // 该操作会使得密钥 2 作废
   cache.get(2);       // 返回 -1 (未找到)
   cache.put(4, 4);    // 该操作会使得密钥 1 作废
   cache.get(1);       // 返回 -1 (未找到)
   cache.get(3);       // 返回  3
   cache.get(4);       // 返回  4

代码:

 class LRUCache {

     public LRUCache(int capacity) {

     }

     public int get(int key) {

     }

     public void put(int key, int value) {

     }
} /**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/

LRU页面置换算法(最近最少使用算法)(我的另一篇博文讲到了LFU最不经常使用页面置换算法,可以进行比较)

  原理:

    选择最后一次访问时间距离当前时间最长的一页并淘汰之。即淘汰没有使用的时间最长的页
    每页设置访问时间戳,每当页面被访问时,该页面的时间戳被更新;
    发生缺页中断时,淘汰时间戳最小的页面;

    如图:图中的页面为三页,依次向存储中加入432143543215这些数字。

       而存储空间只能存储三个页面,所以会按照上述规则不断淘汰已经存储在页面中的数字。

    

解题思路(logN的思路):

    知道了LRU的置换规则后,由于此题需要存储的是key和value,所以

      首先,需要建一个类node,存放三样东西,key,value,times(时间戳)

      其次,选择一种合适的数据结构来解决存储优先级问题,此处我们采用内部是小顶堆的PriorityQueue优先级队列用来实现times最小的元素在队头

         但是我们会在让新元素入队之前可能会删除队列中指定元素,当然可以去遍历队列,但是这样太慢了

         我们可以再用一种HashMap的数据集合用来存储节点,以便快速通过node的key来得到整个node。

      最后,便是处理逻辑关系,写题目要求的get,put方法了

解题代码详解(logN):

 public class node implements Comparable<node>{
private int Key;//键
private int Value;//值
private int Times;//时间戳
node() {}
node(int key, int value, int time) {
this.Key = key;
this.Value = value;
this.Times = time;
}
public int getKey() {
return Key;
} public void setKey(int Key) {
this.Key = Key;
} public int getValue() {
return Value;
} public void setValue(int Value) {
this.Value = Value;
} public int getTimes() {
return Times;
} public void setTimes(int Times) {
this.Times = Times;
} @Override
public int compareTo(node o) {
//实现times最小的元素在队头
return Times - o.Times;
}
} class LRUCache {
PriorityQueue<node> KeyValueTimes = new PriorityQueue();//用于实现优先级顺序
Map<Integer, node> nodeset;//用于O(1)取出某个具体的node
public int Capacity = 0;//我的cache中最大容量
public int nownum = 0;//cache的实时元素个数
public int tim = 0;//时间戳 public LRUCache(int capacity) {
this.Capacity = capacity;//设置cache容量
nodeset = new HashMap<Integer, node>(capacity);//用于O(1)取出某个具体的node,容量依然设置为capacity
} public int get(int key) {
if(this.Capacity == 0)//判断容量是否为空,为空则直接返回-1
return -1;
node nownode = nodeset.get(key);//通过HashMap,快速通过key键快速得到node
if (nownode == null) {//如果key这个键没在队列中,则返回-1
return -1;
}else{
KeyValueTimes.remove(nownode);//移除队列中当前的这个node
nownode.setTimes(tim++);//更新当前这个node的时间戳
KeyValueTimes.offer(nownode);//再把它放回去
}
return nownode.getValue();
} public void put(int key, int value) {
if(this.Capacity == 0)//判断容量是否为空,为空则不进行put
return;
node thisnode = new node(key,value,tim++);
node oldnode = nodeset.get(key);
if(oldnode == null){//队列里不存在这个key
if(nownum < this.Capacity){//没装满
KeyValueTimes.offer(thisnode);//在队列里添加新node
nodeset.put(key,thisnode);//在HashMap里添加新node
nownum++;//更新当前cache的元素个数
}
else{//装满了,需要LRU,最近最久为使用被移除
nodeset.remove(KeyValueTimes.poll().getKey());//移除队列里的队头,移除HashMap对应的那个node
KeyValueTimes.offer(thisnode);//在队列里添加新node
nodeset.put(key,thisnode);//在HashMap里添加新node
}
}
else{//队列里存在这个key
KeyValueTimes.remove(oldnode);//移除队列里键为key的node,移除HashMap对应的那个node
nodeset.remove(oldnode.getKey());
KeyValueTimes.offer(thisnode);//在队列里添加新node,这里新的node的value值可能会不一样,所以更新了value
nodeset.put(key,thisnode);//在队列里添加新node,这里新的node的value值可能会不一样,所以更新了value
}
}
}

操作系统-2-存储管理之LRU页面置换算法(LeetCode146)的更多相关文章

  1. 操作系统笔记(六)页面置换算法 FIFO法 LRU最近最久未使用法 CLOCK法 二次机会法

    前篇在此: 操作系统笔记(五) 虚拟内存,覆盖和交换技术 操作系统 笔记(三)计算机体系结构,地址空间.连续内存分配(四)非连续内存分配:分段,分页 内容不多,就不做index了. 功能:当缺页中断发 ...

  2. LRU页面置换算法

    本文以序列长度20的{ 7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1};以及页面4:为例: #include <stdio.h> #define Init ...

  3. 操作系统页面置换算法(opt,lru,fifo,clock)实现

    选择调出页面的算法就称为页面置换算法.好的页面置换算法应有较低的页面更换频率,也就是说,应将以后不会再访问或者以后较长时间内不会再访问的页面先调出. 常见的置换算法有以下四种(以下来自操作系统课本). ...

  4. [Operate System & Algorithm] 页面置换算法

    页面置换算法是什么?我们看一下百度百科对页面置换算法给出的定义:在地址映射过程中,若在页面中发现所要访问的页面不在内存中,则产生缺页中断.当发生缺页中断时,如果操作系统内存中没有空闲页面,则操作系统必 ...

  5. 操作系统 页面置换算法LRU和FIFO

    LRU(Least Recently Used)最少使用页面置换算法,顾名思义,就是替换掉最少使用的页面. FIFO(first in first out,先进先出)页面置换算法,这是的最早出现的置换 ...

  6. (待续)C#语言中的动态数组(ArrayList)模拟常用页面置换算法(FIFO、LRU、Optimal)

    目录 00 简介 01 算法概述 02 公用方法与变量解释 03 先进先出置换算法(FIFO) 04 最近最久未使用(LRU)算法 05 最佳置换算法(OPT) 00 简介 页面置换算法主要是记录内存 ...

  7. 页面置换算法(最佳置换算法、FIFO置换算法、LRU置换算法、LFU置换算法)

    页面置换产生的原因是:分页请求式存储管理(它是实现虚拟存储管理的方法之一,其中一个特性是多次性-->多次将页面换入或换出内存) 效果最好的页面置换算法:最佳置换算法 比较常用的页面置换算法有:F ...

  8. 【操作系统】页面置换算法(最佳置换算法)(C语言实现)

    [操作系统]页面置换算法(最佳置换算法)(C语言实现) (编码水平较菜,写博客也只是为了个人知识的总结和督促自己学习,如果有错误,希望可以指出) 1.页面置换算法: 在地址映射过程中,若在页面中发现所 ...

  9. 页面置换算法 - FIFO、LFU、LRU

    缓存算法(页面置换算法)-FIFO. LFU. LRU 在前一篇文章中通过leetcode的一道题目了解了LRU算法的具体设计思路,下面继续来探讨一下另外两种常见的Cache算法:FIFO. LFU ...

随机推荐

  1. ES6—get 与 set

    在类里面可以去定义一些getter和setter,getter可以得到一些东西的方法,setter可以设置东西 class Chef{ constructor(food){ this.food = f ...

  2. [项目分享]JSP+Servlet+JDBC实现的云端汽修后台管理系统

    本文存在视频版本,请知悉 项目简介 项目来源于:https://gitee.com/chenlinSir/CloudDemo-servlet 难度等级:简单 基于JSP+Servlet+Jdbc的云端 ...

  3. git基础教程(八)

    8. gitlab相关介绍 8.1 gitlab优势 社区版本,自己可以在公司搭建环境 维护人员多,版本更新块 易用性强,上手快 集成CI(持续集成) 集成CD(持续发布) 8.2 持续集成 8.2. ...

  4. 普通索引和唯一索引如何选择(谈谈change buffer)

    假设有一张市民表(本篇只需要用其中的name和id_card字段,有兴趣的可以翻看“索引”篇,里面有建表语句) 每个人都有一个唯一的身份证号,且业务代码已经保证不会重复. 由于业务需求,市民需要按身份 ...

  5. 一般人不知道的Flask框架SQLAlchemy的那些事

    目录 SQLAlchemy 1.介绍 2.简单使用(能创建表,删除表,不能修改表) 3.一对多关系 4.多对多关系 5.操作数据表 6.基于scoped_session实现线程安全 7.基本增删查改 ...

  6. Deepin中安装使用好用的字典GoldenDict

    2020-03-21   23:08:17 不说废话直接来安装步骤: 打开Deepin的应用商店,输入GoldenDict查找: 找到后点击安装,然后等待一小会,电脑提示音告诉你已经安装完成: 然后再 ...

  7. 我用STM32MP1做了个疫情监控平台3—疫情监控平台实现

    目录 1.前言 2.数据接口的获取 3.Qt界面的实现 4.在开发板上运行Qt程序 5.使用无线模块联网 6.代码下载 @ 1.前言 之前我使用桌面版本Qt实现了肺炎疫情监控平台:基于Qt的新冠肺炎疫 ...

  8. jenkins-gitlab-harbor-ceph基于Kubernetes的CI/CD运用(二)

    一张网图 因为我们使用了Docker in Docker技术,就是把jenkins部署在k8s里.jenkins master会动态创建slave pod,使用slave pod运行代码克隆,项目构建 ...

  9. 学习vue前的准备工作

    起步 1.扎实的HTML/CSS/Javascript基本功,这是前置条件. 2.不要用任何的构建项目工具,只用最简单的<script>,把教程里的例子模仿一遍,理解用法.不推荐上来就直接 ...

  10. javascript异步上传图片文件

    html: <form action="url" enctype="multipart/form-data" id="myform"  ...