当前位置:首页 > JavaScript

js实现lru

2026-04-06 00:46:09JavaScript

LRU缓存算法的实现思路

LRU(Least Recently Used)缓存算法是一种常见的缓存淘汰策略,其核心思想是淘汰最久未使用的数据。在JavaScript中可以通过Map或双向链表实现。

使用Map实现LRU

Map对象保存键值对,并且能够记住键的原始插入顺序,这非常适合实现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);
    } else if (this.cache.size >= this.capacity) {
      const oldestKey = this.cache.keys().next().value;
      this.cache.delete(oldestKey);
    }
    this.cache.set(key, 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.cache = {};
    this.head = new ListNode(0, 0);
    this.tail = new ListNode(0, 0);
    this.head.next = this.tail;
    this.tail.prev = this.head;
  }

  _addNode(node) {
    node.prev = this.head;
    node.next = this.head.next;
    this.head.next.prev = node;
    this.head.next = node;
  }

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

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

  _popTail() {
    const res = this.tail.prev;
    this._removeNode(res);
    return res;
  }

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

  put(key, value) {
    const node = this.cache[key];
    if (!node) {
      const newNode = new ListNode(key, value);
      this.cache[key] = newNode;
      this._addNode(newNode);
      this.size++;
      if (this.size > this.capacity) {
        const tail = this._popTail();
        delete this.cache[tail.key];
        this.size--;
      }
    } else {
      node.value = value;
      this._moveToHead(node);
    }
  }
}

两种实现方式的比较

Map实现方式代码更简洁,适合容量不大的缓存场景。双向链表实现方式性能更高,特别是在频繁操作的大容量缓存场景下,能保证O(1)时间复杂度。

js实现lru

在实际应用中,如果缓存容量较小且对性能要求不高,可以选择Map实现。对于需要高性能的大规模缓存系统,推荐使用双向链表+哈希表的实现方式。

标签: jslru
分享给朋友:

相关文章

js实现交换

js实现交换

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

js实现正交

js实现正交

正交的概念 正交在数学和计算机科学中通常指两个向量垂直或线性无关。在编程中,正交性常被用于设计模块化、低耦合的系统。 向量正交判断 判断两个向量是否正交可以通过点积是否为0来实现: fun…

js实现 功能

js实现 功能

在 JavaScript 中实现功能通常涉及多个关键步骤,具体取决于功能需求。以下是常见功能的实现方法和示例: 基本功能实现 使用函数封装逻辑是最直接的方式。例如,实现一个计算两数之和的函数: f…

js实现菜单

js实现菜单

实现基本HTML结构 使用HTML创建菜单的基本框架,通常包含<ul>和<li>元素。示例结构如下: <ul id="menu"> <li><…

js实现删除

js实现删除

使用 splice 方法删除数组元素 splice 方法可以删除数组中的元素,并返回被删除的元素。它接受两个参数:起始索引和要删除的元素数量。 const array = [1, 2, 3, 4…

js实现图片滚动

js实现图片滚动

图片滚动的实现方法 使用CSS动画实现 通过CSS的animation和@keyframes可以实现简单的图片滚动效果。这种方法适合静态图片的无缝循环滚动。 <style> .scr…