【数据结构】LRU缓存机制结构(C++实现)

  • Post author:
  • Post category:其他

算法描述

LRU实际上是设计一个数据结构,有如下要求:

  • 包含容量capacity和当前元素数量size
  • 包含插入方法put和获取get
  • 时间复杂度为O(1);

算法设计

一般来说通过两个数据结构来实现LRU机制,即

  • 哈希表:用于存取【鍵-节点】对
  • 双向链表:用于存取【键-值】对,尾节点为最新加入的节点,头节点的后一结点为LRU节点

在这里插入图片描述

struct Node{
    int key,value;
    Node *pre,*next;
    Node(int _k,int _v):
        key(_k),value(_v),pre(nullptr),next(nullptr){}
};
class LRUCache {
    const int MAXSIZE=3001;
    Node* head;				
    Node* tail;				/* for tail insertion method */
    vector<Node*> cache_;
    int capacity;
    int size;
public:
    LRUCache(int c):
        size(0),capacity(c) {
            head=new Node(-1,-1);
            tail=head;
            cache_.resize(MAXSIZE,nullptr);
    }
    
    int get(int key) {
        if(cache_[key]==nullptr){
            /* not existed */
            return -1;
        }else{
            /* existed */
            Node* cur=cache_[key];
            /* if cur is tail, ignore update*/
            if(cur!=tail){
                /* release from original position */
                cur->pre->next=cur->next;
                cur->next->pre=cur->pre;
                /* update position to tail */
                tail->next=cur;
                cur->pre=tail;
                cur->next=nullptr;
                tail=cur;
            }
            return cur->value;
        }
    }
    
    void put(int key, int value) {
        if(get(key)==-1){
            /* existed */
            if(size<capacity){
                size++;
            }else{
                /* delete the head->next node */
                Node *popNode=head->next;
                if(popNode==tail){
                    tail->next=nullptr;
                    tail->pre=nullptr;
                    head->next=nullptr;
                    tail=head;
                }else{
                    head->next=popNode->next;
                    popNode->next->pre=head;
                }
                popNode->next=nullptr;
                popNode->pre=nullptr;
                /* important! remove it from cache */
                cache_[popNode->key]=nullptr;
                delete popNode;
            }
            /* create new node (tail insertion)*/
            Node *newNode=new Node(key,value);
            cache_[key]=newNode;
            tail->next=newNode;
            newNode->pre=tail;
            tail=newNode;
        }else{
            cache_[key]->value=value;
        }
    }
};

版权声明:本文为weixin_42157432原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。