C++实现LRU(最久未使用)缓存算法

LRU缓存算法也叫LRU页面置换算法,是一种经典常用的页面置换算法。

LRU的典型实现是hash map + doubly linked list,双向链表用于存储数据结点,并且它是按照结点最近被使用的时间来存储的。如果一个结点被访问了,我们相信它在接下来的一段时间被访问的概率要大于其它结点。于是,我们把它放到双向链表的头部。当我们往双向链表里插入一个结点,我们也有可能很快就会使用到它,同样把它插入到头部。我们使用这种方式不断地调整着双向链表,链表尾部的结点自然也就是最近一段时间,最久没有使用到的结点。那么,当我们的Cache满了,需要替换掉的就是双向链表中最后的那个结点。

哈希表的作用是可以让我们在O(1)的时间找到想要访问的结点,或者返回未找到。

#include<iostream>
#include <list>
#include <unordered_map>
using namespace std;
template<typename K, typename T>
struct Node {
	K key;
	T value;
	Node(K k, T v) :key(k), value(v) {}
};
template<typename K, typename T>
class LRUCache {
public:
	LRUCache(int c) :capacity(c) {}
	T get(K key) {
		assert(cacheMap.find(key) != cacheMap.end());

		//将key移到第一个,并更新cacheMap
		cacheList.splice(cacheList.begin(), cacheList, cacheMap[key]);
		cacheMap[key] = cacheList.begin();
		return cacheMap[key]->value;
	}
	void set(K key, T value) {
		if (cacheMap.find(key) == cacheMap.end()) {
			//淘汰最后一个,然后将其加到第一个位置
			if (cacheList.size() == capacity) {
				cacheMap.erase(cacheList.back().key);
				cacheList.pop_back();
			}
			cacheList.push_front(Node<K, T>(key, value));
			cacheMap[key] = cacheList.begin();
		}
		else {
			//更新节点的值,并将其加到第一个位置
			cacheMap[key]->value = value;
			cacheList.splice(cacheList.begin(), cacheList, cacheMap[key]);
			cacheMap[key] = cacheList.begin();
		}
	}
private:
	int capacity;
	list<Node<K, T> > cacheList;
	//由于iterator依赖具体的map,而map中包含了一个模板,在没有实例化的时候不能确定其类型。
	//此时加一个typename前缀即可
	unordered_map<K, typename list<Node<K, T> >::iterator> cacheMap;
};
int main()
{
	int N = 10;
	LRUCache<int, int> lc(N);
	for (int i = 0; i < N; ++i) {
		lc.set(i, i);
	}
	cout << "at the beginning: " << endl;
	for (int i = 0; i < N; ++i)
		cout << lc.get(i) << " ";
	cout << endl;
	cout << "after inserting: " << endl;
	lc.set(N + 1, N + 1);
	for (int i = 1; i < N; ++i)
		cout << lc.get(i) << " ";
	cout << lc.get(N + 1);
	cout << endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值