每天一点点之数据结构与算法 - 应用 - 分别用链表和数组实现LRU缓冲淘汰策略
一、基本概念:
1、什么是缓存?
缓存的大小是有限的,当缓存被用满时,哪些数据应该被清理出去,哪些数据应该被保留?就需要用到缓存淘汰策略。
常见的3种包括先进先出策略FIFO(First In,First Out)、最少使用策略LFU(Least Frenquently Used)、最近最少使用策略LRU(Least Recently Used)。
二、实现LRU缓存淘汰策略
我的思路是这样的:我们维护一个有序单链表,越靠近链表尾部的结点是越早之前访问的。当有一个新的数据被访问时,我们从链表头开始顺序遍历链表。
1) 如果此数据之前已经被缓存在链表中了,我们遍历得到这个数据对应的结点,并将其从原来的位置删除,然后再插入到链表的头部。
2)如果此数据没有在缓存链表中,又可以分为两种情况:
- 如果此时缓存未满,则将此结点直接插入到链表的头部;
- 如果此时缓存已满,则链表尾结点删除,将新的数据结点插入链表的头部。
这样我们就用链表实现了一个 LRU 缓存,是不是很简单?
现在我们来看下 m 缓存访问的时间复杂度是多少。因为不管缓存有没有满,我们都需要遍历一遍链表,所以这种基于链表的实现思路,缓存访问的时间复杂度为 O(n)。
实际上,我们可以继续优化这个实现思路,比如引入(Hash table)来记录每个数据的位置,将缓存访问的时间复杂度降到 O(1)。
当访问的数据未存在于缓存的数组中时,直接将数据插入数组第一个元素位置,此时数组所有元素需要向后移动1个位置,时间复杂度为O(n);当访问的数据存在于缓存的数组中时,查找到数据并将其插入数组的第一个位置,此时亦需移动数组元素,时间复杂度为O(n)。缓存用满时,则清理掉末尾的数据,时间复杂度为O(1)。
当访问的数据未存在于缓存的数组中时,直接将数据添加进数组作为当前最有一个元素时间复杂度为O(1);当访问的数据存在于缓存的数组中时,查找到数据并将其插入当前数组最后一个元素的位置,此时亦需移动数组元素,时间复杂度为O(n)。缓存用满时,则清理掉数组首位置的元素,且剩余数组元素需整体前移一位,时间复杂度为O(n)。(优化:清理的时候可以考虑一次性清理一定数量,从而降低清理次数,提高性能。)
每天一点点之数据结构与算法 - 应用 - 分别用链表和数组实现LRU缓冲淘汰策略的更多相关文章
- 数据结构与算法之美 06 | 链表(上)-如何实现LRU缓存淘汰算法
常见的缓存淘汰策略: 先进先出 FIFO 最少使用LFU(Least Frequently Used) 最近最少使用 LRU(Least Recently Used) 链表定义: 链表也是线性表的一种 ...
- 算法之如何实现LRU缓冲淘汰策略
1)什么是缓存? 缓存是一种提高数据读取性能的技术,在硬件设计.软件开发中都有着非广泛的应用,比如常见的CPU缓存.数据库缓存.浏览器缓存等等. 2)为什么使用缓存?即缓存的特点缓存的大小是有限的,当 ...
- JavaScript 数据结构与算法之美 - 线性表(数组、栈、队列、链表)
前言 基础知识就像是一座大楼的地基,它决定了我们的技术高度. 我们应该多掌握一些可移值的技术或者再过十几年应该都不会过时的技术,数据结构与算法就是其中之一. 栈.队列.链表.堆 是数据结构与算法中的基 ...
- JavaScript 版数据结构与算法(三)链表
今天,我们要讲的是数据结构与算法中的链表. 链表简介 链表是什么?链表是一种动态的数据结构,这意味着我们可以任意增删元素,它会按需扩容.为何要使用链表?下面列举一些链表的用途: 因为数组的存储有缺陷: ...
- Java数据结构和算法(七)——链表
前面博客我们在讲解数组中,知道数组作为数据存储结构有一定的缺陷.在无序数组中,搜索性能差,在有序数组中,插入效率又很低,而且这两种数组的删除效率都很低,并且数组在创建后,其大小是固定了,设置的过大会造 ...
- 链表:如何实现LRU缓存淘汰算法?
缓存淘汰策略: FIFO:先入先出策略 LFU:最少使用策略 LRU:最近最少使用策略 链表的数据结构: 可以看到,数组需要连续的内存空间,当内存空间充足但不连续时,也会申请失败触发GC,链表则可 ...
- 【数据结构与算法】Java制作一个简单数组类
bobo老师的玩转算法系列–玩转数据结构 简单记录 文章目录 不要小瞧数组 - 制作一个数组类 1 .使用Java中的数组 数组基础 简单使用 2.二次封装属于我们自己的数组 数组基础 制作属于我们自 ...
- 【数据结构与算法Python版学习笔记】递归(Recursion)——优化问题与策略
分治策略:解决问题的典型策略,分而治之 将问题分为若干更小规模的部分 通过解决每一个小规模部分问题,并将结果汇总得到原问题的解 递归算法与分治策略 递归三定律 体现了分支策略 应用相当广泛 排序 查找 ...
- 数据结构和算法 c#– 1.单项链表
1.顺序存储结构 Array 1.引用类型(托管堆) 2.初始化时会设置默认值 2.链式存储结构 2.1.单向链表 2.2.循环链表 2.3.双向链表
随机推荐
- 扩展的Sobel 算子
Custom Extended Sobel Filters https://arxiv.org/pdf/1910.00138.pdf sobel算子是进行边缘检测的一个重要算子.它通常是一个3x3的 ...
- 【capstone/ropgadget】环境配置
具体环境配置可参考 https://github.com/JonathanSalwan/ROPgadget/tree/master 作者给出的安装方式 但具体配置中出现了问题,如引用时出现如下错误: ...
- Program-Language
1. 主流编程语言 2. 编程语言分类 2.1 编译or解释 2.2 按照客观系统的描述可分为两类 2.3 按照编程范型可分为 3. 语言范式 Paradigm 4. 计算机语 ...
- mysql sql语句不同平台上大小写区分
- 使用Picasso实现图片圆角和图片圆形
作者很好的文章访问量缺很少也很难搜到(我这里插个眼以后用的到)作者:先知丨先觉 来源:CSDN 原文:https://blog.csdn.net/github_33304260/article/det ...
- HDU 5504:GT and sequence
GT and sequence Accepts: 95 Submissions: 1467 Time Limit: 2000/1000 MS (Java/Others) Memory Limi ...
- ArrayList与LindedList区别
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构. 2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList ...
- Docker Yearning + Inception SQL审核平台搭建
[一]安装[1.1]系统环境系统环境:CentOS Linux release 7.6.1708 (Core)系统内存:4G系统内核:1Python:3.6.4关闭iptables and selin ...
- 【LeetCode】合并两个有序数组
[问题] 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明:初始化 nums1 和 nums2 的元素数量分别为 m ...
- HZNU-ACM寒假集训Day12小结 数论入门 题解
算不出的等式 BJOI2012 看到这题 真没什么办法 无奈看题解 1.注意到p/q 联想到斜率 2.注意到 [ ] 联想到整点 注意到k在变化,构造一次函数 f(x)=p/q*x ,g(x)=q/p ...