#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;
}
C++ LRU 不同的实现方式
最新推荐文章于 2024-03-09 16:10:44 发布