新闻中心
c++如何实现一个高效的LRU缓存_c++缓存淘汰算法设计与实现
答案:通过哈希表和双向链表结合实现LRU缓存,get和put操作均达到O(1)时间复杂度,利用哈希表快速查找,双向链表维护访问顺序,最新访问节点移至头部,淘汰时从尾部删除,确保高效性。

实现一个高效的LRU(Least Recently Used)缓存,核心在于快速访问数据的同时维护访问顺序,使得最久未使用的元素能被快速淘汰。C++中可以通过结合哈希表和双向链表来达到O(1)的插入、查找和删除效率。
LRU缓存的基本原理
LRU缓存根据“最近最少使用”原则管理有限容量的数据。当缓存满时,优先淘汰最久未访问的条目。为了高效实现这一机制,需要:
- 快速查找某个key是否在缓存中 —— 使用哈希表(unordered_map)
- 维护访问顺序,支持快速移动或删除节点 —— 使用双向链表(自定义或list)
将两者结合:哈希表存储key到链表节点的指针映射,链表按访问时间排序,最新访问的放在头部,淘汰从尾部进行。
数据结构设计
定义双向链表节点和缓存主体结构:
struct ListNode {
int key, value;
ListNode *prev, *next;
ListNode(int k, int v) : key(k), value(v), prev(nullptr), next(nullptr) {}
};
缓存类包含:
- 哈希表:unordered_map
快速定位节点 - 双向链表头尾指针:方便在首尾操作
- 容量限制:capacity
- 当前大小:size
关键操作实现
主要接口为 get 和 put:
get(int key):
Mistral AI
Mistral AI被称为“欧洲版的OpenAI”,也是目前欧洲最强的 LLM 大模型平台
182
查看详情
- 若key不存在,返回-1
- 存在则将其对应节点移到链表头部(表示最新使用),并返回value
put(int key, int value):
- 如果key已存在,更新value并移至头部
- 如果不存在且缓存已满,删除尾部节点(最久未用),同时从哈希表中移除
- 创建新节点插入头部,并加入哈希表
辅助函数用于简化链表操作:
void removeNode(ListNode* node) {
node->prev->next = node->next;
node->next->prev = node->prev;
}
<p>void addToHead(ListNode* node) {
node->next = head->next;
node->next->prev = node;
head->next = node;
node->prev = head;
}</p>完整代码示例
#include <unordered_map>
<p>class LRUCache {
private:
struct ListNode {
int key, value;
ListNode <em>prev, </em>next;
ListNode(int k, int v) : key(k), value(v), prev(nullptr), next(nullptr) {}
};</p><pre class='brush:php;toolbar:false;'>std::unordered_map<int, Lis
tNode*> cache;
ListNode *head, *tail;
int capacity, size;
void removeNode(ListNode* node) {
node->prev->next = node->next;
node->next->prev = node->prev;
}
void addToHead(ListNode* node) {
node->next = head->next;
head->next->prev = node;
head->next = node;
node->prev = head;
}
void moveToHead(ListNode* node) {
removeNode(node);
addToHead(node);
}
ListNode* removeTail() {
ListNode* node = tail->prev;
removeNode(node);
return node;
}public: LRUCache(int cap) : capacity(cap), size(0) { head = new ListNode(0, 0); tail = new ListNode(0, 0); head->next = tail; tail->prev = head; }
~LRUCache() {
while (head) {
ListNode* tmp = head;
head = head->next;
delete tmp;
}
}
int get(int key) {
auto it = cache.find(key);
if (it == cache.end()) return -1;
ListNode* node = it->second;
moveToHead(node);
return node->value;
}
void put(int key, int value) {
auto it = cache.find(key);
if (it != cache.end()) {
ListNode* node = it->second;
node->value = value;
moveToHead(node);
} else {
ListNode* newNode = new ListNode(key, value);
cache[key] = newNode;
addToHead(newNode);
++size;
if (size > capacity) {
ListNode* removed = removeTail();
cache.erase(removed->key);
delete removed;
--size;
}
}
}};
这个实现保证了 get 和 put 操作均为 O(1) 时间复杂度,适合高频读写场景。
基本上就这些。只要理解哈希表+双向链表的配合逻辑,LRU 就不难实现。注意内存释放和指针操作的正确性即可。
以上就是c++++如何实现一个高效的LRU缓存_c++缓存淘汰算法设计与实现的详细内容,更多请关注其它相关文章!
# 移至
# 宝鸡全网SEO优化案例
# 辽宁SEO优化效果好
# 在社交网站产品推广简历
# seo关键词排名实用软件有哪些
# 微信公众号推广的网站
# 苏州网站建设模板免费
# 网站建设怎么寻找客户
# seo关键词排名来火22星来
# 广西网站建设公司平台
# 百家号与seo
# 快速查找
# node
# 如何使用
# 尼克
# 不存在
# 最久
# 欧洲
# 数据结构
# 如何实现
# 链表
# red
# c++
# ai
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
C++ map遍历方法大全_C++ map迭代器使用总结
内存疯狂猛猛涨价:主板销量直接腰斩!
修复二维数组索引越界异常:一维循环到二维坐标的正确映射
mc.js官网登录入口 mc.js官方登录入口最新版
qq浏览器如何查看和导出已保存的密码 qq浏览器密码管理器数据备份教程
Sublime怎么配置Nim语言环境_Sublime Nim代码高亮与补全
PyTorch模型训练效果不佳?深入剖析常见错误与调试技巧
PHP 枚举:根据字符串获取枚举案例的策略与实现
妖精动漫免费平台 妖精动漫官网资源观看网址
J*aScript实现动态背景色下的文本与按钮颜色自适应调整
Lar*el的路由模型绑定怎么用_Lar*el Route Model Binding简化控制器逻辑
响应式容器内容自动缩放与宽高比维持教程
C++如何生成随机数_C++ random库使用方法与范围设置
苹果手机指南针不准怎么校准 传感器校准方法详解【建议收藏】
拼多多视频播放卡顿如何处理 拼多多视频播放优化技巧
C++如何打印当前代码行号与文件名_C++预定义宏FILE与LINE的使用
windows10怎么关闭系统提示音_windows10彻底静音设置方法
Win10系统怎么查看已安装更新_Win10卸载有问题的更新补丁
探索高级语言到C/C++的转译路径:以Go为例及内存管理策略
Yandex搜索引擎一键访问入口_俄罗斯Yandex官网免登录
AO3最新镜像入口 Archive of Our Own官方平台访问
Win11怎么设置鼠标指针速度_Win11提高鼠标指针精确度选项
MAC如何将整个网页截长图_MAC使用Safari的导出为PDF或第三方工具
QQ邮箱网页版入口登录 QQ邮箱在线邮箱官方通道
C++如何使用AddressSanitizer(ASan)_C++调试工具中检测内存访问错误的利器
谷歌浏览器一键优化方案_谷歌浏览器直达主页极速不卡版
深入理解J*aScript Promise异步执行与微任务队列
狙击外星人小游戏开始_狙击外星人小游戏立即开始
电脑安装程序提示“错误1722”怎么办_Windows Installer服务问题解决【教程】
小红书网页版入口链接分享 小红书官网直接进
ArrayList与LinkedList核心操作的Big-O复杂度分析
微信网页版官方入口教程 微信网页版网页版快速登录步骤
Python中高效访问嵌套字典与列表中的键值对
邮政编码查询不到怎么办_邮政编码查询不到的常见原因与对策
深入理解Google Cloud Datastore查询:祖先路径与数据一致性
Word2013如何插入视频和音频媒体_Word2013媒体插入的多媒体支持
J*a TimerTask文件监控:HashMap状态管理与常见陷阱规避指南
蓝湖怎样用切图标注提对接效率_蓝湖用切图标注提对接效率【设计对接】
LINUX下如何进行磁盘分区_fdisk与parted工具在LINUX中的使用对比
怎么在mac上运行html代码_mac运行html代码方法【指南】
mcjs网页版流畅运行 mcjs低配电脑畅玩入口
QQ邮箱官方登录入口_QQ邮箱网页版快捷使用平台
mysql密码锁定怎么解锁_mysql密码锁定解锁后修改密码步骤
整合Supabase认证与Django模型:跨模式迁移的解决方案
Pygame教程:解决用户输入与游戏状态更新不同步问题
Win11怎么开启省电模式_Win11电池节电模式自动开启
Typer应用中灵活处理命令行参数的令牌化与解析
基于动态规划的房屋花卉种植最小成本算法详解
Go语言中高效处理x-www-form-urlencoded表单数据
css子元素高度不一致导致布局错位怎么办_使用align-items:stretch解决高度差异


2025-12-05
浏览次数:次
返回列表
tNode*> cache;
ListNode *head, *tail;
int capacity, size;
void removeNode(ListNode* node) {
node->prev->next = node->next;
node->next->prev = node->prev;
}
void addToHead(ListNode* node) {
node->next = head->next;
head->next->prev = node;
head->next = node;
node->prev = head;
}
void moveToHead(ListNode* node) {
removeNode(node);
addToHead(node);
}
ListNode* removeTail() {
ListNode* node = tail->prev;
removeNode(node);
return node;
}