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

  1. 缓存是一种提高数据读取性能的技术,在硬件设计、软件开发中都有着非常广泛的应用,比如常见的CPU缓存、数据库缓存、浏览器缓存等等。
  2. 缓存的大小有限,当缓存被用满时,哪些数据应该被清理出去,哪些数据应该被保留?这就需要缓存淘汰策略来决定。
  3. 常见的策略有三种:先进先出策略FIFO(First In,First Out)、最少使用策略LFU(Least Frequently Used)、最近最少使用策略LRU(Least Recently Used)。

开篇问题:如何用链表来实现LRU缓存淘汰策略?

  • 数组: 连续的内存空间来存储,对内存的要求比较高
  • 链表 : 不需要一块连续的内存空间 ,通过 “指针”将一组零散的内存块串联起来使用

链表(上):如何实现LRU缓存淘汰算法_第1张图片

最常见的链表结构:单链表,双向链表,循环链表

单链表链表(上):如何实现LRU缓存淘汰算法_第2张图片

结点:内存块

尾节点:指向一个空地址

next:记录下一个节点的指针

与数组一样,链表也支持数据的查找,插入,和删除操作

链表(上):如何实现LRU缓存淘汰算法_第3张图片

循环链表是一种特殊的单链表

链表(上):如何实现LRU缓存淘汰算法_第4张图片

和单链表相比,循环链表的优点是从链尾到链头比较方便。当要处理的数据具有环型结构特点时,就特别适合采用循环链表。比如著名的约瑟夫问题。

双向链表(实际开发中,常用)

链表(上):如何实现LRU缓存淘汰算法_第5张图片

空间换时间

思考:

  • 删除结点中“值等于某个给定值”的结点;
  • 删除给定指针指向的结点。

双向循环链表

链表(上):如何实现LRU缓存淘汰算法_第6张图片

链表与数组性能大比拼

链表(上):如何实现LRU缓存淘汰算法_第7张图片

开篇解疑:

我们维护一个有序单链表,越靠近链表尾部的结点是越早之前访问的。当有一个新的数据被访问时,我们从链表头开始顺序遍历链表。

1.如果此数据之前已经被缓存在链表中了,我们遍历得到这个数据对应的结点,并将其从原来的位置删除,然后再插入到链表的头部。

2.如果此数据没有在缓存链表中,又可以分为两种情况:

  • 如果此时缓存未满,则将此结点直接插入到链表的头部;
  • 如果此时缓存已满,则链表尾结点删除,将新的数据结点插入链表的头部。

你可能感兴趣的:(数据结构与算法之美读书笔记,数据结构,算法)