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)
相关推荐
Zenova EdgeOS23 分钟前
Go 工业边缘错误处理实战:用 errors 构建可追溯错误链
开发语言·数据库·golang
取名真是35 分钟前
Python 算法知识点从基础到进阶
开发语言·python·算法
梦想不只是梦与想43 分钟前
PyTorch、CPU、GPU、CUDA
人工智能·pytorch·python·深度学习·机器学习·cuda
数字融合44 分钟前
透明化视频孪生危化安全管控解决方案
人工智能·python·安全
FRing031 小时前
vue2干货总结3(computed计算属性、watch监听器)
开发语言·前端·vue.js·vue2
Fatbobman(东坡肘子)2 小时前
快速消失的硬盘容量 -- 肘子的 Swift 周报 #160
开发语言·人工智能·redis·ios·swiftui·iphone·swift
揽星河..2 小时前
【C语言】底层程序设计
c语言·开发语言
JavaPub-rodert2 小时前
从零搭建通用管理后台:ShiyuAdmin 的 Go、React 与 RBAC 实践
开发语言·react.js·golang
别问!问就是全会2 小时前
Jupyter Notebook 安装包下载|单元格分块运行,图表直接内嵌
ide·python·其他·jupyter
深蓝AI3 小时前
Python 缓存击穿实测:16 个并发请求如何只回源 1 次
python