LRU算法(c++)

least recently used(最近最少使用算法),是一种内存数据淘汰策略,使用常见是当内存不足时,需要淘汰最近最少使用的数据。


概括来讲,即,“不断访问,不断缓存,放不下了,得删一个。”

实现方法:hash+双向链表

图片非原创:五分钟学算法 公众号

hash以键找指针,链表节点存键与值

1)读一条数据,hash知道已经在不在,在,挪到链表最后(双向链表才能O(1)),不在,插到链表最后。

2)满了,试图删一条数据,删头元素,更新hash(链表里存键、值二者)

typedef int KEYTYPE;
typedef int VALUETYPE;
class CDoubleListNode {
public:
	KEYTYPE key;
	VALUETYPE value;
	CDoubleListNode * pre;
	CDoubleListNode * nxt;
};

class CLRUpool {
	int capacity;
	int current;
	std::map<KEYTYPE, CDoubleListNode *> hashtable;
	CDoubleListNode * pheadNode;
	CDoubleListNode * ptailNode;

public:

	CLRUpool(int _c):capacity(_c), current(0)
	{
		pheadNode = new CDoubleListNode;
		ptailNode = new CDoubleListNode;
		pheadNode->pre = ptailNode->nxt = NULL;
		pheadNode->nxt = ptailNode;
		ptailNode->pre = pheadNode;
	}

	void find(KEYTYPE key)
	{
		std::map<KEYTYPE, CDoubleListNode *>::iterator it; //第二个双冒号啥意思
		it = hashtable.find(key);

		if (it == hashtable.end()) 
		{
			std::cout << "**未查到信息" << key << ",请输入其value:**" << std::endl;
			int value;
			std::cin >> value;
			add(key, value);
		}
		else
		{
			std::cout << "**查到" << key << "的value是" << (it->second)->value << "**" << std::endl;
			// *it指向的节点移到最后
			CDoubleListNode * tmp = it->second;
			tmp->pre->nxt = tmp->nxt;
			tmp->nxt = tmp->pre;
			tmp->pre = ptailNode->pre;
			tmp->nxt = ptailNode;
			ptailNode->pre->nxt = tmp;
			ptailNode->pre = tmp;
		}
		return;
	}

	void add(KEYTYPE key, VALUETYPE value)
	{
		if (current == capacity)
		{
			// 删头
			std::cout << "**缓存已满,删除" << pheadNode->nxt->key << std::endl;

			CDoubleListNode * tmp = pheadNode->nxt;
			hashtable.erase(tmp->key);
			pheadNode->nxt = tmp->nxt;
			tmp->nxt->pre = pheadNode;
			delete tmp;
		}

		// 添加
		std::cout << "**已添加" << key << '-' << value << "**" << std::endl;
		
		CDoubleListNode * tmp = new CDoubleListNode;
		tmp->pre = ptailNode->pre;
		tmp->nxt = ptailNode;
		tmp->key = key;
		tmp->value = value;

		ptailNode->pre->nxt = tmp;
		ptailNode->pre = tmp;

		hashtable[key] = tmp;
		current++;
	}

	~CLRUpool() {
		CDoubleListNode * p = pheadNode->nxt;
		for (; p != NULL; p = p->nxt)
		{
			delete p->pre;
		}
		delete ptailNode;
	}
};

测试

int main(void)
{
	CLRUpool mypool(3);

	mypool.find(1106);

	mypool.find(1102);

	mypool.find(1106);

	mypool.find(1101);

	mypool.find(1104);

	return 0;
}

 结果

猜你喜欢

转载自blog.csdn.net/weixin_45339670/article/details/131154497
今日推荐