JavaScript双向链表实现LRU缓存算法的示例代码

首先,我们需要了解下什么是双向链表和LRU缓存算法。

双向链表:每个节点有两个指针,一个指向其前驱节点,一个指向其后继节点。双向链表的优势在于可以快速对链表中的任意节点进行插入、删除和移动操作,时间复杂度均为O(1)。

LRU缓存算法:Least Recently Used,即最近最少使用。LRU缓存算法通过记录缓存中每个数据项的访问时间,当缓存空间满时,将最近最少使用的数据项从缓存中移除,以空出空间保存新数据。

接下来是双向链表实现LRU缓存算法的示例代码:

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

class LRUCache {
  constructor(capacity) {
    this.capacity = capacity
    this.length = 0
    this.head = new CacheNode(null, null)
    this.tail = new CacheNode(null, null)
    this.head.next = this.tail
    this.tail.prev = this.head
    this.cache = {}
  }

  get(key) {
    if (key in this.cache) {
      const node = this.cache[key]
      this.moveToHead(node)
      return node.value
    } else {
      return -1
    }
  }

  put(key, value) {
    if (key in this.cache) {
      const node = this.cache[key]
      node.value = value
      this.moveToHead(node)
    } else {
      const node = new CacheNode(key, value)
      this.cache[key] = node
      this.addToHead(node)
      this.length++
      if (this.length > this.capacity) {
        this.removeTail()
        this.length--
      }
    }
  }

  moveToHead(node) {
    this.removeNode(node)
    this.addToHead(node)
  }

  addToHead(node) {
    node.prev = this.head
    node.next = this.head.next
    this.head.next.prev = node
    this.head.next = node
  }

  removeNode(node) {
    node.prev.next = node.next
    node.next.prev = node.prev
  }

  removeTail() {
    const node = this.tail.prev
    this.removeNode(node)
    delete this.cache[node.key]
  }
}

这里我们定义了两个类:CacheNode 和 LRUCache。CacheNode 表示缓存的节点,包含一个key和value属性,以及两个指针prev和next。LRUCache 是缓存的数据结构,包含一个capacity属性表示缓存容量,一个length属性表示当前缓存中元素的数量,一个head属性表示双向链表的头节点,一个tail属性表示双向链表的尾节点,和一个cache对象表示缓存中的所有数据。

get(key) 方法表示获取缓存中的数据。如果不存在,则返回-1。如果存在,则将对应节点移动到双向链表的头部,表示最近使用了该数据,并返回节点的值。

put(key, value) 方法表示往缓存中添加数据。如果缓存中已经存在该数据,直接移动到双向链表的头部即可。如果不存在,新建一个节点,添加到双向链表的头部,并在cache中增加对key的引用。如果缓存容量已满,需要将双向链表尾部的节点删掉,并在cache中删除对应的key的引用。

moveToHead(node) 方法表示将节点移动到双向链表的头部,表示最近使用了该数据。需要先将该节点从双向链表中删除,然后添加到双向链表的头部。

addToHead(node) 方法表示添加节点到双向链表的头部。

removeNode(node) 方法表示从双向链表中删除节点。

removeTail() 方法表示删除双向链表的尾节点。需要先删除该节点的引用,再从双向链表中删除该节点。

下面是一个示例:

const cache = new LRUCache(2)

cache.put(1, 'a')
cache.put(2, 'b')

console.log(cache.get(1)) // output: 'a'

cache.put(3, 'c')

console.log(cache.get(2)) // output: -1

cache.put(4, 'd')

console.log(cache.get(1)) // output: -1
console.log(cache.get(3)) // output: 'c'
console.log(cache.get(4)) // output: 'd'

