c++实现泛型LRU

LRU的基本实现原理是hash map + 双向链表

要求get 、set方法的时间复杂度为O(1)

#include <iostream>
#include <unordered_map>
#include <cassert>


using namespace std;

template <typename K, typename V>
struct LListNode {
    K key;
    V value;
    LListNode<K, V>* next;
    LListNode<K, V>* pre;
    LListNode(K k, V v) : key(k), value(v), next(nullptr), pre(nullptr) { }
};

template <typename K, typename V>
class DDList {
public:
    DDList()
     : head_(new LListNode<K, V>(-1, -1)), tail_(new LListNode<K, V>(-1, -1)), size_(0)
    {
        head_->next = tail_;
        tail_->pre = head_;
    }
    DDList(const DDList &) = delete;
    DDList& operator= (const DDList &) = delete;
    ~DDList() 
    {
        LListNode<K, V>* p;
        while (((p = head_->next) != tail_)) {
            erase(p);
            delete p;
        }
        delete head_;
        delete tail_;
    }
    void append_front(LListNode<K, V>* node)
    {
        ++size_;
        node->next = head_->next;
        head_->next = node;
        node->next->pre = node;
        node->pre = head_;
    }
    LListNode<K, V>* remove_back() 
    {
        assert(size_ != 0);
        --size_;
        LListNode<K, V>* p = tail_->pre;
        p->pre->next = tail_;
        tail_->pre = p->pre;
        return p;
    }
    void erase(LListNode<K, V>* node) 
    {
        --size_;
        node->pre->next = node->next;
        node->next->pre = node->pre;
    }
    int get_size() 
    {
        return size_;
    }

private:
    LListNode<K, V>* head_;
    LListNode<K, V>* tail_;
    int size_;

};

template <typename K, typename V>
class LRUCache {
public:
    LRUCache(int capacity) {
        cap_ = capacity;
    }
    
    int get(K key) {
        if (map_cache_.count(key) == 1) {
            auto p = map_cache_[key];
            cache_.erase(p);
            cache_.append_front(p);
            return p->value;
        }
        return -1;
    }
    
    void put(K key, V value) {
        if (map_cache_.count(key) == 1) {
            auto p = map_cache_[key];
            p->value = value;
            cache_.erase(p);
            cache_.append_front(p);
        } else {
            auto p = new LListNode<K, V>(key, value);
            map_cache_[key] = p;
            cache_.append_front(p);
            if (cache_.get_size() > cap_) {
                auto ptr = cache_.remove_back();
                map_cache_.erase(ptr->key);
                delete ptr;
            }

        }
    }

private:
    int cap_;
    DDList<K, V> cache_;
    unordered_map<K, LListNode<K, V>*> map_cache_;
};
//测试代码
int main() {

    LRUCache<int, int>* lRUCache = new LRUCache<int, int>(2);
    lRUCache->put(1, 1); // 缓存是 {1=1}
    lRUCache->put(2, 2); // 缓存是 {1=1, 2=2}
    lRUCache->get(1);    // 返回 1
    lRUCache->put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
    lRUCache->get(2);    // 返回 -1 (未找到)
    lRUCache->put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
    lRUCache->get(1);    // 返回 -1 (未找到)
    lRUCache->get(3);    // 返回 3
    cout << lRUCache->get(4);    // 返回 4
    delete lRUCache;
    return 0;
}

and 无内存泄露
请添加图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值