LRU算法初识(小白的第一篇优快云)
1、废话不多说直接上我的垃圾屎山
public class ShouLuLru {
class Node {
private int key;
private int value;
private Node pre;
private Node next;
public Node(int key, int value) {
this.key = key;
this.value = value;
}
}
private int cap;
private Node tail;
private Node head;
private Map<Integer, Node> map;
public ShouLuLru(int cap) {
this.cap = cap;
tail = new Node(-1, -1);
head = new Node(-1, -1);
map = new HashMap<>(cap);
tail.pre = head;
head.next = tail;
}
public Integer get(int key) {
if (map.containsKey(key)) {
Node node = map.get(key);
node.pre.next = node.next;
node.next.pre = node.pre;
Node oldHead = head.next;
oldHead.pre = node;
node.next = oldHead;
head.next = node;
node.pre = head;
return map.get(key).value;
} else {
return -1;
}
}
public void put(int key,int value){
if(map.containsKey(key)){
Node node = map.get(key);
node.value = value;
node.pre.next = node.next;
node.next.pre = node.pre;
Node oldHead = head.next;
oldHead.pre = node;
node.next = oldHead;
head.next = node;
node.pre = head;
map.put(key,node);
}else{
if(map.size() == cap){
Node oldTail = tail.pre;
tail.pre = oldTail.pre;
oldTail.pre.next = tail;
map.remove(oldTail.key);
}
Node needNode = new Node(key, value);
Node oldHead = head.next;
oldHead.pre = needNode;
needNode.next = oldHead;
head.next = needNode;
needNode.pre = head;
map.put(key,needNode);
}
}
public static void main(String[] args) {
ShouLuLru shouLuLru = new ShouLuLru(2);
shouLuLru.get(2);
shouLuLru.put(2, 1);
shouLuLru.put(2, 2);
shouLuLru.get(2);
shouLuLru.put(1, 1);
shouLuLru.put(4, 1);
shouLuLru.get(2);
}
}
2、LRU自我理解
lru(least recently used)是最近最少使用,是一种缓存淘汰机制,一般在redis的缓存淘汰策略中出现,面试的时候在考redis中出现。
3、算法设计
既然要最近最少使用,那么这个结构一定是有序的,不然你没办法删除特定的节点,而且算法要求在0(1)时间范围内完成,那么我首先能想到的就是hash,而且删除也要快,那么就是双向链表。总的来说这个算法就是:hash+双向链表。对于我这个小白来说,难点就是头尾指针的操作。在操作链表时,我把所有的头尾指针操作都写了,你们在写的时候可以将加入头结点和删除尾结点包装成一个方法,这样调用起来方便一点。