LRU缓存淘汰

模板代码实现

#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)标记界限,这样在添加节点和删除节点的时候就不需要检查相邻的节点是否存在。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值