# LRU [Leetcode 146. LRU Cache](https://leetcode.cn/problems/lru-cache/description/) Header: ```cpp #ifndef S0146_LRU_CACHE_HPP #define S0146_LRU_CACHE_HPP #include #include class LRUCache { public: /** * @brief Least Recently Used Cache * * 这是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰 * * @param capacity 容量,这是一个正整数 */ LRUCache(int capacity); /** * @brief 读取数据 * * @param key 数据对应的键值 * @return 数据的值 */ int get(int key); /** * @brief 放入对应的数据 * * @param key 数据对应的键值 * @param value 数据对应的值 */ void put(int key, int value); private: struct CacheNode { int key; int value; CacheNode *next; CacheNode *prev; CacheNode(int key, int value) : key(key), value(value), next(nullptr), prev(nullptr){}; CacheNode(int key, int value, CacheNode *next, CacheNode *prev) : key(key), value(value), next(next), prev(prev){}; }; CacheNode *head; CacheNode *tail; int capacity; std::unordered_map map; // 键值是 key,值是该节点的指针 void moveToHead(CacheNode *node); // 将节点移动到头部 }; #endif ``` Source: ```cpp #include "s0146_lru_cache.hpp" void LRUCache::moveToHead(CacheNode *node) { // 如果是头部节点 if (node == head) return; // 如果不是头部节点,但是是尾部节点 if (node == tail) tail = node->prev; // 处理该节点的前后两个节点的指针 if (node->prev) node->prev->next = node->next; if (node->next) node->next->prev = node->prev; // 将该节点移动到头部 node->prev = nullptr; node->next = head; // 处理头部节点 head->prev = node; head = node; } LRUCache::LRUCache(int capacity) { this->capacity = capacity; head = nullptr; tail = nullptr; map = std::unordered_map(); } int LRUCache::get(int key) { if (map.size() == 0) return -1; if (map.count(key) == 0) return -1; moveToHead(map[key]); return map[key]->value; } void LRUCache::put(int key, int value) { // 如果 key 已存在,则更新 value ,并将这个节点移动到头部 if (map.count(key) == 1) { map[key]->value = value; moveToHead(map[key]); return; } // 否则创建该节点 CacheNode *newNode = (CacheNode *)malloc(sizeof(CacheNode)); newNode->value = value; newNode->key = key; newNode->next = head; newNode->prev = nullptr; // 处理头部节点 if (head) head->prev = newNode; head = newNode; // 处理尾部节点 if (map.size() == 0) tail = newNode; // 更新哈希表 map[key] = newNode; // 如果容量已满 if (map.size() > capacity) { // 更新尾部节点 CacheNode *node = tail; if (tail->prev) { tail->prev->next = nullptr; tail = tail->prev; } // 移除该节点 map.erase(node->key); free(node); } } ```