C++ LRU 不同的实现方式

#include <list>
#include <unordered_map>
#include <cassert>
#include <iostream>

using namespace std;

class LRUCache {

	struct Element {
		int key;
		int value;
		Element(int k, int v) : key(k), value(v) {  }
	};

public:

	LRUCache(int capacity):m_capacity(capacity){}

public:
	int get(int key) {
		if (m_unordmap.find(key) == m_unordmap.end())
			return -1;
		else {
			//更新链表(where,object,object ->pos)
			m_list.splice(m_list.begin(), m_list, m_unordmap[key]);
			//更新map
			m_unordmap[key] = m_list.begin();
			return m_unordmap[key]->value;
		}
	}
	void put(int key, int value) {
		assert(m_capacity > 0);
		//已经存在的情况
		if (m_unordmap.find(key)!=m_unordmap.end()) {
			m_list.splice(m_list.begin(), m_list, m_unordmap[key]);
			m_unordmap[key] = m_list.begin();
			m_list.begin()->value = value;
		}
		//缓存已经满的情况
		else if (m_list.size()==m_capacity) {
			m_unordmap.erase(m_list.back().key);
			m_list.pop_back();
			m_list.push_front(Element(key, value));
			m_unordmap[key] = m_list.begin();
		}
		//未满的情况
		else {
			m_list.push_front(Element(key, value));
			m_unordmap[key] = m_list.begin();
		}
	}
	void print() {
		auto it = m_list.begin();
		while (it != m_list.end()) {

			cout << "(" <<it->key << ":" << it->value << ") ";
			++it;
		}
		cout << endl;
	}
	
private:
	list<Element> m_list;
	unordered_map<int, list<Element>::iterator>m_unordmap;
	int m_capacity;
};

class LRUCacheEx {

public:
	struct LinkNode {
		int key;
		int value;
		LinkNode*pre;
		LinkNode*next;
		LinkNode(int k,int v):key(k),value(v),pre(nullptr),next(nullptr){}
	};
	LRUCacheEx(int n) :max_cnt(n), cnt(0) {

		head = new LinkNode(-1, -1);
		tail = new LinkNode(-1, -1);
		head->next = tail;
		tail->pre = head;
	}
	//更新位置到head处
	void update(LinkNode*p) {

		if (p->pre == head)
			return;

		//先断开
		p->pre->next = p->next;
		p->next->pre = p->pre;
		//重新连接
		p->next = head->next;
		head->next->pre = p;

		p->pre = head;
		head->next = p;

	}
	void print() {
		LinkNode*p = head->next;
		while (p != tail) {
			cout << "(" << p->key << ":" << p->value<<") ";
			p = p->next;
		}
		cout << endl;
	}
	int get(int k) {
		auto it = m_map.find(k);
		//不存在
		if (it == m_map.end())
			return -1;
		// 更新位置
		LinkNode*p = it->second;
		update(p);
		return p->value;
	}
	void put(int k, int v) {

		if (max_cnt <= 0)
			return;

		unordered_map<int, LinkNode*>::iterator it = m_map.find(k);
		//存在键值
		if (it != m_map.end()) {
			LinkNode*p = it->second;
			p->value = v;
			update(p);
		}
		//存储已经满了
		else if (cnt == max_cnt) {
			//断开并删除
			LinkNode*p = tail->pre;

			tail->pre = p->pre;
			p->pre->next = tail;

			m_map.erase(p->key);
			delete p;
			//生成新的
			p = new LinkNode(k, v);
			m_map[k] = p;
			//插入到head之后
			p->next = head->next;
			head->next->pre = p;

			p->pre = head;
			head->next = p;
		}
		//未满
		else {
			LinkNode *p = new LinkNode(k, v);
			m_map[k] = p;
			//插入到head之后
			p->next = head->next;
			head->next->pre = p;

			p->pre = head;
			head->next = p;
			cnt++;
		}
	}
private:
	int max_cnt;//最大容量
	int cnt;//计数器
	unordered_map<int, LinkNode*>m_map;
	LinkNode*head;
	LinkNode*tail;
};
int main() {

	LRUCache lr(3);
	lr.put(1, 1);
	lr.put(2, 2);
	lr.put(3, 3);
	lr.print();
	lr.put(4, 4);
	lr.get(2);
	lr.print();

	LRUCacheEx lrex(3);
	lrex.put(1, 1);
	lrex.put(2, 2);
	lrex.put(3, 3);
	lrex.print();
	lrex.put(4, 4);
	lrex.get(2);
	lrex.print();

	return 0;
}

参考 一
参考 二

发布了40 篇原创文章 · 获赞 6 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/mrbaolong/article/details/104389745