LRUCache(最近最久未用)源码实现
用链表加哈希表(哈希表key记录key,value记录key前驱结点的指针)
class Node
{
public:
Node(int k = -1, int v = -1, Node* n = NULL) :key(k), value(v), next(n) {};
int key;
int value;
Node* next;
};
class LRUCache
{
public:
LRUCache(int capacity) {
size = capacity;
// 每个链表类型先来一个假头部,操作方便(比如在链表头部删除插入的时候不用特判)
dummy = new Node();
tail = dummy;
}
int get(int key) {
// 如果这个key存在,通过哈希表查找到他的前驱节点,最后把这个节点移动到链表尾部
if (key_to_prev.find(key) != key_to_prev.end()) {
Node* prev = key_to_prev[key];
int val = prev->next->value;
move_to_tail(key);
return val;
}
else {
return -1;
}
}
void put(int key, int value) {
// 如果找到这个key,修改他的value,把它移动到链表尾部
if (key_to_prev.find(key) != key_to_prev.end()) {
Node* prev = key_to_prev[key];
Node* current = prev->next;
current->value = value;
move_to_tail(key);
}
else {
// 如果没有找到这个key,并且有空余的位置,将他加入链表尾部
if (size != 0) {
size--;
Node* p = new Node(key, value);
key_to_prev[key] = tail;
tail->next = p;
tail = p;
}
// 如果没有找到这个key并且位置已经满了,修改头结点key和value,将他移动到链表尾部省去new和deleteNode
else {
key_to_prev.erase(dummy->next->key);
dummy->next->key = key;
dummy->next->value = value;
key_to_prev[key] = dummy;
move_to_tail(key);
}
}
}
// 将当前key所在节点移动到链表尾部
void move_to_tail(int key) {
Node* prev = key_to_prev[key];
Node* current = prev->next;
// 如果当前节点current已经在链表尾部就不用操作了,否则
if (current->next != NULL) {
key_to_prev[current->next->key] = prev;
prev->next = current->next;
current->next = NULL;
key_to_prev[key] = tail;
tail->next = current;
tail = current;
}
}
int size;
Node* dummy; // 链表头部
Node* tail; // 链表尾部
unordered_map<int, Node*> key_to_prev;
};