-
缓冲淘汰策略:指缓存被用满时清理数据的优先顺序
- 先进先出策略(FIFO:First in,First out)
- 最少使用策略(LFU:Least Frequently Used )
- 最近最少使用策略(LRU:Least Recently Used)
-
链表:通过‘指针’将一组零散的内存块串联起来使用。适合插入、删除操作频繁的场景,查询时间复杂度较高。
-
链表分类
- 单链表
- 循环链表
- 双向链表
- 双向循环链表
-
记录下个节点地址的指针叫做后继指针next
-
单链表:头结点用来记录链表的基地址,尾节点指向一个空地址NULL,表示链表最后一个节点。
-
循环链表:尾结点指向链表的头结点
-
双向链表:每个结点包含后继指针与前驱指针
-
思想:
- 空间换时间(比如缓冲操作):对于执行较慢的程序,通过消耗更多的内存来进行优化。
- 时间换空间(代码跑在手机或者单片机上):消耗过多内存的程序,通过消耗更多的时间来降低内存的消耗。
-
链表与数组性能比拼
时间复杂度 | 数组 | 链表 |
---|---|---|
插入、删除 | O(n) | O(1) |
随机访问 | O(1) | O(n) |
- 什么是缓存
缓冲是一种提高数据读取性能的技术,在硬件设计、软件开发中都有着非广泛的应用,比如常见的 CPU 缓冲、数据库缓冲、浏览器缓冲
- 为什么使用缓存?即缓存的特点
缓冲的大小是有限的,当缓存被用满时,哪些数据应该被清理出去,哪些数据应该被保留?就需要用到缓存淘汰策略(如第 1 点)
- 链表实现 LRU 缓存淘汰策略
当访问的数据没有存储在缓存的链表中时,直接将数据插入链表表头,时间复杂度为O(1);当访问的数据存在于存储的链表中时,将该数据对应的节点,插入到链表表头,时间复杂度为O(n)。如果缓存被占满,则从链表尾部的数据开始清理,时间复杂度为O(1)。
- 数组实现 LRU 缓存淘汰策略
- 方式一:首位置保存最新访问数据,末尾位置优先清理
当访问的数据未存在于缓存的数组中时,直接将数据插入数组第一个元素位置,此时数组所有元素需要向后移动1个位置,时间复杂度为O(n);当访问的数据存在于缓存的数组中时,查找到数据并将其插入数组的第一个位置,此时亦需移动数组元素,时间复杂度为O(n)。缓存用满时,则清理掉末尾的数据,时间复杂度为O(1)。
- 方式二:首位置优先清理,末尾位置保存最新访问数据
当访问的数据未存在于缓存的数组中时,直接将数据添加进数组作为当前最有一个元素时间复杂度为O(1);当访问的数据存在于缓存的数组中时,查找到数据并将其插入当前数组最后一个元素的位置,此时亦需移动数组元素,时间复杂度为O(n)。缓存用满时,则清理掉数组首位置的元素,且剩余数组元素需整体前移一位,时间复杂度为O(n)。(优化:清理的时候可以考虑一次性清理一定数量,从而降低清理次数,提高性能。)