C++ 实现 LRU 缓存机制,以及 采用模板的 LRU

LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。

LeetCode 原题链接

思路,主要涉及到查找和更新,采用双向链表加 unordered_map 可以把时间复杂度降为  O(1)

其中,双向链表可以自己实现,也可以采用 STL 中的 list ,其中 list 里面有封装好的实现,可以精简代码

自己实现,更锻炼自己的对链表和 LRU 缓存的理解

基于 list 的实现

先贴上代码 ,其中 splice 函数就是为这一题而生的 : 第一个参数为目标位置,第二参数为要移动的链表,后面的参数用来限定位置,若只有两个参数时,这个函数会把要移动的链表整体移动到目标位置;要是指定位置了,只会移动范围内的,一个参数代表单个节点,两个参数代表,起始点和终点。  这里我们只需要移动一个节点,所以有三个参数。

main 函数可以用第二个实现里面的代码

class LRUCache {
private:
    int cap; // 缓存容量
    list<pair<int,int>> cacheList; // 双向链表,方便插入和删除
    // key 为数据的密钥, value 为存放当前密钥的节点 迭代器
    unordered_map<int, list<pair<int, int>>::iterator> cacheMap;
public:
    LRUCache( int capacity ) : cap(capacity) {};

    int get( int key ) {
        auto iter = cacheMap.find(key);
        // iter 的类型为  unordered_map<int, list<pair<int, int>>::iterator>::iterator
        if (iter==cacheMap.end()) //  查找元素不在容器内
            return -1;

        // list 的一个快捷方法,参数分别为   位置,所移动的链表,要移动的节点(可以为一个范围)
        cacheList.splice( cacheList.begin(), cacheList, iter->second );
        return iter->second->second;
    }

    void put( int key, int value ) {
        auto iter = cacheMap.find( key );
        
        if (iter == cacheMap.end()) {
            // 新增当前元素
            cacheList.push_front({key, value});
            cacheMap.insert({ key, cacheList.begin() });

            // 若容量超了,则删除末尾节点,并在 哈希表中删除
            if (cacheMap.size() > cap) 
                cacheMap.erase(cacheList.back().first), cacheList.pop_back();
        } else {
            // 更新当前节点, 并移动到第一个位置
       
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值