LRU的学习和LRU的模拟实现

Posted zhaocx111222333

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LRU的学习和LRU的模拟实现相关的知识,希望对你有一定的参考价值。

LRU是什么

LRU是Least Recently Used的缩写,意思是最近最少未使用,它是一种Cache替换算法。
广义上的Cache指的是位于速度相差较大的两种硬件之间, 用于协调两者数据传输速度差异的结构。
LRU在缺页中断中利用广泛,每次访问一个页,就会把页数放入一个数据结构,当数据结构满了就会淘汰掉最近最少未使用的页数,这个数据结构可以保证最新被访问的数据在最开始的位置。

图片来自网络。

组织结构

这样一个数据结构要保持高效实现O(1)的put和get,可以使用使用双向链表+哈希表来实现。是因为双向链表可以实现任意位置O(1)的插入和删除,使用哈希表是因为哈希表的增删查改也是O(1)

使用双向链表来作为存储结构存储具体的数据
list<pair<int, int>>利用存储键值对高效控制链表

利用哈希映射链表的迭代器实现链表的高效查找
哈希表的结构就是
unordered_map<int, list<pair<int, int>>::iterator>
Key就是用来记录插入的信息,而Value则是该节点对应链表的迭代器,可以通过Key高效的获取这个节点在链表的位置。

实现和详细注释

#include<iostream>
#include<list>
#include<unordered_map>
using namespace std;
class LRU {
public:
	LRU(int capacity) {
		_capacity = capacity;
	}
	//根据Key高效获取Value,这里也代表访问
	int get(int key) {
		auto hashit = _hashmap.find(key);
		if (hashit != _hashmap.end())		//存在就刷新位置并返回Value
		{
			auto listit = hashit->second;
			pair<int, int> kv = *listit;
			_list.erase(listit);
			_list.push_front(kv);
			_hashmap[key] = _list.begin();	//更新哈希表迭代器
			return kv.second;
		}
		else
		{
			return -1;
		}
	}
	void Push(int key, int value) {
		// 1.如果数据不存在则进行插入
		//(判断容量是否满)满了需要链表尾删,哈希表删除
		//不满就直接尾插
		// 2.如果数据存在则进行数据更新到链表头
		auto hashit = _hashmap.find(key);             //获取迭代器
		if (hashit == _hashmap.end())				  //数据不存在
		{
			if (_list.size() >= _capacity)
			{
				_hashmap.erase(_list.back().first);   //拿到链表尾的Key删除哈希表
				_list.pop_back();					  //链表尾删
			}
			_list.push_front(make_pair(key, value));
			_hashmap[key] = _list.begin();		      //获取迭代器并插入哈希表
		}
		else
		{
			auto listit = hashit->second;	          //拿到即将被删除的迭代器
			pair<int, int> kv = *listit;	          //不用make_pair,用旧的赋值改value也行
			kv.second = value;						  //修改迭代器的value
			_list.erase(listit);
			_list.push_front(kv);
			_hashmap[key] = _list.begin();
		}
	}

	
private:
	list<pair<int, int>> _list; 
	unordered_map<int, list<pair<int, int>>::iterator> _hashmap;
	size_t _capacity; //需要指定该结构的容量大小
};

以上是关于LRU的学习和LRU的模拟实现的主要内容,如果未能解决你的问题,请参考以下文章

LRU的学习和LRU的模拟实现

LRU和FIFO页面置换算法模拟实战

LRU算法实现

C#窗体模拟三种页面置换算法(OPT,FIFO,LRU)

#yyds干货盘点#使用线程安全型双向链表实现简单 LRU Cache 模拟

使用线程安全型双向链表实现简单 LRU Cache 模拟