LRU 缓存结构

文章目录

LRU

  • 优先去除最久没有访问到的数据。

实现

  • 通过组合哈希表(Hash Table)和双向链表(Doubly Linked List)实现 LRU 缓存。并且以 O(1) 的时间复杂度执行 get 和 put 操作
  • 核心是对节点的新增、访问都会让节点移动到双向链表头部,当容量超过时,直接删除尾部节点即可
javascript 复制代码
class LRUCache {
  constructor(capacity) {
    // 容量
    this.capacity = capacity;
    this.cache = new Map();

    // 用于记录访问顺序的双向链表,声明空的头节点和尾节点
    this.head = {};
    this.tail = {};
    // 头和尾相连
    this.head.next = this.tail;
    this.tail.prev = this.head;
  }

  get(key) {
    const map = this.cache;

    if (!map.has(key)) {
      return -1;
    }
	// 每次把使用的节点放到链表的头部
    const node = map.get(key);
    this._moveToHead(node);
    return node.value;
  }

  put(key, value) {
    const map = this.cache;
    
    // 如果 key 已存在,更新并移动到双向链表头部
    if (map.has(key)) {
      const node = map.get(key);
      node.value = value;
      this._moveToHead(node);
    } else {
      if (map.size >= this.capacity) {
        // 缓存容量已满,移除尾部节点
        const leastUsedKey = this.tail.prev.key;
        this._removeNode(this.tail.prev);
        map.delete(leastUsedKey);
      }

      // 创建新节点,和更新 HashMap,并移动到链表头部
      const newNode = this._addNode({ key, value });
      map.set(key, newNode);
    }
  }
  // 双向链表删除节点
  _removeNode(node) {
    node.prev.next = node.next;
    node.next.prev = node.prev;
  }
 // 删除双向链表旧节点位置,然后移动到头部
  _moveToHead(node) {
    this._removeNode(node);
    this._addNode(node);
  }
 // 添加节点并移动到头部
  _addNode(node) {
    node.prev = this.head;
    node.next = this.head.next;
    this.head.next.prev = node;
    this.head.next = node;
    return node;
  }
}

// 使用示例
const cache = new LRUCache(2);
cache.put(1, 10);
console.log(cache.get(1)); // 10
cache.put(2, 20);
cache.put(3, 30);
console.log(cache.get(1)); // -1
相关推荐
三十而立洋39 分钟前
深入理解 Monorepo:子包安装依赖
前端·前端工程化
IT_陈寒1 小时前
Java Stream处理大集合,我的内存怎么就炸了
前端·人工智能·后端
Captaincc1 小时前
AI 用量桌面端-桌面宠物自定义指南
前端·人工智能
a187927218311 小时前
【算法】双指针与滑动窗口(二):滑动窗口——吃进、判定、吐出
算法·leetcode·双指针·滑动窗口·原理·模板·算法讲解
铭哥的编程日记1 小时前
从一道 LeetCode Hard 到吃透一类题:加权区间调度「排序 + 二分 + DP」
算法·leetcode·职场和发展
Navigator_Z1 小时前
LeetCode //C - 1248. Count Number of Nice Subarrays
c语言·算法·leetcode
OpenTiny社区1 小时前
码力全开,智启前端新生态|OpenTiny 登陆华为全联接大会2026
前端·github
妙码生花1 小时前
利用AI从零学Go并完成实战项目,完工总结:目录结构
前端·后端·go
妙码生花2 小时前
利用AI从零学Go并完成实战项目,完工总结:商业级开源产品定位和核心特性介绍
前端·后端·go
Captaincc2 小时前
掘金AI用量统计v0.1.0大更新-支持桌面宠物自定义和订阅额度卡片
前端·后端