缓存淘汰策略 LRU

定义Node结点
注意这里的构造函数是要初始化的有参的构造函数。
class Node{
Node pre,next; //定义结点的前后结点
int key,val;
public Node(int key,int val){
this.key=key;
this.val=val;
}
}
手写双向链表
需要用到上面定义的 Node Class类,其实主要就是注意指针的边界条件。
还有在这三个函数:
- void addFirst(Node n)
- void remove(Node n)
- Node removeLast()
这几个函数里面关于前向和后向指针的指向要注意。
class DoubleList{
Node head,tail;//这是在定义头尾结点,但是要在构造函数里面初始化
public DoubleList(){
head=new Node(0,0);
tail=new Node(0,0);
// 这里初始化的时候 把head 和 tail 连接起来先
head.next=tail;
tail.pre=head;
}
void addFirst(Node n){// 头插
head.next.pre=n;
n.next=head.next;
n.pre=head;
head.next=n;
}
void remove(Node n){// 删除指定的结点
n.pre.next = n.next;
n.next.pre = n.pre;
}
Node removeLast(){
Node last=tail.pre;
remove(last);
return last;
}
}
主要LRU的实现
上面主要是我们自己定义数据结构,其实java里面的LinkedHashMap也可以直接拿来用,不过我们这样的话,就容易让这道题没什么好写的,所以最好还是别偷懒吧,这些东西自己写了之后,对自己的代码能力也会有提升的。
//主要LRU的实现
class LRUCache {
Map<Integer,Node> map;
DoubleList cache;
int cap;// 我们初始化的容量
public LRUCache(int capacity) {
map=new HashMap<>();
cache=new DoubleList();
this.cap=capacity;
}
public int get(int key) {
if(!map.containsKey(key)){
return -1;
}
Node n=map.get(key);
cache.remove(n);
cache.addFirst(n);
return n.val;
}
public void put(int key, int value) {
Node n=new Node(key,value);
if(map.containsKey(key)){
cache.remove(map.get(key));
}else if(cap==map.size()){
Node oldest=cache.removeLast();
map.remove(oldest.key);
}
cache.addFirst(n);
map.put(key,n);
}
}

浙公网安备 33010602011771号