LRU算法的原理与实现

作者&投稿:章娅 (若有异议请与网页底部的电邮联系)
~ LRU是Least Recently Used的缩写,即最近最少使用算法,应用面非常的广泛,比如redis当中的内存淘汰策略。因为计算机的内存都是有限的,当用户访问的数据如果存在内存当中直接返回的给用户的话,效率会非常快,但是如果内存不存在,在去磁盘里面查找的,效率会大打折扣。所以我们希望在有限的内存空间当中,多存放点热点数据,用户不经常访问的数据,尽量淘汰掉,避免占用内存空间。

使用双向链表来实现LRU 这篇文章已经用双向链表来实现过LRU算法了,但是基于双向链表的特性,使得该算法的时间复杂度为O(n),显然不是最优的算法,那么有没有算法,可以达到O(1),当然是有的,早早的计算机科学家已经想到,并且已经实现了。

在笔者介绍接下来的内容时,还是希望先了解一下两篇博文:
一、 图解HashMap原理
二、 图解LinkedHashMap

之前使用双向链表去实现LRU算法时,时间复杂度没有达到O(1),主要原因在于遍历结点时,带来的时间开销,那么换句话说,要实现遍历结点时,时间复杂度为O(1),第一时间想到的应该是hash数组,但是hash算法可能会存在不同的key值,产生相同的hash值,那么可以将不同key,但是相同hash值的结点,以单链表的形式存放。这样仅仅是实现了存取时间复杂度为O(1),如何实现数据能够按访问顺序存放呢?并且增删的时间复杂度为O(1),这个可以使用双向链表来实现,所以综合来讲,就是实现散列数组+双向链表来使用LRU,可以达到时间复杂度为O(1)。

逻辑视图如下:

咋一看这个图乱的很,稍微解释一下,如果感觉理解上有点困难,可以先去了解一下之前推荐的两篇博文,那里会介绍的更加详细一点。

1.最左侧其实就是一个普通的数组,数组的大小必须是2的倍数,这个原因是什么呢?因为这个数组的存放方式是散列的,意思就是需要key.hashcode & (length -1)才能得出存放位置的方式,hash的好处是可以根据key值,在时间复杂度为O(1)的前提找到对应的存放位置,这也是我们的初衷,说到这里其实还没有解释为什么一定要是2的倍数,因为2的倍数-1,这个数的二进制,一定全是1,比如16-1=15,二进制表示就是1111,&运算符其实就是将值全部化成二进制逐位与,比如10111011 & 1111 = 1011 = 11,但是如果不是2的倍数,比如7-1=6,化成二进制就是0110,由于末位是0,不管什么二进制值与0110做&运算,一定是偶数,这样会导致散列分布不均匀。

2.不同key值,相同hash值,如何存放呢?相同的hash值做与运算一定能够得到相同的数组脚标,这些结点,以单链表的形式存在,就是图中数组右侧的单链表。

3.如何实现按访问顺序?上图除去数组和挂在数组右侧的单链表,还有绿色和黄色的单向箭头,在右上角还有一个双向链表的头指针。其实这些箭头就是维护不同结点的访问顺序,即双向链表。

总上所述,这种数据结构定义的结构体如下:
class Node{
Object key; //存放key值,用于计算存放数组脚标位置
Object value;//存放元素值
int hash;//存放key.hashcode
Node next;//维护单链表顺序
Node before;//维护双向链表顺序
Node after;
}

笔者用java实现如下,感兴趣可以用自己喜欢的语言去实现一遍,加深理解:

其实以上实现底层原理就是LinkedHashMap的实现原理,只不过笔者做了一些简化,去掉了繁琐的继承,扩容等,突出了算法核心,如果读者感兴趣也可以去研究一下LinkedHashMap的源码。

使用LinkedHashMap来实现LRU算法:

看起来是不是简单了很多,因为LinkedHashMap底层已经封装好了,我们直接调用就好,但是作为一个想要变优秀的码农,一定要知其然知其所以然。

使用散列+双向链表的方式是如何实现O(1)复杂度的?在实现LRU算法过程中,无非两种操作,查找和修改,使用散列数组实现查找时间复杂度为O(1),使用双向链表实现修改复杂度为O(1),并且双向链表还可以维护访问顺序,所以使用这种方式,可以达到O(1)。


