不能只用 std::unordered_map 实现 LRU,因其不维护访问顺序,无法 O(1) 定位最近最少使用节点;必须结合双向链表实现节点位置更新与淘汰,哈希表存 Node* 以支持零拷贝指针操作,并通过内存池或 deque 复用节点避免频繁分配。
为什么不能只用 std::unordered_map 实现 LRU?
因为 std::unordered_map 本身不维护访问顺序,无法在 O(1) 时间内定位“最近最少使用”的节点。LRU 的核心诉求是:每次 get 或 put 都要更新节点位置,且淘汰时取尾部——这必须靠双向链表支撑;而哈希表只负责 O(1) 定位节点指针。两者缺一不可。
常见错误是试图用 std::map 按时间戳排序,或给每个键存一个 last_access_time 再遍历找最小值——这两种都退化到 O(n),完全违背 LRU 的高性能初衷。
std::list 和自定义双向链表哪个更合适?
用 std::list 看似省事,但存在两个硬伤:一是迭代器失效风险(如外部代码意外调用 list::splice 或 erase);二是它不支持直接把某个节点移到头部——你得先 erase 再 push_front,触发两次内存操作,且 erase 后原迭代器立即失效,无法安全持有。
更稳妥的做法是手写轻量级双向链表节点:
立即学习“C++免费学习笔记(深入)”;
struct Node {
int key, value;
Node* prev;
Node* next;
Node(int k, int v) : key(k), value(v), prev(nullptr), next(nullptr) {}
};
这样能用 move_to_head() 原地调整指针,全程无内存分配、无迭代器失效,真正满足 O(1) 要求。