全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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)

  • 若key不存在,返回-1
  • 存在则将其对应节点移到链表头部(表示最新使用),并返回value

put(int key, int value)

  • 如果key已存在,更新value并移至头部
  • 如果不存在且缓存已满,删除尾部节点(最久未用),同时从哈希表中移除
  • 创建新节点插入头部,并加入哈希表

辅助函数用于简化链表操作:

void removeNode(ListNode* node) {
    node->prev->next = node->next;
    node->next->prev = node->prev;
}

void addToHead(ListNode* node) { node->next = head->next; node->next->prev = node; head->next = node; node->prev = head; }

完整代码示例

#include 

class LRUCache { private: struct ListNode { int key, value; ListNode prev, next; ListNode(int k, int v) : key(k), value(v), prev(nullptr), next(nullptr) {} };

std::unordered_mapzuojiankuohaophpcnint, ListNode*youjiankuohaophpcn cache;
ListNode *head, *tail;
int capacity, size;

void removeNode(ListNode* node) {
    node-youjiankuohaophpcnprev-youjiankuohaophpcnnext = node-youjiankuohaophpcnnext;
    node-youjiankuohaophpcnnext-youjiankuohaophpcnprev = node-youjiankuohaophpcnprev;
}

void addToHead(ListNode* node) {
    node-youjiankuohaophpcnnext = head-youjiankuohaophpcnnext;
    head-youjiankuohaophpcnnext-youjiankuohaophpcnprev = node;
    head-youjiankuohaophpcnnext = node;
    node-youjiankuohaophpcnprev = head;
}

void moveToHead(ListNode* node) {
    removeNode(node);
    addToHead(node);
}

ListNode* removeTail() {
    ListNode* node = tail-youjiankuohaophpcnprev;
    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-youjiankuohaophpcnnext;
        delete tmp;
    }
}

int get(int key) {
    auto it = cache.find(key);
    if (it == cache.end()) return -1;
    ListNode* node = it-youjiankuohaophpcnsecond;
    moveToHead(node);
    return node-youjiankuohaophpcnvalue;
}

void put(int key, int value) {
    auto it = cache.find(key);
    if (it != cache.end()) {
        ListNode* node = it-youjiankuohaophpcnsecond;
        node-youjiankuohaophpcnvalue = value;
        moveToHead(node);
    } else {
        ListNode* newNode = new ListNode(key, value);
        cache[key] = newNode;
        addToHead(newNode);
        ++size;
        if (size youjiankuohaophpcn capacity) {
            ListNode* removed = removeTail();
            cache.erase(removed-youjiankuohaophpcnkey);
            delete removed;
            --size;
        }
    }
}

};

这个实现保证了 get 和 put 操作均为 O(1) 时间复杂度,适合高频读写场景。

基本上就这些。只要理解哈希表+双向链表的配合逻辑,LRU 就不难实现。注意内存释放和指针操作的正确性即可。


# node  # ai  # c++  # red  # int  # 指针  # 数据结构  # 接口  # public  # cap  # 算法  # 链表  # 不存在  # 最久  # 移至  # 快速查找  # 这一  # 放在  # 均为  # 可以通过  # 自定义 


相关文章: 如何彻底删除建站之星生成的Banner?  建站之星五站合一营销型网站搭建攻略,流量入口全覆盖优化指南  建站之星后台密码遗忘?如何快速找回?  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  建站168自助建站系统:快速模板定制与SEO优化指南  建站主机服务器选购指南:轻量应用与VPS配置解析  武汉外贸网站制作公司,现在武汉外贸前景怎么样啊?  如何破解联通资金短缺导致的基站建设难题?  图册素材网站设计制作软件,图册的导出方式有几种?  一键网站制作软件,义乌购一件代发流程?  建站主机默认首页配置指南:核心功能与访问路径优化  宝塔建站后网页无法访问如何解决?  独立制作一个网站多少钱,建立网站需要花多少钱?  官网网站制作腾讯审核要多久,联想路由器newifi官网  C#怎么使用委托和事件 C# delegate与event编程方法  安云自助建站系统如何快速提升SEO排名?  c# Task.Yield 的作用是什么 它和Task.Delay(1)有区别吗  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  如何高效搭建专业期货交易平台网站?  ,想在网上投简历,哪几个网站比较好?  娃派WAP自助建站:免费模板+移动优化,快速打造专业网站  已有域名和空间如何快速搭建网站?  网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?  网站建设制作、微信公众号,公明人民医院怎么在网上预约?  定制建站模板如何实现SEO优化与智能系统配置?18字教程  如何生成腾讯云建站专用兑换码?  如何获取上海专业网站定制建站电话?  广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?  宝塔建站助手安装配置与建站模板使用全流程解析  太原网站制作公司有哪些,网约车营运证查询官网?  高防服务器租用指南:配置选择与快速部署攻略  网站专业制作公司,网站编辑是做什么的?好做吗?工作前景如何?    东莞专业制作网站的公司,东莞大学生网的网址是什么?  常州企业建站如何选择最佳模板?  做企业网站制作流程,企业网站制作基本流程有哪些?  C++如何将C风格字符串(char*)转换为std::string?(代码示例)  宝塔面板创建网站无法访问?如何快速排查修复?  建站VPS能否同时实现高效与安全翻墙?  如何在IIS管理器中快速创建并配置网站?  如何通过宝塔面板实现本地网站访问?  制作营销网站公司,淘特是干什么用的?  c++23 std::expected怎么用 c++优雅处理函数错误返回【详解】  如何通过西部建站助手安装IIS服务器?  如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?  如何用西部建站助手快速创建专业网站?  如何快速登录WAP自助建站平台?  如何通过万网虚拟主机快速搭建网站?  如何零成本快速生成个人自助网站?  rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。