1. Hash+双向链表
1.1 Java实现:
public class LRUCache {
class DLinkedNode {
int key;
int value;
DLinkedNode pre;
DLinkedNode next;
DLinkedNode() {
this.key = 0;
this.value = 0;
pre = null;
next = null;
}
DLinkedNode(int key, int value) {
this.key = key;
this.value = value;
pre = null;
next = null;
}
}
private ConcurrentMap<Integer, DLinkedNode> cache = new ConcurrentHashMap<Integer, DLinkedNode>();
private int size;
private int capacity;
private DLinkedNode head, tail;
public LRUCache(int capacity) {
this.size = 0;
this.capacity = capacity;
head = new DLinkedNode();
head.pre = null;
tail = new DLinkedNode();
tail.next = null;
head.next = tail;
tail.pre = head;
}
public int get(String key) {
DLinkedNode node = cache.get(key);
if (node == null) {
return -1; // should raise exception here.
}
moveToHead(node);
return node.value;
}
public void put(int key, int value) {
if (cache.containsKey(key)) {
DLinkedNode node = cache.get(key);
node.value = value;
moveToHead(node);
} else {
DLinkedNode node = new DLinkedNode(key, value);
cache.put(key, node);
addToHead(node);
++size;
if (size > capacity) {
DLinkedNode tail = removeTail();
cache.remove(tail.key);
size--;
}
}
}
private void moveToHead(DLinkedNode node) {
removeNode(node);
addToHead(node);
}
private void addToHead(DLinkedNode node) {
node.pre = head;
node.next = head.next;
head.next.pre = node;
head.next = node;
}
private void removeNode(DLinkedNode node) {
DLinkedNode pre = node.pre;
DLinkedNode next = node.next;
pre.next = next;
next.pre = pre;
}
private DLinkedNode removeTail() {
DLinkedNode node = tail.pre;
removeNode(node);
return node;
}
}
1.2. C++实现
struct DLinkedListNode {
DLinkedListNode *next, *prev;
int key, val;
DLinkedListNode() : key(0), val(0), next(nullptr), prev(nullptr) {}
DLinkedListNode(int key, int val) : key(key), val(val), next(nullptr), prev(nullptr) {}
};
class LRUCache {
private:
unordered_map<int, DLinkedListNode *> cache;
DLinkedListNode *head, *tail;
int size, capacity;
public:
LRUCache(int capacity) : capacity(capacity), size(0) {
head = new DLinkedListNode();
tail = new DLinkedListNode();
head->next = tail;
tail->prev = head;
}
int get(int key) {
if (!cache.count(key)) {
return -1;
}
DLinkedListNode *node = cache[key];
moveToHead(node);
return node->val;
}
void put(int key, int value) {
if (!cache.count(key)) {
DLinkedListNode *node = new DLinkedListNode(key, value);
cache[key] = node;
++size;
addToHead(node);
if (size > capacity) {
DLinkedListNode *node = removeTail();
cache.erase(node->key);
delete node;
size -= 1;
}
} else {
DLinkedListNode *node = cache[key];
node->val = value;
moveToHead(node);
}
}
void moveToHead(DLinkedListNode *node) {
removeNode(node);
addToHead(node);
}
void removeNode(DLinkedListNode *node) {
//1-->2-->3
node->prev->next = node->next;
node->next->prev = node->prev;
}
void addToHead(DLinkedListNode *node) {
node->prev = head;
node->next = head->next;
// head->next->prev = node;
node->next->prev = node;// try one time;
head->next = node;
}
DLinkedListNode *removeTail() {
DLinkedListNode *node = tail->prev;
removeNode(node);
return node;
}
};