LRU algorithm (c++)

The least recently used (least recently used algorithm) is a memory data elimination strategy. The common use is that when the memory is insufficient, the least recently used data needs to be eliminated.


In a nutshell, that is, "keep accessing, keep caching, if you can't put it down, you have to delete one."

Implementation method: hash+doubly linked list

The picture is not original: five minutes to learn the algorithm official account

Hash finds pointers with keys, and linked list nodes store keys and values

1) Read a piece of data, and the hash knows whether it is already there. If it is, move it to the end of the linked list (a doubly linked list can only be O(1)), if it is not, insert it to the end of the linked list.

2) When it is full, try to delete a piece of data, delete the header element, and update the hash (both key and value are stored in the linked list)

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;
	}
};

test

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

	mypool.find(1106);

	mypool.find(1102);

	mypool.find(1106);

	mypool.find(1101);

	mypool.find(1104);

	return 0;
}

 result

Guess you like

Origin blog.csdn.net/weixin_45339670/article/details/131154497