LRU算法初识(小白的第一篇CSDN)
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+双向链表。对于我这个小白来说,难点就是头尾指针的操作。在操作链表时,我把所有的头尾指针操作都写了,你们在写的时候可以将加入头结点和删除尾结点包装成一个方法,这样调用起来方便一点。