LRU缓存C++实现

LRU是一种缓存淘汰算法,淘汰原则是将最近不常访问的数据删除。
在这里插入图片描述
程序使用双向链表+unordered_map,unordered_map实现O(1)的查找效率。用类LRU对双向链表和unordered_map进行封装,对外提供构造函数,插入函数Insert(int key, int value),获取值函数Getvalue(int key),获取大小函数Getsize(),获取容量函数Getcapacity()。

代码如下:

#include<iostream>
#include<unordered_map>  
using namespace std;

//节点结构体
struct node{
	int m_key;
	int m_value;
	node *pre;
	node *next;
	node(int key, int value) :
		m_key(key),
		m_value(value),
		pre(nullptr),
		next(nullptr){}
};

//LRU缓存实现类,双向链表
class LRU{
public:
	LRU(int size);
	~LRU();
	void Insert(int key, int value);
	int Getvalue(int key);
	int Getsize();
	int Getcapacity();
private:
	int m_capacity;
	node *phead;
	node *ptail;
	unordered_map<int, node*> mp;
	void Remove(node *pnode);
	void Sethead(node *pnode);
};

LRU::LRU(int size){
	m_capacity = size;
	phead = nullptr;
	ptail = nullptr;
}

LRU::~LRU(){
	auto it = mp.begin();
	//删除mp
	while (it != mp.end()){
		delete it->second;
		it->second = nullptr;
		mp.erase(it++);    //关联容器删除后迭代器失效,所以使用删除之前的迭代器定位下一个元素
	}
}

//移除
void LRU::Remove(node *pnode){
	if (pnode == phead){
		phead = phead->next;
		if (phead != nullptr){           //防止只有一个节点Remove出错
			phead->pre = nullptr;
		}
	}
	else if (pnode == ptail){
		ptail = ptail->pre;
		if (ptail != nullptr){
			ptail->next = nullptr;
		}
	}
	else{
		pnode->pre->next = pnode->next;
		pnode->next->pre = pnode->pre;
	}
}

//节点放在头部
void LRU::Sethead(node *pnode){
	pnode->next = phead;
	pnode->pre = nullptr;
	if (phead != nullptr){
		phead->pre = pnode;
	}
	phead = pnode;
	if (ptail == nullptr){
		ptail = pnode;
	}
}

//插入数据
void LRU::Insert(int key, int value){
	auto it = mp.find(key);
	if (it == mp.end()){
		node *pnode = new node(key, value);
		Sethead(pnode);
		mp[key] = pnode;
	}
	else{
		it->second->m_value = value;
		Remove(it->second);
		Sethead(it->second);
	}
	if (mp.size() > m_capacity){
		auto it = mp.find(ptail->m_key);
		Remove(it->second);
		delete it->second;
		it->second = nullptr;
		mp.erase(it);
	}
}

//获取数据
int LRU::Getvalue(int key){
	auto it = mp.find(key);
	if (it != mp.end()){
		auto no = it->second;
		Remove(no);
		Sethead(no);
		return it->second->m_value;
	}
	else{
		return -1;
	}
}

int LRU::Getsize(){
	return mp.size();
}

int LRU::Getcapacity(){
	return m_capacity;
}

void main(){
	LRU mylru(3);
	mylru.Insert(1, 10);
	mylru.Insert(3, 20);
	mylru.Insert(5, 30);
	cout << mylru.Getvalue(1) << endl;
	mylru.Insert(7, 40);
	cout << mylru.Getvalue(1) << endl;
	cout << mylru.Getvalue(3) << endl;
	cout << mylru.Getvalue(5) << endl;
	cout << mylru.Getvalue(7) << endl;
	cout << mylru.Getsize() << endl
}

测试结果:

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值