zoukankan      html  css  js  c++  java
  • [Leetcode] LRU 算法实现

    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是虚拟内存技术中,页置换时需要用到的算法,最近最少使用算法。也就是说替换掉最近最少被使用的页。

    采用双链表实现一个栈,栈顶(用head指针表示)放最近使用的元素。end指针表示栈底,地方不够的时候end指针的元素值就会被覆盖,覆盖后因为成了最近使用,所以会被提到head的位置。链表中部也可能有元素被提到head的位置。

    class LRUCache{
    struct ListNode{
        int key;
        int value;
        ListNode* prev;
        ListNode* next;
    };
    public:
        LRUCache(int capacity){
            if(capacity >= 0){
                Capacity = capacity;
                size = 0;
            }
        }
        
        void set(int key, int value){
            ListNode* p = head;
            for(; p != NULL && p -> key != key; p = p -> next);
            if(p == NULL && size == Capacity){  //The case that didn't find key and capacity is full
                p = end;
                p -> key = key;
            }
            if(p != NULL){  //The case that has found the key (treat the previous case as found the key in end)
                p -> value = value;
                if(p != head){  //If the key is in head of the list, we don't need to do anything since the head is the most recently used.
                    ListNode* pre = p -> prev;
                    ListNode* fol = p -> next;
                    
                    if(p == end && pre != NULL){
                        end = pre;
                    }
                    p -> next = head;
                    p -> prev = NULL;
                    head -> prev = p;
                    head = p;
                
                    if(pre != NULL)
                        pre -> next = fol;
                    if(fol != NULL)
                        fol -> prev = pre;
                }
            }else{  //The case that has not found the key, and capacity is not full, need to create one.
                p = new ListNode();
                p -> key = key;
                p -> value = value;
                if(head == NULL){
                    head = end = p;
                    p -> prev = NULL;
                    p -> next = NULL;
                }else{
                    p -> prev = NULL;
                    p -> next = head;
                    head -> prev = p;
                    head = p;
                }
                size++;
            }
            
        }
        
        int get(int key){
            ListNode* p = head;
            for(; p != NULL && p -> key != key; p = p -> next);
            if(p == NULL) return -1;
        
            if(p != head){
                ListNode* pre = p -> prev;
                ListNode* fol = p -> next;
                if(p == end)
                    end = pre;
                
                p -> next = head;
                p -> prev = NULL;
                head -> prev = p;
                head = p;
                
                if(pre != NULL)
                    pre -> next = fol;
                if(fol != NULL)
                    fol -> prev = pre;
            }
            return p -> value;
        }
    private:
        ListNode* head = NULL;
        ListNode* end = NULL;
        int size = 0;
        int Capacity = 0;
    };
  • 相关阅读:
    context-annotation
    bean-annotation
    K-means算法
    基于概率的分类-贝叶斯分类
    Application
    ConfigurableApplicationContext
    相关性分析
    方差分析
    Java 大写金额转换成数字
    linux 遍历文件添加index
  • 原文地址:https://www.cnblogs.com/felixfang/p/3607336.html
Copyright © 2011-2022 走看看