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
}