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

};

 

你可能感兴趣的:(LeetCode)