zoukankan      html  css  js  c++  java
  • LRU Cache

    题意:

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.

    get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
    set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

    学LRU是在操作系统中,最近最久未被使用的,根据cache的大小,每当有一个进程来到时,都要根据当前的情况而做一些改变。

    set:如果当前来到的key在cache中,则将该节点删除并且移到链表的头部,如果不存在,并且当前的cache满了,则将尾部删除,将新来的节点加入到链表的首部,否则直接加入练表中即可。

    get:如果当前的key在cache中,则将该节点从链表中移除并且添加带链表的首部并返回value,否则返回-1。

    代码给的是用hashmap和双链表完成的,因为当删除一个节点的时候,需要知道他的后记节点,虽然单链表也能做到这一点,但是如果要删除的节点是尾节点,那么就要知道他的前一个节点,这样的话就要便利整个链表,那么就会花o(n)的时间复杂度,虽然说当链表中有n个节点,那么(o(1)*(n-1) + o(n))/n这样平均的话时间复杂度是在o(1)的,但是也可以彻底做到时间复杂度是o(1)的,就用双链表,会将首位标记出来。

     
    struct Linklist
    {
        int key;
        int value;
        struct Linklist* pre;
        struct Linklist* next;
    };
    
    class LRUCache
    {
    private:
        int count;
        int size;
        struct Linklist* tail;
        struct Linklist* head;
        map<int,Linklist*>mp;
    public:
        LRUCache(int size)
        {
            this->size = size;
            this->tail = NULL;
            this->head = NULL;
            this->count = 0;
        }
        //如果该节点在map中存在,则删除当前的,并改变节点的值,将该节点放在双链表的表头
        //否则返回-1
        int get(int key)
        {
            if(head == NULL) return -1;
            map<int,Linklist*>::iterator it = mp.find(key);
            if(it == mp.end()) 
            {
                return -1;
            } 
            else 
            {
                Linklist *p = it->second;
                pushup(p);
            }
            return head->value;
        }
        //双链表删除节点 然后放在双链表的表头
        void pushup(Linklist* p)
        {
            if(this->count == 1) return ;
            if(p == this->head) return;
            if(p == this->tail) 
            {
                tail = p->pre;
            }
            p->pre->next = p->next;
            if(p->next != NULL)
                p->next->pre = p->pre;
    
            p->next = head;
            p->pre = NULL;
            head->pre = p;
            head = p;
        }
        //当前值,没有在cache中  则删除链表中最后一个节点&&map中删除,然后将访问的节点加在链表的表头
        //没有在cache中,则将尾删除  将新的元素入链表  并将元素加入到map中
        void  set(int key,int value)
        {
            if(head == NULL)
            {
                head = (Linklist *)malloc(sizeof(Linklist));
                head->value = value;
                head->key = key;
                head->pre = NULL;
                head->next = NULL;
                mp[key] = head;
                tail = head;
                this->count++;
            }
            else
            {
                map<int,Linklist*>::iterator it = mp.find(key);
                if(it == mp.end()) 
                {
                    if(size == count)
                    {
                        if(size == 1 && tail == head) //size == 1
                        {
                            mp.erase(head->key);
                            head->key = key;
                            head->value = value;
                            mp[head->key] = head;
                        }
                        else //
                        {
                            Linklist *p = tail;
                            tail->pre->next = p->next;
                            mp.erase(tail->key);
                            tail = tail->pre;
                            p->key = key;
                            p->value = value;
                            p->next = head;
                            head->pre = p;
                            head = p;
                            mp[head->key] = head;
    
                        }    
                    }
                    else
                    {
                        Linklist *p = (Linklist*)malloc(sizeof(Linklist));
                        p->value = value;
                        p->key = key;
                        p->next = head;
                        p->pre = NULL;
                        head->pre = p;
                        head = p;
                        mp[head->key] = head;
                        this->count++;
                    }
                }
                else
                {
                    Linklist *p = it->second;
                    p->value = value;
                    pushup(p);
                }
            }
        }
    };

    lala

  • 相关阅读:
    40 图 |我用 Mac M1 玩转 Spring Cloud
    # 20 图 |6000 字 |实战缓存(上篇)
    博客园,你肿么了?
    ES 终于可以搜到”悟空哥“了!
    48 张图 | 手摸手教你微服务的性能监控、压测和调优
    植树节,种个二叉树吧?
    紫霞仙子:区块链的十二连问
    太上老君的炼丹炉之分布式 Quorum NWR
    病毒入侵:全靠分布式
    为什么要“除夕”,原来是内存爆了
  • 原文地址:https://www.cnblogs.com/chenyang920/p/5979076.html
Copyright © 2011-2022 走看看