缓存淘汰策略 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);
    }
}

posted @ 2022-05-02 13:01  ArtiaDeng  阅读(43)  评论(0)    收藏  举报