首页 > 其他分享 >LRU

LRU

时间:2022-09-25 21:57:20浏览次数:34  
标签:node int DoubleLinkedNode value next LRU key

// LRU缓存机制
// 使用哈希表 + 双向链表(维护使用的频率)
class LRUCache {
    class DoubleLinkedNode {
        int key;    
        int value;
        DoubleLinkedNode prev;
        DoubleLinkedNode next;
        
        public DoubleLinkedNode() {}
        public DoubleLinkedNode(int key, int value) {
            this.key = key;
            this.value = value;
        }
    }

    int size;
    int capacity;
    DoubleLinkedNode head;  // 头结点(起到连接作用)
    DoubleLinkedNode tail;  // 尾节点(起到连接作用)
    Map<Integer, DoubleLinkedNode> cache = new HashMap<>(); // 起到缓存的作用

    public LRUCache(int capacity) {
        this.size = 0;
        this.capacity = capacity;

        head = new DoubleLinkedNode();
        tail = new DoubleLinkedNode();

        head.next = tail;
        tail.prev = head;
    }
    
    public int get(int key) {
        DoubleLinkedNode node =  cache.get(key);
        if (node == null) {
            return -1;  // 不存在 返回-1
        }
        moveToHead(node);   // 刚查询过,移动到头部
        return node.value;
    }

    // 移动到头部(删除节点 在头部增加节点)
    public void moveToHead(DoubleLinkedNode node) {
        removeNode(node);
        addToHead(node);
    }

    // 删除节点
    public void removeNode(DoubleLinkedNode node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    // 增加节点到头部
    public void addToHead(DoubleLinkedNode node) {
        node.prev = head;
        node.next = head.next;

        head.next = node;
        node.next.prev = node;
    }

    // 删除尾部节点
    public DoubleLinkedNode removeTail() {
        DoubleLinkedNode node = tail.prev;
        removeNode(node);
        return node;
    }
    
    public void put(int key, int value) {
        DoubleLinkedNode node = cache.get(key);
        if (node == null) {
            DoubleLinkedNode newNode = new DoubleLinkedNode(key, value);
            cache.put(key, newNode);
            addToHead(newNode);
            size++;
            if (size > capacity) {
                // 删除尾部元素
                DoubleLinkedNode tail = removeTail();   // 删除链表尾部
                cache.remove(tail.key);
                size--;
            }
        } else {
            node.value = value; //
            moveToHead(node);   // 移动到头部
        }
    }
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */

 

标签:node,int,DoubleLinkedNode,value,next,LRU,key
From: https://www.cnblogs.com/xiazhenbin/p/16729075.html

相关文章

  • 计算机系统结构大题精讲2-LRU替换算法
    LRU近期最少使用算法1、考虑一个920字的程序,其访问虚存的地址流为:23、216、156、618、382、490、492、868、916、728。若页面大小为200字,主存容量为600字,采用LRU算法。请......
  • 学习-从浏览器缓存淘汰策略和 Vue 的 keep-alive 学习 LRU 算法
    LRU(Leastfrequentlyused:最近最少使用)。算法在缓存写满的时候,会根据所有数据的访问记录,淘汰掉未来被访问几率最低的数据。也就是说该算法认为,最近被访问过的数据,在将来被......
  • js实现 LRU 算法
    方式一:map实现classLRU{constructor(size){this.size=size;this.cache=newMap();}get(key){if(this.cache.has(ke......
  • LinkedHashMap源码及LRU实现原理
    基本认识LinkedHashMap位于java.util包,于JDK1.4引入,属于JavaCollectionsFramework的成员。查看其UML关系如下图所示:HashMap在很多场景下都满足K-V的存取,而且在非多线......