考研 OS 和计组的高频考点,当初只会纸上做题手算替换页面和 Cache,现在需要手撸代码了。由于要求 get() 和 put() 函数在 O(1) 的复杂度执行,采用 Hashmap 映射双链表结点的方法,写到一半迭代器的用法忘了还去搜了半天【cai
class LRUCache {
public:
LRUCache(int capacity) {
this->capacity = capacity;
this->front = new struct Node(0, 0);
this->end = new struct Node(0, 0);
this->front->next = end;
this->end->prev = front;
}
int get(int key) {
unordered_map<int, struct Node*>::iterator it = m.find(key);
if(it != m.end()) { //检查map中是否已经存在该key
struct Node* pNode = it->second;
//把这个结点拆下来放到list头部
teardownNode(pNode);
insertNodeAtFront(pNode);
return pNode->value; //返回该值
} else {
return -1;
}
}
void put(int key, int value) {
unordered_map<int, struct Node*>::iterator it = m.find(key);
if(it != m.end()) { //当key已经存在于map中时,只需修改对应链表结点的值
struct Node* pNode = it->second;
pNode->value = value;
//把这个结点拆下来放到list头部
teardownNode(pNode);
insertNodeAtFront(pNode);
} else { //否则(仅缓存满时)删去链尾最近最久未使用的结点并插入新值
if(m.size() >= capacity) {
struct Node* d = end->prev;
m.erase(d->key);
teardownNode(d);
delete d;
}
struct Node* pNode = new Node(key, value);
m[key] = pNode;
insertNodeAtFront(pNode);
}
}
private:
struct Node {
int key;
int value;
struct Node* prev;
struct Node* next;
Node(int key, int value) {
this->key = key;
this->value = value;
this->prev = NULL;
this->next = NULL;
}
};
int capacity = 0;
struct Node* front = NULL; //指向不存放数据的头结点
struct Node* end = NULL; //指向不存放数据的末尾结点
unordered_map<int, struct Node*> m;
void insertNodeAtFront(struct Node* pNode) {
pNode->next = front->next;
front->next->prev = pNode;
front->next = pNode;
pNode->prev = front;
}
void teardownNode(struct Node* pNode) {
pNode->prev->next = pNode->next;
pNode->next->prev = pNode->prev;
}
};
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache* obj = new LRUCache(capacity);
* int param_1 = obj->get(key);
* obj->put(key,value);
*/