新闻中心

c++如何实现一个高效的LRU缓存_c++缓存淘汰算法设计与实现

2025-12-05
浏览次数:
返回列表
答案:通过哈希表和双向链表结合实现LRU缓存,get和put操作均达到O(1)时间复杂度,利用哈希表快速查找,双向链表维护访问顺序,最新访问节点移至头部,淘汰时从尾部删除,确保高效性。

c++如何实现一个高效的lru缓存_c++缓存淘汰算法设计与实现

实现一个高效的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

Mistral AI被称为“欧洲版的OpenAI”,也是目前欧洲最强的 LLM 大模型平台

Mistral AI 182 查看详情 Mistral AI
  • 若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, ListNode*> 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解决高度差异 

搜索