LRU算法为什么使用双向链表+散列表的形式

LRU算法是一种缓存淘汰策略,当缓存满时,会淘汰最久未使用的数据。通过使用双链表和散列表,可以实现高效的节点移动(O(1))和查询(O(1))。文章详细解释了为何选择双链表和散列表,以及如何利用双向链表解决查询和删除节点的问题。
摘要由CSDN通过智能技术生成

什么是LRU算法

LRU算法是一种缓存淘汰策略,也称为最近最久未使用算法。对于计算机来说,缓存的容量是有限的,当缓存满的时候 势必要淘汰掉无用或没那么有用的缓存,我们的LRU邀约而生。其思路就是淘汰掉最久没有使用到访问到的缓存。

思路

哪个数据是最久未使用的呢?

我们可以将每一个数据当成一个节点,每当我们访问它们的时候,就将这个节点提到节点的头部,这样后最后面的节点就是我们需要淘汰的最久未使用的数据

图解

实现的数据结构

现在思路有了,让我们来说说为什么使用双链表+散列表的数据结构吧~

  1. 首先我们需要将每一个节点储存起来,势必需要一个集合来储存起来。(使用链表

  1. 这就有了两种选择ArrayListLinkedList这两种常见的集合。ArrayList集合底层使用的是数组实现,而LinkedList集合底层使用的是链表实现。

  1. 而我们每一次访问都需要将访问到的节点进行移动到第一个节点,后面的节点需要依次往下移动。我们的数组移动起来是非常耗时的,复杂度O(n),显然不划算,故选择链表,移动一个节点只需要将链表的指向改变,复杂度O(1)。所以我们将移动节点的性能提高到了O(1)

  1. 事实上是链表也有一些小问题,我们都知道,链表的移动是O(1),但是链表的查询性能是O(n)呀。当我们需要访问某个节点的时候,我们需要遍历一遍链表才知道这个节点是否在我们的缓存之中,这显然不合适。(使用散列表

  1. 我们可以添加一个散列表去提高我们的查询效率。最合适的就是我们最常用的HashMap~

  1. 我们的HashMap存储它们的key,value指向节点本身。查询时,只需要判断HashMap是否存在这个key,复杂度O(1),存在就直接获取到value也就是那个节点。所以我们将查询性能也提高到了O(1)

  1. 使用了散列表提高了查询效率的同时,也同样多出了一些小小的问题。因为使用了散列表可以快速精准的定位某一个节点,但是我们要做的不只是将这个节点移动到头部,还需要将这个节点删除,也就是将上一个节点连接到下一个节点。(使用双向链表

  1. 使用了双向链表就可以快速得到 查询到的节点的上一个节点,就可以将上一个节点的指向从该节点转变为下一个节点。

图解如下

第一次这么去写东西呀,可能出现考虑不周的地方,如果遇到不对的地方希望可以多多指正,谢谢大家~

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值