LRU缓存机制-算法

其底层实现的用map管理的双向链表,在链表的头部存放最近被访问的,尾部自然就是最近最久未被访问的节点。

其中需要保存的有size、capacity、head、tail、map成员属性

方法有get和put,

初始化的时候,需要设置参数大小,如果不设置的话,默认为10;

get方法,需要判断map中是否存在,如果存在直接返回,不存在放回-1;

put方法,需要判断map中是否存在,如果存在则修改当前key的value值,如果不存在,新建一个node,加入到map中,然后size ++;判断是否超出capacity,超出的话,需要移除链表尾元素,然后移除map的尾元素。

在使用get方法,需要将我们访问到元素加入到链表头部,并移除原先的关系。

在使用put方法,如果不存在,需要将我们访问到元素加入到链表头部且size大于capacity时,需要删除链表尾部元素,如果存在的话,将元素加入到链表头部,并移除原先的关系。

package com.lhb.offer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @author lhb
 * @date 2022/3/14
 */
public class Offer_146 {
    class Node{
        int key;
        int val;
        Node prev;
        Node next;

        public Node(int key, int val) {
            this.val = val;
            this.key = key;
        }

        public Node() {
        }
    }
    Map<Integer, Node> map;
    int capacity = 0;
    int size;
    Node head, tail;
    public Offer_146() {
        this(10);
    }
    public Offer_146(int capacity) {
        this.size = 0;
        this.capacity = capacity;
        head = new Node();
        tail = new Node();
        map = new HashMap<>();
        head.next = tail;
        tail.prev = head;
    }

    int get(int key) {
        Node node = map.get(key);
        if (node == null) {
            return -1;
        }
        removeNodeToHead(node);
        return node.val;
    }
    void put(int key, int val){
        Node node = map.get(key);
        if (node == null) {
            Node newNode = new Node(key, val);
            moveToHead(newNode);
            ++size;
            if (size > capacity) {
                Node tail = removeTail();
                map.remove(tail.key);
                --size;
            }
        } else {
            node.val = val;
            moveToHead(node);
        }
        node.next = head.next;
        head.next = node;
        size ++;
    }
    void removeNodeToHead(Node node) {
        removeNode(node);
        moveToHead(node);
    }
    void moveToHead(Node node) {
        node.next = head.next;
        head.next =node;
    }
    void removeNode(Node node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }
    Node removeTail() {
        Node temp = tail.prev;
        removeNode(temp);
        return temp;
    }

    public static void main(String[] args) {

    }
}

 

posted @ 2022-03-14 16:03  牵魂  阅读(29)  评论(0编辑  收藏  举报