模板代码实现
#pragma once
#include<iostream>
#include<unordered_map>
template<typename Node>
struct DListNode
{
int key_ = 0;
Node* value_ = nullptr;
DListNode* pre_ = nullptr;
DListNode* next_ = nullptr;
DListNode(){}
DListNode(int key, Node* val):key_(key),value_(val),pre_(nullptr),next_(nullptr){}
};
template<typename Node>
class LRUCache
{
public:
LRUCache(int cap);
int Get(int key);
void Put(int key, Node* val);
private:
void addToHead(DListNode<Node>* node);
void removeNode(DListNode<Node>* node);
void moveToHead(DListNode<Node>* node);
DListNode<Node>* removeTail();
private:
std::unordered_map<int, DListNode<Node>*> cache_;
DListNode<Node>* head_ = nullptr;
DListNode<Node>* tail_ = nullptr;
int size_ = 0;
int cap_ = 0;
};
template<typename Node>
LRUCache<Node>::LRUCache(int cap) :cap_(cap)
{
this->head_ = new DListNode<Node>();
this->tail_ = new DListNode<Node>();
this->head_->next_ = this->tail_;
this->tail_->pre_ = this->head_;
}
template<typename Node>
int LRUCache<Node>::Get(int key)
{
if (!this->cache_.count(key))
{
return -1;
}
DListNode* node = this->cache_[key];
this->moveToHead(node);
return node->value_;
}
template<typename Node>
void LRUCache<Node>::Put(int key, Node* val)
{
if (!this->cache_.count(key))
{
DListNode<Node>* node = new DListNode<Node>(key, val);
this->cache_[key] = node;
this->addToHead(node);
++this->size_;
if (this->size_ > this->cap_)
{
DListNode<Node>* removeNode = this->removeTail();
this->cache_.erase(removeNode->key_);
delete removeNode;
--this->size_;
}
}
else
{
DListNode<Node>* node = this->cache_[key];
node->value_ = val;
this->moveToHead(node);
}
}
template<typename Node>
void LRUCache<Node>::addToHead(DListNode<Node>* node)
{
node->pre_ = this->head_;
node->next_ = this->head_->next_;
this->head_->next_->pre_ = node;
this->head_->next_ = node;
}
template<typename Node>
void LRUCache<Node>::removeNode(DListNode<Node>* node)
{
node->pre_->next_ = node->next_;
node->next_->pre_ = node->pre_;
}
template<typename Node>
void LRUCache<Node>::moveToHead(DListNode<Node>* node)
{
this->removeNode(node);
this->addToHead(node);
}
template<typename Node>
DListNode<Node>* LRUCache<Node>::removeTail()
{
DListNode<Node>* node = this->tail_->pre_;
this->removeNode(node);
return node;
}
小技巧
在双向链表的实现中,使用一个伪头部(dummy head)和伪尾部(dummy tail)标记界限,这样在添加节点和删除节点的时候就不需要检查相邻的节点是否存在。