146. LRU缓存机制/C++

在这里插入图片描述
整个程序看起来颇为复杂。
如果不考虑效率的话,可以只用一个双向链表。
最近访问的节点就放到队尾。
加入新节点时,也直接放到队尾;如果容量不够就先把队首节点删掉,再把新节点加入队尾。

但是如果考虑到效率。
每次获取和加入节点时,都要判断该节点是否存在(O(n))。
因此使用一个hash表来存储key,可以以O(1)来判断节点是否存在。
并且hash表的value就是对应节点。

//双向链表节点
struct DoubleListNode{
    int _key;
    int _val;
    DoubleListNode* pre;
    DoubleListNode* next;
    DoubleListNode(int key, int value):_key(key),_val(value),pre(nullptr),next(nullptr){}
};

class LRUCache {
public:
	//首尾节点不存储信息,只方便在队首取出节点,在队尾插入节点
    LRUCache(int capacity):_capacity(capacity) {
        _head = new DoubleListNode(-1,-1);
        _tail = new DoubleListNode(-1,-1);
        _head->next = _tail;
        _tail->pre = _head;
    }
    
    int get(int key) {
    	//如果不存在就返回-1
        if(_map.count(key) == 0) return -1;
        //如果存在就把节点移到队尾
        DoubleListNode* node = _map[key];
        kick_node(node);
        push_back(node);
        return node->_val;
    }
    
    void put(int key, int value) {
    	//如果存在,就更新value,把节点移到队尾
        if(_map.count(key)){
            DoubleListNode* node = _map[key];
            node->_val = value;
            kick_node(node);
            push_back(node);
        }
        //如果不存在就准备新建节点,插入到队尾
        else{
        	//如果满了就把删掉队首节点
            if(_map.size()==_capacity)
                pop_front();
            //把新节点加入到hash表以及队尾
            DoubleListNode* node = new DoubleListNode(key,value);
            _map[key] = node;
            push_back(node);
        }
    }
private:
	//从链表以及hash表删去队首节点
    void pop_front(){
        DoubleListNode* del = _head->next;
        _head->next = del->next;
        del->next->pre = _head;
        _map.erase(del->_key);
        delete del;
        del = nullptr;
    }
    
    //将node加入到队尾
    void push_back(DoubleListNode* node){
        node->pre = _tail->pre;
        node->next = _tail;
        _tail->pre->next = node;
        _tail->pre = node;
    }
    
    //将node从链表移出来(不删除)
    void kick_node(DoubleListNode* node){
        node->next->pre = node->pre;
        node->pre->next = node->next;
        node->next = nullptr;
        node->pre = nullptr;
    }
    
    int _capacity;
    map<int,DoubleListNode*> _map;
    DoubleListNode* _head;
    DoubleListNode* _tail;
};

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache* obj = new LRUCache(capacity);
 * int param_1 = obj->get(key);
 * obj->put(key,value);
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值