多样性算法在58部落的实践和思考
原始算法、MMR和DPP效果对比 多样性层主要考虑稳定性以及时效性,我们主要流量在两个隐式多样性算法MMR和DDP,而我们原始算法是通过启发式规则进行控制的。通过对比最优参数下的算法,发现DDP整体效果上好于MMR,并且相对于原始算法都有很大程度提升。下表表示两个算法相比原始算法变化。 指标\\算法MMR DDP pvctr+3.4%+5...

喷泉编码的主要分类
Raptor码的单位符号的编码和解码平均算术复杂度为 ,其中 是解码开销。因此Raptor码的单位编解码复杂度是与码长成线性关系,比LT码的对数关系又有所进步。 如果保持LT码的编码算法不变,仅仅改变其解码算法,用一种所谓的RU解码器代替LT码采用的BP解码器,就生成了一种新型的喷泉编码,称为RU码。它需...

请问RU370F的谐音怎么读?
这个字是rudolph,意思是鲁道夫数。圆周率是数学中最重要的常数之一,现在的计算机可以很轻松地计算圆周率数万亿位,在计算机没有诞生以前,数学家计算圆周率经历了几何算法和分析算法,计算效率非常低。比如圆周率在德国又叫做鲁道夫数,原因是十七世纪,德国数学家鲁道夫·范·科伊伦,在后半生的10多年时间里...

魔方简单口诀表,我是个新手。说的简单点
(第四步) 在魔方新的顶面上画十字,形成:这个算法会把顶层在如下4种情况中切换,顶面的4个棱色块在旋转之后,也只可能有这4种情况:在应用算法前,应参照上图顶面绿色的样子来确定你魔方的方位;初学者使用的魔方口诀算法:RU'F'UFR 另外,在“一字”的时候,也可以试试:R'F'U'FUR (第五...

