[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;
};

 

posted on 2014-03-18 12:12  Felix Fang  阅读(786)  评论(0编辑  收藏  举报

导航