1. 程式人生 > >C++實現LRU(最久未使用)快取演算法

C++實現LRU(最久未使用)快取演算法

LRU快取演算法也叫LRU頁面置換演算法,是一種經典常用的頁面置換演算法,本文將用C++實現一個LRU演算法。

LRU演算法實現並不難,但是要高效地實現卻是有難度的,要想高效實現其中的插入、刪除、查詢,第一想法就是紅黑樹,但是紅黑樹也是一種折中的辦法。插入、刪除效率最高當屬連結串列,查詢效率當屬hash。所以,這裡我們就將連結串列和hash結合起來,利用空間換時間的思想,實現LRU演算法。

LRU具體概念就不列出了,本文的目的是進一步瞭解LRU演算法和學習高效的程式設計方法。

程式碼如下:

class LRUCache{
private:
	//LRU資料結構
	struct Node{
		int key;
		int value;
		Node(int k,int v):key(k),value(v){}
	};
public:
	LRUCache(int c):capacity(c) {}
	
	int get(int key){
		if (cacheMap.find(key) == cacheMap.end())
			return -1; //這裡產生缺頁中斷,根據頁表將頁面調入記憶體,然後set(key, value)
		//將key移到第一個,並更新cacheMap 
		cacheList.splice(cacheList.begin(),cacheList,cacheMap[key]);
		cacheMap[key] = cacheList.begin();
		return cacheMap[key]->value;
	}
	void set(int key, int value){
		if (cacheMap.find(key) == cacheMap.end())
		{
			//淘汰最後一個,然後將其加到第一個位置
			if (cacheList.size() == capacity)
			{
				cacheMap.erase(cacheList.back().key);
				cacheList.pop_back();
			}
			cacheList.push_front(Node(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> cacheList;
	unordered_map<int, list<Node>::iterator> cacheMap;
};

實際演算法並不難,但是高效解決問題的思想是值得學習的。也讓我們更加了解LRU快取演算法了。