LRU介绍和实现

LRU全称是Least Recently Used,即最近最久未使用的意思。

LRU算法的设计原则是:如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小。也就是说,当限定的空间已存满数据时,应当把最久没有被访问到的数据淘汰。(这一段是找的,让大家理解一下什么是LRU)。

 

说一下我们什么时候见到过LRU:其实老师们肯定都给大家举过这么个例子:你在图书馆,你把书架子里的书拿到桌子上。。但是桌子是有限的,你有时候不得不把一些书放回去。这就相当于内存和硬盘。这个例子都说过吧?

LRU就是记录你最长时间没看过的书,就把它放回去。在cache那里见过吧

 

然后最近在研究redis,又看到了这个LRU,所以就想写一下吧。

题目:设计一个结构,这个结构可以查询K-V,但是容量有限,当存不下的时候就要把用的年代最久远的那个东西扔掉。

其实思路很简单,我们维护一个双向链表即可,get也就是使用了,我们就把把它提到最安全的位置。新来的KV就依次放即可。

我们就先写这个双向链表结构

先写节点结构:

	public static class Node<V> {public V value;public Node<V> last;//前public Node<V> next;//后public Node(V value) {this.value = value;}}

然后写双向链表结构: 我们没必要把链表操作都写了,分析一下,我们只有三个操作:

1、加节点

2、使用了某个节点就把它调到尾,代表优先级最高

3、把优先级最低的移除,也就是去头部

(不会的,翻我之前的链表操作都有写)

	public static class NodeDoubleLinkedList<V> {private Node<V> head;//头private Node<V> tail;//尾public NodeDoubleLinkedList() {this.head = null;this.tail = null;}public void addNode(Node<V> newNode) {if (newNode == null) {return;}if (this.head == null) {//头空this.head = newNode;this.tail = newNode;} else {//头不空this.tail.next = newNode;newNode.last = this.tail;//注意让本节点前指针指向旧尾this.tail = newNode;//指向新尾}}
/*某个点移到最后*/public void moveNodeToTail(Node<V> node) {if (this.tail == node) {//是尾return;}if (this.head == node) {//是头this.head = node.next;this.head.last = null;} else {//中间node.last.next = node.next;node.next.last = node.last;}node.last = this.tail;node.next = null;this.tail.next = node;this.tail = node;}
/*删除第一个*/public Node<V> removeHead() {if (this.head == null) {return null;}Node<V> res = this.head;if (this.head == this.tail) {//就一个this.head = null;this.tail = null;} else {this.head = res.next;res.next = null;this.head.last = null;}return res;}}

链表操作封装完了就要实现这个结构了。

具体思路代码注释

	public static class MyCache<K, V> {//为了kv or vk都能查private HashMap<K, Node<V>> keyNodeMap;private HashMap<Node<V>, K> nodeKeyMap;//用来做优先级private NodeDoubleLinkedList<V> nodeList;private int capacity;//容量public MyCache(int capacity) {if (capacity < 1) {//你容量连1都不给,捣乱呢throw new RuntimeException("should be more than 0.");}this.keyNodeMap = new HashMap<K, Node<V>>();this.nodeKeyMap = new HashMap<Node<V>, K>();this.nodeList = new NodeDoubleLinkedList<V>();this.capacity = capacity;}public V get(K key) {if (this.keyNodeMap.containsKey(key)) {Node<V> res = this.keyNodeMap.get(key);this.nodeList.moveNodeToTail(res);//使用过了就放到尾部return res.value;}return null;}public void set(K key, V value) {if (this.keyNodeMap.containsKey(key)) {Node<V> node = this.keyNodeMap.get(key);node.value = value;//放新vthis.nodeList.moveNodeToTail(node);//我们认为放入旧key也是使用过} else {Node<V> newNode = new Node<V>(value);this.keyNodeMap.put(key, newNode);this.nodeKeyMap.put(newNode, key);this.nodeList.addNode(newNode);//加进去if (this.keyNodeMap.size() == this.capacity + 1) {this.removeMostUnusedCache();//放不下就去掉优先级最低的}}}private void removeMostUnusedCache() {//删除头Node<V> removeNode = this.nodeList.removeHead();K removeKey = this.nodeKeyMap.get(removeNode);//删除掉两个map中的记录this.nodeKeyMap.remove(removeNode);this.keyNodeMap.remove(removeKey);}}

 

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

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

相关文章

机器学习知识总结系列- 知识图谱(0-0)

文章目录目录机器学习知识图谱目录 本系列的文章只是根据个人的习惯进行总结&#xff0c;可能结构与一些书籍上不太一样&#xff0c;开始的内容比较简单&#xff0c;会随着后续的深入&#xff0c;不断丰富和更新图谱&#xff0c;同时也期待有相同兴趣的朋友一起给我留言一起丰富…

跳表介绍和实现

想慢慢的给大家自然的引入跳表。 想想&#xff0c;我们 1&#xff09;在有序数列里搜索一个数 2&#xff09;或者把一个数插入到正确的位置 都怎么做&#xff1f; 很简单吧 对于第一个操作&#xff0c;我们可以一个一个比较&#xff0c;在数组中我们可以二分&#xff0c;这…

机器学习知识总结系列- 基本概念(1-0)

文章目录目录1. 机器学习的定义2. 机器学习的分类2.1根据是否在人类监督下进行训练监督学习非监督学习半监督学习强化学习2.2根据是否可以动态渐进的学习在线学习批量学习2.3根据是否在训练数据过程中进行模式识别实例学习基于模型的学习3. 机器学习中的一些常见名词4. 机器学习…

剑指offer(刷题21-30)--c++,Python版本

文章目录目录第 21题&#xff1a;解题思路&#xff1a;代码实现&#xff1a;cpython第22 题&#xff1a;解题思路&#xff1a;代码实现&#xff1a;cpython第23 题&#xff1a;解题思路&#xff1a;代码实现&#xff1a;cpython第24 题&#xff1a;解题思路&#xff1a;代码实现…

redis——对象

刚写了redis主要的数据结构&#xff1a; 动态字符串、双端链表、字典、压缩列表、整数集合、跳表等 redis肯定不能直接使用这些数据结构来实现数据库&#xff0c;它用这些数据库建立了一个对象系统&#xff0c;包含&#xff1a; 字符串对象、列表对象、哈希对象、集合对象、…

剑指offer(刷题31-40)--c++,Python版本

文章目录目录第31 题&#xff1a;解题思路&#xff1a;代码实现&#xff1a;cpython第32题&#xff1a;解题思路&#xff1a;代码实现&#xff1a;cpython第33题&#xff1a;解题思路&#xff1a;代码实现&#xff1a;cpython第34题&#xff1a;解题思路&#xff1a;代码实现&a…

redis——数据库

redis服务器将所有数据库都保存在redis/redisServer中&#xff0c;数组db存放所有数据库&#xff0c;每一项是一个redisdb结构。dbnum代表数据库数量。 客户端有一个指针指向当前数据库&#xff0c;可以切换&#xff0c;也就是移动指针。 键空间 现在稍微介绍一下redisdb结构…

剑指offer(刷题41-50)--c++,Python版本

文章目录目录第41题&#xff1a;解题思路&#xff1a;代码实现&#xff1a;cpython第42题&#xff1a;解题思路&#xff1a;代码实现&#xff1a;cpython第43题&#xff1a;解题思路&#xff1a;代码实现&#xff1a;cpython第44题&#xff1a;解题思路&#xff1a;代码实现&am…

redis——持久化

因为redis是内存数据库&#xff0c;他把数据都存在内存里&#xff0c;所以要想办法实现持久化功能。 RDB RDB持久化可以手动执行&#xff0c;也可以配置定期执行&#xff0c;可以把某个时间的数据状态保存到RDB文件中&#xff0c;反之&#xff0c;我们可以用RDB文件还原数据库…

redis原理总结

数据结构&#xff08;字典、链表、字符串&#xff09; 数据结构&#xff08;整数集合&#xff0c;压缩列表&#xff09; 数据结构&#xff08;跳表介绍和手撕&#xff09; LRU介绍和实现 对象&#xff08;字符串对象、列表对象、哈希对象、集合对象、有序集合总结&#xff…

剑指offer(刷题51-60)--c++,Python版本

文章目录目录第51题&#xff1a;解题思路&#xff1a;代码实现&#xff1a;cpython第52题&#xff1a;解题思路&#xff1a;代码实现&#xff1a;cpython第53题&#xff1a;解题思路&#xff1a;代码实现&#xff1a;cpython第54题&#xff1a;解题思路&#xff1a;代码实现&am…

2017第一届河北省大学生程序设计竞赛题解

超级密码 小明今年9岁了&#xff0c;最近迷上了设计密码&#xff01;今天&#xff0c;他又设计了一套他认为很复杂的密码&#xff0c;并且称之为“超级密码”. 说实话&#xff0c;这套所谓的“超级密码”其实并不难&#xff1a;对于一个给定的字符串&#xff0c;你只要提取其中…

剑指offer(刷题61-65)--c++,Python版本

文章目录目录第61题&#xff1a;解题思路&#xff1a;代码实现&#xff1a;cpython第62题&#xff1a;解题思路&#xff1a;代码实现&#xff1a;cpython第63题&#xff1a;解题思路&#xff1a;代码实现&#xff1a;cpython第64题&#xff1a;解题思路&#xff1a;代码实现&am…

2018第二届河北省大学生程序设计竞赛题解

icebound的账单 题目描述 icebound从小就有记账的习惯。又到了月末icebound统计资金状况的时候。icebound每个月除了不停的挥霍以外&#xff0c;有时他会良心发现&#xff0c;勤工俭学&#xff0c;因此会有一些微薄的收入。然而icebound数学不好&#xff0c;需要你来帮助他统计…

大数的四则运算(加法、减法、乘法、除法)

大数的四则运算&#xff08;加法、减法、乘法、除法&#xff09; 前言&#xff1a; 在计算机中数字表示的范围是有限制的&#xff0c;比如我们熟知的 int、float、double 等数据类型所能表示的范围都是有限的&#xff0c;如果我们要对位数达到几十位、几百位、上千位的大整数进…

数组基操三连(1)

题目&#xff1a; 给定一个数组arr&#xff0c;求出需要排序的最短子数组长度 要求&#xff1a; 时间o(n),空间o(1) 思路&#xff1a; 有序的数组中&#xff0c;任意一个数字&#xff0c;一定小于左边的数大于右边的数。 我们找到的需要排序的子数组&#xff0c;显然是比右边…

IT互联网公司的笔试的输入输出- c++ python

文章目录目录c方式1&#xff1a;方式2&#xff1a;Python方式1&#xff1a;方式2&#xff1a;方式3&#xff1a;目录 c 方式1&#xff1a; 第一种情况&#xff1a;输入n个数&#xff0c;存放在数组中 #include <iostream> #include <vector> using namespace st…

随机过程1

随机过程1概述1.参考书目2.主要内容3.概率论--基本概念回顾3.1对“不确定性”的认识3.2 应对“不确定性”应该怎么做3.3随机变量&#xff08;Random Variable&#xff09;3.4分布函数&#xff08;Distribution Function&#xff09;3.5概率密度&#xff08;Density&#xff09;…