这里我们创建了一个容量为2的LRUCache。然后分别往cache中添加数据,最后输出各个数据的值。在输出数据之前,我们先打印LRUCache的状态。可以看到,当调用put方法,向cache中添加第3个元素时,cache中已经满了,需要将最旧的数据(key=1)删除。最后输出的结果中也验证了这点。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript双向链表实现LRU缓存算法的示例代码 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • JavaScript前端构建工具原理的理解

    JavaScript前端构建工具是指能够自动进行前端开发过程的工具。它们可以自动生成、优化和修改前端代码和资源,以提高开发效率、代码质量和应用性能。常见的前端构建工具包括Webpack、Grunt和Gulp等。 以下是JavaScript前端构建工具原理的理解: 工作原理 前端构建工具的工作原理主要包括以下四个步骤: 读取和解析配置文件:前端构建工具需要读取…

    node js 2023年6月9日
    00
  • 使用Node.js写一个代码生成器的方法步骤

    使用Node.js编写代码生成器的方法步骤如下: 1. 安装Node.js 首先需要安装Node.js,Node.js是一款基于Chrome V8引擎的JavaScript运行时。安装完后,可以使用Node.js的npm模块来安装其他需要使用的包。 2. 选择生成器类型 生成器有各种不同的类型,可以用于不同的用途。例如,可以创建一个用于生成web应用程序的生…

    node js 2023年6月8日
    00
  • node中使用es6/7/8(支持性与性能)

    在Node中使用ES6/7/8语法需要经过一些配置和使用相关的工具,下面是具体的步骤: 1. 安装工具 安装babel和babel-cli,可用以下命令: $ npm install –save-dev babel babel-cli $ npm install –save-dev babel-preset-env 其中,babel-preset-env…

    node js 2023年6月8日
    00
  • 前端开发不得不知的10个最佳ES6特性

    前言 在现代前端开发中,了解 ES6(ECMAScript 2015)是非常重要的。ES6是JavaScript的下一代标准,已经成为前端开发的主要标准之一。本文将重点介绍前端开发者不得不知道的10个最佳ES6特性,帮助你在开发中更轻松地使用JavaScript。 1. 变量声明 ES6引入了两个新的变量声明类型:let和const。let和const之间的…

    node js 2023年6月8日
    00
  • npm install常见报错以及问题详解

    npm install常见报错以及问题详解 在使用npm安装依赖包的过程中,经常会出现各种报错和问题。本文将介绍个人在使用npm install时遇到的一些常见报错以及问题的分析和解决方案。 1. “npm ERR! code ECONNREFUSED”报错 这个报错通常是因为网络连接问题引起的,解决方法分为以下两种: 检查网络连接是否正常,可以尝试使用命令…

    node js 2023年6月8日
    00
  • 基于NodeJS的前后端分离的思考与实践(四)安全问题解决方案

    针对“基于NodeJS的前后端分离的思考与实践(四)安全问题解决方案”这个主题,我将结合具体的安全问题和解决方案,给出完整的攻略。 安全问题说明 开发过程中,如果不注意安全问题,容易造成数据泄露、篡改等后果,导致用户信息的泄露,进而影响企业的声誉。因此,我们需要在开发过程中考虑安全问题,避免出现安全漏洞。下面是常见的安全问题: 1. CSRF攻击 CSRF攻…

    node js 2023年6月8日
    00
  • Windows下安装NodeJS的详细步骤

    下面是Windows下安装NodeJS的详细步骤的完整攻略。 1.下载NodeJS安装包 打开NodeJS的官网(https://nodejs.org),在页面中选择“Download”菜单,点击对应的下载链接,选择msi安装文件(Windows Installer)进行下载。 2.安装NodeJS 下载完成后,双击msi安装文件,按照提示完成安装。在安装过…

    node js 2023年6月8日
    00
  • 微信js-sdk上传与下载图片接口用法示例

    好的。首先,需要明确一下微信js-sdk是指微信公众号提供的一套前端JS接口,可以让网页嵌入到微信客户端内部,从而实现与微信相关的功能接口调用。微信js-sdk中提供了图片上传和下载的接口,下面分别对两个功能进行详细讲解。 图片上传接口用法示例 步骤1:引入微信JS-SDK 在需要使用图片上传接口的页面中,需要先引入微信JS-SDK的相关代码,在<he…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部