2019-12-20
算法:AET\/ALC 目的:分析细化用户活跃情况、时间碎片化等 备注:一般按角色统计 PCU: 最高同时在线用户数(Peak Concurrent Users) 定义:在一个瞬间极点上达到的同时在线的用户总数 算法:每隔5分钟或10分钟取一次同时在线用户数,其最大值为这段时间的PCU 目的:分析衡量游戏热度及活动的开展与效果(如阵营战、BOSS战...

为什么越来越多的公司退出传统算法竞赛了?
所以,算法竞赛没有带来预期的收益,就搞不下去。顺便说说算法的重要性,很多求职者老是问我,工作中谁会用到二叉树啊,你让我写这个根本没用,要用的时候我复习一下,或者下载个包,不是什么都解决了?素质,同学,懂不懂什么叫素质啊?你学了4年计算机,二叉树的原理都不记得,我怎么能相信在某些...

工厂routing是什么意思
服务质量路由算法仿真平台的设计与实现。Research on MANET Network Routing Algorithm Based on Quantum Search Algorithm.基于量子搜索算法的MANET网络路由算法研究。Model and Algorithm for Location Routing Problem Based on Equilibrium Principle.基于均衡原理的定位-运输路线安排问题模型及求解算法。Study on...

美的空调RU是什么故障
Ru是自动的意思。建议如下:1、空调温度的设置一定要保持在合理的温度范围,也就是夏天应为26℃~28℃,冬天应在18℃~20℃。空调温度室内与室外不能相差太大,一般在5℃~10℃为宜。如果温度相差太大的话,在进出的时候经受气温骤变,很容易患感冒等疾病。2、首先要使人感觉舒适。就温度而言,使人...

软着陆的拼音
软着陆的拼音是Ruǎn zhuó lù。软着陆是指航天器在着陆时通过软件控制,实现低速度、低冲击度着陆的方式。与硬着陆相比,其更加安全可靠,同时降低对航天器的损伤。扩展知识:软着陆技术要点主要包括姿态控制、高精度控制、实时状态估计等。其中姿态控制是指通过制导算法和推力矢量控制实现空间飞行器在较...

算法设计比赛做什么算法好
http:\/\/acm.timus.ru这几个OJ上练习比较好的题目分类(POJ上的)1。这个是我最喜欢的初期:一.基本算法:(1)枚举. (poj1753,poj2965)(2008-10-27Done 位运算+宽搜)(2)贪心(poj1328,poj2109,poj2586)(3)递归和分治法.(4)递推.(5)构造法.(poj3295)(6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj...

平罗县15085675337: LRU页面淘汰算法是什么? -
南委抗骨: LRU算法 最近最久未使用(LRU)的页面置换算法,是根据页面调入内存后的使用情况进行决策的.由于无法预测各页面将来的使用情况,只能利用“最近的过去”作为“最近的将来”的近似,因此,LRU置换算法是选择最近最久未使用的页面予以淘汰.该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间t,当须淘汰一个页面时,选择现有页面中其t值最大的,即最近最久未使用的页面予以淘汰.LRU的实现(需要“堆栈”支持) 可利用一个特殊的栈来保存当前使用的各个页面的页面号.每当进程访问某页面时,便将该页面的页面号从栈中移出,将它压入栈顶.因此,栈顶始终是最新被访问页面的编号,而栈底则是最近最久未使用页面的页面号.

平罗县15085675337: LRU页面置换算法的实现 -
南委抗骨: 我会.就是最近未使用的算法吧.例如一个三道程序,等待进入的是1,2,3,4,4,2,5,6,3,4,2,1.先分别把1,2,3导入,然后导入4,置换的是1,因为他离导入时间最远.然后又是4,不需要置换,然后是2,也不需要,因为内存中有,到5的时候,因为3最远,所以置换3,依次类推,还有不懂联系我吧.QQ:243926566

平罗县15085675337: LRU算法具体怎么算的,有没有例子 -
南委抗骨: LRU算法参考例子如下: include<iostream> using namespace std;int ans[1000];//存放原序列 int block[1000];//机器分给程序的内存块 int num[1000];//每个页面在内存中待的时间 int n; //页面流数 int m; //内存块数 int sum;//命中次数 //初...

平罗县15085675337: LRU最近最久未使用算法~~ -
南委抗骨: 最简单的算法,他出题的话肯定会给你好几个时间段的( 内存调用,页面调用,好多计算机相关都有这个算法,还有其他算法,你应该懂),所谓醉酒未使用就是你看以前那几个时间段,哪个页面或者内存单元到现在没有用的时间最长,就这个意思了.

平罗县15085675337: lru算法提出者是谁?其基本思想是什么?其基于什么假设?希望好心的高手给予解答. -
南委抗骨: LRU是Least Recently Used的缩写,即最近最少使用页面置换算法,是为虚拟页式存储管理服务的. LRU算法的提出,是基于这样一个事实:在前面几条指令中使用频繁的页面很可能在后面的几条指令中频繁使用.反过来说,已经很久没有使用的页面很可能在未来较长的一段时间内不会被用到.这个,就是著名的局部性原理 ——比内存速度还要快的cache,也是基于同样的原理运行的.因此,我们只需要在每次调换时,找到最近最少使用的那个页面调出内存.这就是LRU算法的全部内容.

平罗县15085675337: LRU算法,缺页是什么概念?怎么计算缺页次数?有一个虚拟存储系统,分配给某个进程3 页内存(假设开始时内存为空),页面访问序列是:2,3,2,1,5,2,4,5,... -
南委抗骨:[答案] 根据LRU算法,需要替换上次使用距现在最远的页面. 首先2,3,2这三页进入内存(进程只分配到3个页面,切顺序为由内到外,第二个2进入时不缺页,所以共缺页2次),1进入时,内存不满且内存中没有1这个页面即第1个进入内存,所以顺序是2,3,1...

平罗县15085675337: 描述几个常用的页面转换(淘汰)算法基本原理 -
南委抗骨: 某虚拟存储系统采用最近最少使用(LRU)页面淘汰算法,假定系统为每个作业分配3个页面的主存空间,其中一个页面用用来存放程序.现有某作业的部分语句如下: Var A:Array[1...150,1...100] of integer; i,j:interger; for i=1 to 150 do for j=1to ...

平罗县15085675337: 操作系统 页面置换算法LRU -
南委抗骨: 这两种方法都正确,LRU算法有几种实现,前一种是基于计数器的,需要统计之前的引用页,后一种是基于队列的调度,只调整队列就能找到最近未使用的页.如果是考试的话可以说明一下用了哪种方法,个人感觉第二种方法比较合适 《操作系统概念》第七版·高等教育出版社P286

平罗县15085675337: LRU是什么 -
南委抗骨: LRU是Least Recently Used最近最久未使用算法.Oracle系统使用的一种算法,对于在内存中但最近又不用的数据块(内存块)叫做LRU,Oracle会根据那些数据属于LRU而将其移出内存而腾出空间来加载另外的数据.什么是LRU算法? LRU是Least Recently Used的缩写,即最近最少使用页面置换算法,是为虚拟页式存储管理服务的.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网