ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【数据结构】算法设计 LRU Least Recently Used 最近最少使用算法

2021-06-06 11:34:39  阅读:166  来源: 互联网

标签:Node node Used Recently map int 算法 key public


目录

LRU Least Recently Used 最近最少使用算法

LRU可以算是书本中比较熟悉的算法了,有缓存存在的场景下,基本都会有它的身影。它的作用就是在空间一定的缓存中,淘汰掉最近最少使用的数据,这样就有空间容纳新的数据。

那么假如需要设计一个类似LRU的算法,要支持获取数据get和插入数据put,并且要求时间复杂度在O(1)。

如果get返回-1,代表这个值不在缓存中,否则返回对应的值。

put(k,v)的操作,如果k在缓存中,那就更新。如果不存在就插入,如果缓存容量满了,就把最近没有使用过的数据删掉,再插入。

思路

要求时间复杂度O(1),说明查找的速度和插入的速度都必须很快。

我们还要维护一个最近最久未使用的数据,但是这个数据一旦被访问过,就不再是最近最久未使用的数据了。

结合这几个要求,链表应该是最符合的数据结构了,但是链表存在一个问题,查找的速度不是O(1)。那就再加一个Map,把所有的链表节点都放到Map中,这样查找的速度就是O(1)。

链表还必须是带尾指针的双向链表,这样删除的操作就会更加的方便。

class LRUCache {
//实现一个双向链表
public class DList{
       private Node ret;
       private int size;

       private Node tail;
       public DList(){
            this.ret = new Node(-1,-1);
            this.size=0;
       }

       public void addFirst(Node node){
            if(ret.next==null){
                ret.next = node;
                node.prev = ret;
                tail = node;
                size++;
                return;
            }
            Node p = ret.next;
            node.next =p;
            ret.next = node;
            p.prev = node;
            node.prev = ret;
            size++;
            return;
       }

       public void remove(Node node){
           if(node==tail){
               tail = tail.prev ;
           }
           Node p = node.prev;
           Node q = node.next;
           p.next = q;
           if(q!=null){
               q.prev = p;
           }
           size--;
       }

       public Node removeLast(){
           Node res = tail;
           remove(tail);
           return res;
       }
        public int size(){
           return this.size;
       }
   }

    public class Node {
        public int key, val;
        public Node next, prev;
        public Node(int k, int v) {
            this.key = k;
            this.val = v;
        }
   }

        private HashMap<Integer, Node> map;
        private int cap;
        private DList cache;
        public LRUCache(int capacity) {
            this.cap = capacity;
            this.map = new HashMap<>();
            this.cache = new DList();
        }

        public int get(int key) {
            if(!map.containsKey(key)){
                return -1;
            }
            Node node = map.get(key);
            int val = node.val;
            put(key,val);
            return val;
        }

        public void put(int key, int value) {
            Node x = new Node(key, value);
            if(map.containsKey(key)){
                cache.remove(map.get(key));
                cache.addFirst(x);
                map.put(key,x);
            }
            else{
                if(cap == cache.size()){
                    Node last = cache.removeLast();
                    map.remove(last.key);
                }
                cache.addFirst(x);
                map.put(key,x);
            }
        }
}

Tag

design LRU

标签:Node,node,Used,Recently,map,int,算法,key,public
来源: https://www.cnblogs.com/dreamtaker/p/14854881.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有