java 最少使用(lru)置换算法_最近最久未使用算法(LRU)介绍与实现

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 17:35   1659   0

概念

LRU 全称是 Least Recently Used,即最近最久未使用算法,它是页面置换算法的一种。

原理

LRU 算法根据数据的历史访问记录来进行淘汰数据,其核心思想是「如果数据最近被访问过,那么将来被访问的几率也更高」。

我们可以通过一个有内存限制的栈来表示这个算法。

  • get(key):如果 key 在栈中,则返回对应的 value 值,否则返回 -1
  • put(key):如果 key 不在栈中,则将该 key 、value put 进栈中(注意,如果栈内存已满,则必须把最近最久未使用的元素从栈中删除);如果 key 在栈中,则重置value的值。

a94e9f6b8c78669fce3aded273417f64.png
LRU

实现

如果通过一个栈来实现,每次 get 值后都需要进行排序,会带来一些额外的时间复杂度。如果需要从 O(1) 时间复杂度内解决问题,一般会使用 Hash table + Doubly linked list 的方式。

  • Hash table:O(1) 时间复杂度查找元素。
  • Doubly linked list:O(1) 时间复杂度增删改元素。

Doubly linked list(双项链表)

de988a5881409a246b486dffe50a4987.png
双项链表

定义一个初始的双项链表,当需要往内存中 put 值时,把它放到双项链表 Dummy Tail 之前的位置。

0e404722611b5f30b114e1beaf9a829d.png
put (2, 2)

0e2ec31b1a5a77643735fad1ad7fdeef.png
put (3, 3)

如果已经超过内存限制,则需要先把 Dummy Head 之后的元素移除掉,然后再添加新的值。

b9d616b90396b635fca04e382c0c49ca.png
put (4, 3) 前需要移除 (2, 2)

faeaf873059165a0fe07fa6f5dfd92cd.png
put (4, 3)

当需要从双项链表中获取对应的值时,获取之后把对应的值移到 Dummy Tail 之前的位置(使用过的数据避免先被 delete)。

9aed2101b2eae8211cf4ef67a38b9b5b.png
get(3)

如果需要从双项链表中获取的值不存在,则不进行改动。

9aed2101b2eae8211cf4ef67a38b9b5b.png
get(5)

如果往内存中 put 的数据已经存在,则先把该数据从双项链表中移动到 Dummy Tail 之前的位置。然后更新对应的值。

faeaf873059165a0fe07fa6f5dfd92cd.png
put(4, 7) 之前先把 (4, 3) 移动到 Dummy Tail 之前的位置

1bd9b63125f8f0a4840dccabdf5a2722.png
更新值

Hash table(哈希表)

在每次往双项链表中 put 值时我们都需要往 Hash table 里面存储对应 key、value。

这样当我们需要查找双项链表中是否已存在对应的值。

JavaScript 示例

/**

应用

  • 缓存

参考

https://en.wikipedia.org/wiki/Cache_replacement_policies

https://backtobackswe.com/

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP