链表(上):如何实现LRU缓存淘汰算法?

链表结构

  1. 单链表
    链表通过指针将一组零散的内存块串联在一起。其中,我们把内存块称为链表的“结点”。为了将所有的结点串起来,每个链表的结点除了存储数据之外,还需要记录链上的下一个结点的地址。如图所示,我们把这个记录下个结点地址的指针叫作后继指针 next。
    image
    我们习惯性地把第一个结点叫作头结点,把最后一个结点叫作尾结点。其中,头结点用来记录链表的基地址。有了它,我们就可以遍历得到整条链表。而尾结点特殊的地方是:指针不是指向下一个结点,而是指向一个空地址 NULL,表示这是链表上最后一个结点。
  2. 循环链表
    循环链表是一种特殊的单链表。它跟单链表唯一的区别就在尾结点。单链表的尾结点指针指向空地址,而循环链表的尾结点指针是指向链表的头结点。它像一个环一样首尾相连,所以叫作“循环”链表,如图所示:
    image
  3. 双向链表
    单向链表只有一个方向,结点只有一个后继指针 next 指向后面的结点。而双向链表,顾名思义,它支持两个方向,每个结点不止有一个后继指针 next 指向后面的结点,还有一个前驱指针 prev 指向前面的结点,如图所示:
    image
  4. 双向循环链表
    如图所示:
    image

基于链表实现 LRU 缓存淘汰算法?

  1. 有哪些缓存淘汰策略?
    所以常见的策略有三种:
    先进先出策略 FIFO(First In,First Out)、最少使用策略 LFU(Least Frequently Used)、最近最少使用策略 LRU(Least Recently Used)
  2. 什么是缓存?
    缓存是一种提高数据读取性能的技术,在硬件设计、软件开发中都有着非广泛的应用,比如常见的CPU缓存、数据库缓存、浏览器缓存等等。
  3. 为什么使用缓存?即缓存的特点
    缓存的大小是有限的,当缓存被用满时,哪些数据应该被清理出去,哪些数据应该被保留?就需要用到缓存淘汰策略。
  4. 什么是缓存淘汰策略?
    指的是当缓存被用满时清理数据的优先顺序。
  5. 链表实现LRU缓存淘汰策略
    LRU的算法思路是真的简单,概括下: 使用定长链表来保存所有缓存的值,并且最老的值放在链表最后面 当访问的值在链表中时: 将找到链表中值将其删除,并重新在链表头添加该值(保证链表中 数值的顺序是从新到旧) 当访问的值不在链表中时: 当链表已满:删除链表最后一个值,将要添加的值放在链表头 当链表未满:直接在链表头添加
    当访问的数据没有存储在缓存的链表中时,分两种情况:
  • 如果此时缓存未满,将数据直接插入链表表头,只需要考虑指针的改变,时间复杂度为O(1);
  • 如果此时缓存已满,则链表尾结点删除,将新的数据结点插入链表的头部,只需要考虑指针的改变,时间复杂度为O(1)。
    当访问的数据存在于存储的链表中时,我们遍历得到这个数据对应的结点,并将其从原来的位置删除,然后再插入到链表的头部,时间复杂度为O(n)。

删除值等于给定值的结点对应的链表操作的总时间复杂度为 O(n)

posted @   fionna  阅读(64)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示