LRUCache
Leetcode上的LRUCache缓存机制,实现get和put时时间复杂度O(1).
//
#include<iostream>
#include<map>
using namespace std;
//------------------------leetcode LRUCache----------------------------//
// 双端链表设置优先级(最近使用..最近不经常使用),hash_map可以在O(1)找到对应节点
// put(key,val),先检查是否存在缓存是否存在key,若存在直接更新它的val;并把该
//节点挂到缓存最近使用(链表尾部);若不存在该key,判断缓存是否满了,满了则移除
//最近不经常用(链表头部),插入到尾部,同时插入map中,缓存不满直接插入。
class node {
public:
int key;
int val;
node* last;
node* next;
node(int k, int v) {
key = k;
val = v;
last = NULL;
next = NULL;
}
};
class doubleQueue {
public:
node* head;
node* tail;
doubleQueue() {
this->head = NULL;
this->tail = NULL;
}
void addntotail(node* addn) { //加入刚操作过的节点到尾部
if (addn == NULL)
return;
if (this->tail == NULL)
{
this->head = addn;
this->tail = addn;
}
else {
this->tail->next = addn;
addn->next = NULL;
addn->last = this->tail;
this->tail = addn;
}
}
node* removeNode(node* rmvnode) { //移除某个节点 并返回该节点
if (this->head == NULL)
return NULL;
if (this->head == this->tail) { //只有一个节点
this->head = NULL;
this->tail = NULL;
return rmvnode;
}
if (rmvnode == this->tail)
{
this->tail = this->tail->last;
rmvnode->last = NULL;
return rmvnode;
}
if (rmvnode == this->head) {
node* nextHead = rmvnode->next;
nextHead->last = NULL;
rmvnode->next = NULL;
this->head = nextHead;
return rmvnode;
}
else {
node* lastnode = rmvnode->last;
node* nextnode = rmvnode->next;
lastnode->next = nextnode;
nextnode->last = lastnode;
rmvnode->last = NULL;
rmvnode->next = NULL;
return rmvnode;
}
}
};
class LRUCache {
private:
map<int, node*> mymap;
doubleQueue myqueue;
int capacity;
int size;
public:
LRUCache(int num) :capacity(num), size(0) {}
void put(int key, int val) {
if (mymap.find(key) == mymap.end()) { //插入元素不存在的
if (size > capacity) //目前缓存已满,先删除头,再插入
{
node* outnode = myqueue.removeNode(myqueue.head);
mymap.erase(outnode->key);
node* newnode = new node(key, val);
this->mymap.insert(make_pair(key, newnode));
myqueue.addntotail(newnode);
}
else { //缓存未满
node* newnode = new node(key, val);
this->mymap.insert(make_pair(key, newnode));
myqueue.addntotail(newnode);
size++;
}
}
else //插入已经存在的 直接修改值即可
{
auto it = mymap.find(key);
it->second->val = val; //map中改val 通过节点改的 因此map不需要操作
node* rmN = myqueue.removeNode(it->second);
myqueue.addntotail(rmN);
}
}
int get(int key) {
int rets;
if (mymap.find(key) == mymap.end())
return -1;
else
rets = mymap.find(key)->second->val;
node* rmvNode = myqueue.removeNode(mymap.find(key)->second);
myqueue.addntotail(rmvNode);
return rets;
}
};
//测试
int main()
{
LRUCache mycache(1);
mycache.put(2, 1);
cout << mycache.get(2) << endl;
mycache.put(3, 2);
return 0;
}