LRU的C++实现

2 篇文章 0 订阅

(Least Recently Used Algorithm,LRU)

关于操作系统的内存管理,如何节省利用容量不大的内存最多的进程提供资源,一直是研究的重要方向。而内存的虚拟存储管理,是现在最通用,最成功的方式—— 在内存有限的情况下,扩展一部分外存作为虚拟内存,真正的内存只存储当前运行时所用得到信息。这无疑极大地扩充了内存的功能,极大地提高了计算机的并发度。虚拟页式存储管理,则是将进程所需空间划分为多个页面,内存中只存放当前所需页面,其余页面放入外存的管理方式。

然而,有利就有弊,虚拟页式存储管理减少了进程所需的内存空间,却也带来了运行时间变长这一缺点:进程运行过程中,不可避免地要把在外存中存放的一些信息和内存中已有的进行交换,由于外存的低速,这一步骤所花费的时间不可忽略。因而,采取尽量好的算法以减少读取外存的次数,也是相当有意义的事情。


LRU的实现有这样几种思路:

1、利用数组保存节点信息,另外节点信息除了内容还需要保存最近使用情况。

缺点:每次都需要遍历来找信息,同时也要遍历来删除(指LRU cache满了的情况)

2、链表来保存节点,双向链表,最末端为最新使用的,这样能减少删除时候的时间效率。


其实,还可以用一个哈希表来储存key值对应的节点的地址,这样就可以实现查找O(1),删除添加O(1)了。。。。。

以下为Leetcode上的LRU Cache,只用到链表。

题目要求有get,有set。

// 连表的形式来储存;
// 链表头为最早入表的节点,链表尾为最新的节点;
struct MyListNode{
	int key;
	int val;
	MyListNode* next;
	MyListNode* pre;
	MyListNode(int k, int v):key(k), val(v), next(NULL), pre(NULL){}
};
class LRUCache{
public:

	LRUCache(int capacity):cap(capacity), nodeNum(0), pHead(NULL), pTail(NULL) {
	}

	int get(int key) {
		if(pHead == NULL)
		{
			return -1;
		}
		MyListNode* pNode = pHead;
		while(pNode != NULL)
		{
			if(pNode->key == key)
			{
				int val = pNode->val;
				DeleteFromList(pNode);
				AddToList(pNode);
				return val;
			}
			pNode = pNode->next;
		}

		return -1;
	}

	void set(int key, int value) {
		MyListNode* pNode = pHead;
		while(pNode != NULL)
		{
			if(pNode->key == key)
			{
				pNode->val = value;
				DeleteFromList(pNode);
				AddToList(pNode);
				return;
			}
			pNode = pNode->next;
		}

		pNode = new MyListNode(key, value);
		AddToList(pNode);
	}
	void AddToList(MyListNode* pNode){
		if(nodeNum == cap)
		{
			MyListNode* pTmp = pHead;
			pHead = pHead->next;
			DeleteFromList(pTmp);
			delete pTmp;
			AddToList(pNode);
		}
		else
		{
			++nodeNum;
			if(nodeNum == 1)
			{
				pHead = pNode;
				pTail = pNode;
			}
			else
			{
				pTail->next = pNode;
				pNode->pre = pTail;
				pNode->next = NULL;
				pTail = pNode;
			}
		}
	}
	void DeleteFromList(MyListNode* pNode){
		MyListNode* pPre = pNode->pre;
		MyListNode* pNext = pNode->next;
		nodeNum--;
		if(pPre == NULL)
		{
			pHead = pNext;
		}
		else
		{
			pPre->next = pNext;
		}

		if(pNext == NULL)
		{
			pTail = pPre;
		}
		else
		{
			pNext->pre = pPre;
		}
	}
	MyListNode* pHead;
	MyListNode* pTail;
	int nodeNum;
	int cap;
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值