首页 > 编程语言 >js实现 LRU 算法

js实现 LRU 算法

时间:2022-08-30 18:33:21浏览次数:51  
标签:node const get cache js 算法 LRU key 节点

方式一:map实现

class LRU {
    constructor(size) {
        this.size = size;
        this.cache = new Map();
    }
    get(key) {
        if (this.cache.has(key)) {
            const value = this.cache.get(key);
            this.cache.delete(key);
            this.cache.set(key, value);
            return value;
        }
        return -1;
    }
    put(key, val) {
        if (this.cache.has(key)) {
            this.cache.delete(key);
        }
        if (this.cache.size >= this.size) {
            // 如果当前缓存的map 的长度超出限制,则删除最前面的一个映射keys.next().value 可以拿到第一个映射的 key
            this.cache.delete(this.cache.keys().next().value);
        }
        this.cache.set(key, val);
    }
}
const lruCache = new LRU(2);
lruCache.put(1, 1);
lruCache.put(2, 2);
const res1 = lruCache.get(1);
lruCache.put(3, 3);
const res2 = lruCache.get(2);
lruCache.put(4, 4);
const res3 = lruCache.get(1);
const res4 = lruCache.get(3);
const res5 = lruCache.get(4);

console.log("LRU", res1, res2, res3, res4, res5); // 1 -1 -1 3 4

 

方式二:map+双向链表

class DoubleNode {
    constructor(element) {
        this.element = element;
        this.next = null;
        this.prev = null;
    }
}
class LRUCache2 {
    constructor(capacity) {
        this.capacity = capacity;
        this.size = 0;
        this.cache = new Map();
        this.head = new DoubleNode();
        this.tail = new DoubleNode();
        this.head.next = this.tail;
        this.tail.prev = this.head;
    }
    get(key) {
        if (!this.cache.has(key)) {
            return -1;
        }
        const node = this.cache.get(key);
        this.moveToHead(node);
        return node.element.value;
    }
    put(key, value) {
        if (!this.cache.has(key)) {
            const node = new DoubleNode({
                key,
                value,
            });
            this.cache.set(key, node);
            this.addToHead(node);
            this.size++;
            if (this.size > this.capacity) {
                const removed = this.removeTail();
                console.log("removed===", removed);
                this.cache.delete(removed.element.key);
                this.size--;
            }
        } else {
            const node = this.cache.get(key);
            node.element.value = value;
            this.moveToHead(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;
    }
    moveToHead(node) {
        this.removeNode(node);
        this.addToHead(node);
    }
    removeTail() {
        const node = this.tail.prev;
        this.removeNode(node);
        return node;
    }
}
const lruCache2 = new LRUCache2(2);
lruCache2.put(1, 1);
lruCache2.put(2, 2);
const res11 = lruCache2.get(1);
// console.log("res11", res11);
lruCache2.put(3, 3);
const res22 = lruCache2.get(2);
// console.log("res22", res22);
lruCache2.put(4, 4);
const res33 = lruCache2.get(1);
const res44 = lruCache2.get(3);
const res55 = lruCache2.get(4);

console.log(res11, res22, res33, res44, res55); // 1 -1 -1 3 4

 

标签:node,const,get,cache,js,算法,LRU,key,节点
From: https://www.cnblogs.com/beileixinqing/p/16640439.html

相关文章

  • geopandas 生成 geojson 文件
    创建GeoDataFrame 输出geojson文件importgeopandasss=np.stack((lon.flatten(),lat.flatten()),1)ss1=[Point(ss[0].tolist())foriinss]print(ss)......
  • vue.js3: 多张图片合并([email protected])
    一,安装用到的第三方库1,安装:liuhongdi@lhdpc:/data/vue/pdf/image2pdf$npmi-Svuedraggable@nextadded2packagesin11s2,查看已安装的版本:liuhongdi@lhd......
  • 页面滚动到指定位置——js中scrollIntoView()的用法
    element.scrollIntoView()参数默认为true1.什么是scrollIntoView?scrollIntoView是一个与页面(容器)滚动相关的API2.如何调用?element.scrollIntoView()参数默认为true参......
  • js -- setTimeout 实现倒计时不准确的问题
    setTimeout、setInterval属于定时触发器线程属于macrotask,它的回调会受到GUI渲染、事件触发、http请求、等的影响。所以这两个不适合做精准的定时。最好的方法是定时矫正......
  • JSON WEB TOKEN
    1、JSONWEBTOKEN1.1、什么是JWTJSONWebToken(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。简称JWT,在HTTP通信过程中,进......
  • LinkedHashMap源码及LRU实现原理
    基本认识LinkedHashMap位于java.util包,于JDK1.4引入,属于JavaCollectionsFramework的成员。查看其UML关系如下图所示:HashMap在很多场景下都满足K-V的存取,而且在非多线......
  • JS hashCode()
     functionhashcode(str){varhash=0,i,chr,len;if(str.length===0)returnhash;for(i=0,len=str.length;i<len;i++){chr=str.charCo......
  • JS 1到10随机数,2到10随机数
    Math.random()返回一个0~1之间的随机数;Math.floor()向下取整;Math.ceil()向上取整;Math.round()四舍五入;Math.fround()32位浮点数;1~10随机数letnum......
  • webpack5 中使用iframe 复用导航栏时js代码多次编译问题
    作为webpack萌新,在使用webpack时,偶然发现热更新了多次,最开始以为是配置问题,网上找了很久都没有答案,无意看见一个一个帖子说多引用了一遍js文件,于是我我回去找代码看是不是......
  • js之深拷贝与浅拷贝
    一、深拷贝与浅拷贝什么是深拷贝深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象(新旧对象不共享同一块内存),且修改新对象不会影响......