C# 如何实现一个LRU缓存 - 最近最少使用算法的C#实现

来源:这里教程网 时间:2026-02-21 17:32:41 作者:

用 C# 实现一个高效 LRU 缓存,关键在于让 getput 操作都保持 O(1) 时间复杂度。标准解法是哈希表(

Dictionary
)配合双向链表(
LinkedList<node></node>
),而不是靠 List 或 Queue 模拟——后者会导致移动或删除节点时退化到 O(n)。

核心结构:Dictionary + LinkedList

哈希表负责快速定位 key 对应的节点;双向链表按访问顺序组织节点,尾部为“最近使用”,头部为“最久未使用”。

Dictionary<tkey linkedlistnode>></tkey>
存 key → 链表节点映射
LinkedList<cacheditem></cacheditem>
维护访问时序,新访问或新增都移到
Last
CachedItem
是自定义结构体或类,含
Key
Value

Get 操作:查到就移到链表尾

如果 key 存在,先从 Dictionary 取出对应节点,再调用

Remove()
+
AddLast()
把它挪到链表末尾,表示“刚刚被使用”。最后返回 value。

没命中直接返回
default(TValue)
或抛异常,按需设计
注意:不要新建节点或改 value,只做位置调整

Put 操作:更新或插入,并处理容量超限

分两种情况:

key 已存在:更新节点的 value,再移至链表尾 key 不存在:新建
CachedItem
AddLast
入链表,并加入 Dictionary
插入后若
Count >= Capacity
,则移除
First
节点,同时从 Dictionary 中删掉它的 key

小技巧与避坑点

避免常见低效写法:

别用
List<t></t>
手动找索引再 RemoveAt —— 删除中间元素是 O(n)
别每次 get 都重建 Dictionary 或重排整个链表 注意 null 值处理:value 类型为可空引用类型时,
default
不代表“不存在”,建议用
TryGetValue
+ 显式判断
线程安全?如需并发访问,可包装成
ConcurrentDictionary
+ 锁住链表操作,或用
ReaderWriterLockSlim

基本上就这些。C# 的

LinkedList
天然支持 O(1) 的节点移除和尾插,搭配 Dictionary 就能干净利落地落地 LRU。不需要第三方库,.NET 自带组件足矣。

相关推荐

热文推荐