当前位置:首页 > JavaScript

js实现lru

2026-03-14 06:43:01JavaScript

实现LRU缓存算法的JavaScript方法

LRU(Least Recently Used)缓存算法是一种常见的缓存淘汰策略,核心思想是当缓存空间不足时,优先淘汰最近最少使用的数据。以下是两种JavaScript实现方式:

使用Map实现LRU缓存

Map的插入顺序特性天然适合LRU逻辑,结合其O(1)时间复杂度的操作:

js实现lru

class LRUCache {
  constructor(capacity) {
    this.capacity = capacity;
    this.cache = new Map();
  }

  get(key) {
    if (!this.cache.has(key)) return -1;
    const value = this.cache.get(key);
    this.cache.delete(key);
    this.cache.set(key, value);
    return value;
  }

  put(key, value) {
    if (this.cache.has(key)) this.cache.delete(key);
    this.cache.set(key, value);
    if (this.cache.size > this.capacity) {
      this.cache.delete(this.cache.keys().next().value);
    }
  }
}

特点

js实现lru

  • Map维护键值对的插入顺序,keys().next().value直接获取最久未使用的键
  • 所有操作时间复杂度均为O(1)
  • 代码简洁,直接利用语言特性

双向链表+哈希表实现

更经典的实现方式,显式维护访问顺序:

class ListNode {
  constructor(key, value) {
    this.key = key;
    this.value = value;
    this.prev = null;
    this.next = null;
  }
}

class LRUCache {
  constructor(capacity) {
    this.capacity = capacity;
    this.size = 0;
    this.hash = {};
    this.dummyHead = new ListNode();
    this.dummyTail = new ListNode();
    this.dummyHead.next = this.dummyTail;
    this.dummyTail.prev = this.dummyHead;
  }

  _moveToHead(node) {
    this._removeNode(node);
    this._addToHead(node);
  }

  _removeNode(node) {
    node.prev.next = node.next;
    node.next.prev = node.prev;
  }

  _addToHead(node) {
    node.prev = this.dummyHead;
    node.next = this.dummyHead.next;
    this.dummyHead.next.prev = node;
    this.dummyHead.next = node;
  }

  get(key) {
    const node = this.hash[key];
    if (!node) return -1;
    this._moveToHead(node);
    return node.value;
  }

  put(key, value) {
    const node = this.hash[key];
    if (node) {
      node.value = value;
      this._moveToHead(node);
    } else {
      const newNode = new ListNode(key, value);
      this.hash[key] = newNode;
      this._addToHead(newNode);
      this.size++;
      if (this.size > this.capacity) {
        const tail = this.dummyTail.prev;
        this._removeNode(tail);
        delete this.hash[tail.key];
        this.size--;
      }
    }
  }
}

特点

  • 双向链表维护访问顺序,头部是最新访问节点
  • 哈希表实现O(1)时间查找
  • 需要手动维护节点间的指针关系
  • 适用于需要更细粒度控制的场景

性能对比

实现方式 时间复杂度 空间复杂度 代码复杂度
Map实现 O(1) O(n)
双向链表+哈希表 O(1) O(n)

实际应用中,现代JavaScript引擎的Map实现已经非常高效,多数场景推荐使用第一种方案。如需支持更复杂的缓存策略(如TTL),可考虑扩展第二种方案。

标签: jslru
分享给朋友:

相关文章

js实现跳转

js实现跳转

使用 window.location 跳转 通过修改 window.location.href 或直接使用 window.location 实现页面跳转,适用于普通跳转或带参数的 URL。 // 方…

原生js实现轮播图

原生js实现轮播图

基本结构搭建 HTML部分需要包含轮播图容器、图片列表及导航按钮。结构示例如下: <div class="slider-container"> <div class="slid…

js实现vr

js实现vr

使用WebXR API实现VR体验 WebXR是浏览器中实现VR和AR体验的标准API,它取代了早期的WebVR。现代浏览器如Chrome、Edge和Firefox已支持WebXR。 // 初始化W…

js实现交换

js实现交换

交换变量的方法 在JavaScript中,交换两个变量的值有多种方法。以下是常见的几种实现方式: 使用临时变量 通过引入一个临时变量来存储其中一个变量的值,实现交换: let a = 1; le…

js实现跑马灯

js实现跑马灯

实现跑马灯效果 使用HTML和JavaScript可以轻松实现跑马灯效果。以下是两种常见的实现方式: HTML结构 <div id="marquee"> <span>…

js 实现递归

js 实现递归

递归的基本概念 递归是指函数直接或间接调用自身的过程。在JavaScript中,递归通常用于解决可以分解为相似子问题的问题,如阶乘、斐波那契数列、树形结构遍历等。 递归的实现要点 基线条件(Base…