基于双链表的实现
需要维护的是两个:
- 负责达到快速查找作用的
unodered_map<key, DLinkList*>
,key存放的是键,值存放的是这个键在cache里面的地址,这样查找的时候就能快速找到键并通过值访问地址获取其val了 - 负责记录具体信息和使用记录的cache多个
DlinkList
链接起来的链表。推荐创建一个虚拟头和尾结点,方便管理,越靠近头就越是最近用过,越靠近链表尾部,就代表越久未使用过。
struct DLinkedNode{ //使用记录的双向链表int key_, value_;DLinkedNode* pre_;DLinkedNode* next_;DLinkedNode():key_(0),value_(0), pre_(nullptr), next_(nullptr){}DLinkedNode(int key, int value):key_(key), value_(value),pre_(nullptr),next_(nullptr){}
};class LRUCache {
private:unordered_map<int,DLinkedNode*> cache; //缓存,只是为了更快速的找到DLinkedNode* head;DLinkedNode* tail;size_t size;size_t cap;public:LRUCache(int capacity): cap(capacity),size(0){head = new DLinkedNode();tail = new DLinkedNode();head->next_ = tail;tail->pre_ = head;}int get(int key) {if(!cache.count(key)) return -1;DLinkedNode* node = cache[key];moveToHead(node);return temp->value_;}void put(int key, int value) {if(!cache.count(key)){ //cache里没有就加结点,cache只是为了快速找到DLinkedNode* node = new DLinkedNode(key,value);addToHead(node);cache[key] = node;size++;if(size > cap){DLinkedNode* removed = removeTail();cache.erase(removed->key_);delete removed;size--;}}else{ //加入的存在了,把它挪到使用记录双向链表的第一个DLinkedNode* node = cache[key];temp->value_ = value;moveToHead(node);}}//一些操作双向链表记录的操作方法void addToHead(DLinkedNode* node){node->pre_ = head;node->next_ = head->next_;head->next_->pre_ = node;head->next_ = node;}void removeNode(DLinkedNode* node){node->pre_->next_ = node->next_;node->next_->pre_ = node->pre_;}void moveToHead(DLinkedNode* node){removeNode(node);addToHead(node);}DLinkedNode* removeTail(){DLinkedNode* node = tail->pre_;removeNode(node);return node;}};/*** 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);*/