LRU has not been implemented using the algorithm hash table + doubly linked list for the longest time recently

LRU algorithm

Based on the principle of locality, recently accessed memory is likely to be accessed again in the future.

Therefore, when we eliminate data, we give priority to eliminating the data that has not been used for the longest time.

Implementation ideas

Use a doubly linked list to mount the most recently used data to the head of the chain, so that the longest unused data is at the end of the queue, and delete the elements at the end of the queue when eliminating data.

To quickly locate a key keyThe position of k e y in the linked list, you can use a hash table to recordkey − N ode key-NodekeyNode mapping . _ _

topic

Leetcode 146. LRU cache

insert image description here

Code

class LRUCache
{
    
    
public:
    struct DListNode
    {
    
    
        int key, value; //事实上key值没有使用
        DListNode *pre;
        DListNode *next;
        DListNode() {
    
    }
        DListNode(int a, int b) {
    
     key = a, value = b; }
    };

    unordered_map<int, DListNode *> mp; // key-Node 映射

    int MAX_SIZE;
    DListNode *HEAD;
    DListNode *TAIL;
    LRUCache(int capacity) //初始化双向链表
    {
    
    
        MAX_SIZE = capacity;
        HEAD = new DListNode;
        TAIL = new DListNode;
        HEAD->next = TAIL;
        TAIL->pre = HEAD;
    }

    int get(int key)
    {
    
    
        if (!mp.count(key)) //如果该key不存在,返回-1
            return -1;

        DListNode *tmp = mp[key]; //将这个结点调整到链表头部
        tmp->pre->next = tmp->next;
        tmp->next->pre = tmp->pre;
        tmp->next = HEAD->next;
        tmp->pre = HEAD;
        HEAD->next = tmp;
        tmp->next->pre = tmp;
        return mp[key]->value;
    }

    void put(int key, int value)
    {
    
    
        if (!mp.count(key)) //如果之前不在缓存,创建并放到链头
        {
    
    
            DListNode *tmp = new DListNode(key, value); //将这个结点放到链表头部
            mp[key] = tmp;
            tmp->pre = HEAD;
            tmp->next = HEAD->next;
            HEAD->next->pre = tmp;
            HEAD->next = tmp;
            if (mp.size() > MAX_SIZE) //超过容量,需要删除链表尾部结点
            {
    
    
                mp.erase(TAIL->pre->key);
                TAIL->pre->pre->next = TAIL;
                TAIL->pre = TAIL->pre->pre;
            }
        }
        else //已经存在,调整到链表头部
        {
    
    
            DListNode *tmp = mp[key];
            tmp->value = value;
            tmp->pre->next = tmp->next;
            tmp->next->pre = tmp->pre;
            tmp->next = HEAD->next;
            tmp->pre = HEAD;
            HEAD->next->pre = tmp;
            HEAD->next = tmp;
        }
    }
};

Guess you like

Origin blog.csdn.net/hesorchen/article/details/124096105