LRU机制实现

Least Recently Used (LRU)最近最少使用。

函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

C++版本,

cpp 复制代码
struct DLinkedNode {
    int key, value;
    DLinkedNode* prev;
    DLinkedNode* next;
    DLinkedNode() : key(0), value(0), prev(nullptr), next(nullptr) {}
    DLinkedNode(int _key, int _value) : key(_key), value(_value), prev(nullptr), next(nullptr) {}
};

class LRUCache {
private:
    unordered_map<int, DLinkedNode*> cache;
    DLinkedNode* head;
    DLinkedNode* tail;
    int size;
    int capacity;

public:
    LRUCache(int capacity) : capacity(capacity), size(0) {
        head = new DLinkedNode();
        tail = new DLinkedNode();
        head->next = tail;
        tail->prev = head;
    }
    
    int get(int key) {
        if (!cache.count(key)) {
            return -1;
        }
        DLinkedNode* node = cache[key];
        moveToHead(node);
        return node->value;
    }
    
    void put(int key, int value) {
        if (!cache.count(key)) {
            DLinkedNode* node = new DLinkedNode(key, value);
            cache[key] = node;
            addToHead(node);
            ++size;
            if (size > capacity) {
                DLinkedNode* removed = removeTail();
                cache.erase(removed->key);
                delete removed;
                --size;
            }
        } else {
            DLinkedNode* node = cache[key];
            node->value = value;
            moveToHead(node);
        }
    }

    void addToHead(DLinkedNode* node) {
        node->prev = head;
        node->next = head->next;
        head->next->prev = node;
        head->next = node;
    }

    void removeNode(DLinkedNode* node) {
        node->prev->next = node->next;
        node->next->prev = node->prev;
    }

    void moveToHead(DLinkedNode* node) {
        removeNode(node);
        addToHead(node);
    }

    DLinkedNode* removeTail() {
        DLinkedNode* node = tail->prev;
        removeNode(node);
        return node;
    }
};

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache* obj = new LRUCache(capacity);
 * int param_1 = obj->get(key);
 * obj->put(key,value);
 */

python3版本,

python 复制代码
class DLinkedNode:
    def __init__(self, key=0, value=0):
        self.key = key 
        self.value = value 
        self.prev = None 
        self.next=  None 

class LRUCache:

    def __init__(self, capacity: int):
        self.cache = dict()
        self.head = DLinkedNode()
        self.tail = DLinkedNode()
        self.head.next = self.tail 
        self.tail.prev = self.head 
        self.capacity = capacity 
        self.size = 0

    def get(self, key: int) -> int:
        if key not in self.cache:
            return -1
        node = self.cache[key]
        self.moveToHead(node)
        return node.value 

    def put(self, key: int, value: int) -> None:
        if key not in self.cache:
            node = DLinkedNode(key, value)
            self.cache[key] = node 
            self.addToHead(node)
            self.size += 1
            if self.size > self.capacity:
                removed = self.removeTail()
                self.cache.pop(removed.key)
                self.size -= 1
        else:
            node = self.cache[key]
            node.value = value 
            self.moveToHead(node)
    
    def addToHead(self, node):
        node.prev = self.head 
        node.next = self.head.next 
        self.head.next.prev = node 
        self.head.next = node 
    
    def removeNode(self, node):
        node.prev.next = node.next 
        node.next.prev = node.prev 
    
    def moveToHead(self, node):
        self.removeNode(node)
        self.addToHead(node)
    
    def removeTail(self):
        node = self.tail.prev 
        self.removeNode(node)
        return node 



# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
相关推荐
浪浪山齐天大圣21 分钟前
python数据可视化之Matplotlib(8)-Matplotlib样式系统深度解析:从入门到企业级应用
python·matplotlib·数据可视化
F_D_Z32 分钟前
【PyTorch】单对象分割
人工智能·pytorch·python·深度学习·机器学习
编程自留地34 分钟前
18.4 查看订单
python·django·商城
wanzhong233337 分钟前
学习triton-第1课 向量加法
开发语言·python·高性能计算
浊酒南街39 分钟前
Pytorch基础入门4
人工智能·pytorch·python
三千道应用题1 小时前
C#语言入门详解(18)传值、输出、引用、数组、具名、可选参数、扩展方法
开发语言·c#
忧郁的蛋~1 小时前
使用.NET标准库实现多任务并行处理的详细过程
开发语言·c#·.net
dragon_perfect1 小时前
全流程基于Yolov8实现在Label-Studio实现半自动标注,已经把整个流程理清楚,把所有的坑解决。
开发语言·python·yolo·labelstudio
kalvin_y_liu1 小时前
四款主流深度相机在Python/C#开发中的典型案例及技术实现方案
开发语言·python·数码相机
劲镝丶1 小时前
malloc概述
c语言·开发语言·c++