LRU
最近最久未使用的置换算法(LRU):最近最久未使用(LRU)的置换算法的基本思路是,发生缺页时,选择最长时间没有被访问的页面进行置换,也就是说,该算法假设已经很久没有使用的页面很有可能在未来较长的⼀段时间内仍然不会被使用。
图解:

最后一步因为1号页面是「过去时间段里最久没有被访问的」, 所以把1号页面换出到磁盘,然后把3号页面换入到内存。
代码简易实现
#include<iostream>
#include<list>
#include<map>
using namespace std;
struct MyLRUnode
{
int key;//形成key+value结构
int value;
MyLRUnode(int a, int b) :key(a), value(b){}
};
class LRUCache
{
public:
LRUCache(int size)
{
Lru_capacity = size;
}
int get(int key)
{
if (mymap.find(key) != mymap.end())
{
mylist.splice(mylist.begin(), mylist, mymap[key]);//则将mylist链表上找到的的iterator位置的元素重新链接到mylist.begin()位置上
mymap[key] = mylist.begin();//然后将map映射表中 键为key的页面映射位置重置一下
return mymap[key]->value;//最后返回将key对应的value返回
}
else
{
return -1;
}
}
void put(int key,int value)
{
if (mymap.find(key) == mymap.end())//key值不在页中
{
if (mylist.size() == Lru_capacity)//不在页中并且页还满了
{
mymap.erase(mylist.back().key);//将list尾部节点对应的key和其页映射关系删除
mylist.pop_back();//将list尾部节点删除
}
MyLRUnode pnewnode(key, value);//创建新页
mylist.push_front(pnewnode);//插入页链表中
mymap[key] = mylist.begin();//key对应页面关系存入map
}
else//key值在页中
{
mymap[key]->value = value;//更新key对应的value值
mylist.splice(mylist.begin(), mylist, mymap[key]);//将mylist链表上找到的的iterator位置的元素重新链接到mylist.begin()位置上
mymap[key] = mylist.begin();//然后将map映射表中 键为key的页面映射位置重置一下
}
}
void show_list()
{
list<MyLRUnode>::iterator it = mylist.begin();
for (; it != mylist.end();)
{
cout << it->key << ":" << it->value << endl;
it++;
}
cout << endl;
}
void show_map()
{
map<int, list<MyLRUnode>::iterator>::iterator it = mymap.begin();
while (it != mymap.end())
{
cout << it->first << ":" << (it->second)->value << endl;
it++;
}
cout << endl;
}
private:
int Lru_capacity;
list<MyLRUnode> mylist;
map<int, list<MyLRUnode>::iterator> mymap;//用来通过key键值 直接找到对应的双向链表节点
};
小结:使用双向链表list和map实现LRU算法。双向链表用于保存key-value,队头的元素表示最近一次被访问的元素,队尾的元素表示最近最久未使用的元素,map提供key到key对应节点在双向链表中的位置的映射。
LRU(最近最久未使用)是一种页面置换算法,当发生缺页时,会选择最长时间未被访问的页面进行置换。文章通过图解和C++代码实现,解释了LRU的工作原理,使用双向链表和map来维护数据结构。

6251

被折叠的 条评论
为什么被折叠?



