基于Map实现一个简单的LRU

721 阅读1分钟

DSC_1051.JPG

话说手撕LRU算法最近在面试中比较“网红”,于是记录一下。

LUR(Least recently used)即最近最少使用,是缓存常用的一个算法,简单来说就是缓存最近使用的数据,沉水(也可以理解删掉)最近没有使用的数据,因为LRU遵循的规则是 “最近被访问过的数据,在将来被访问的几率最大”。

Map数据结构是有序的哈希数据结构,非常适合用来实现LRU功能,一是有序,二是,因为是哈希表结构,所以实现增删数据的时间复杂度是O(1),非常快

代码实现其实不难,理清楚LRU的原理以及Map这个ES6新的API即可,以下是代码简单实现版:

class myLRU{
    constructor(length){
        if(length < 1) throw new Error('invalid length')
        this.data =  new Map()
        this.length = length

    }
    set(key,value){
        const data = this.data
        if(data.has(key)){
            data.delete(key)
        }
        data.set(key, value)
        if(data.size > this.length){ //如果超出了容量,则删除Map最老的元素
            const delKey = data.keys().next().value
            data.delete(delKey)
        }
    }
    get(key){
        const data = this.data
        if(!data.has(key)) return null
        const val = data.get(key)
        data.delete(key)

        data.set(key, val)
        return val
    }
}

测试:

let lru = new myLRU(3)

lru.set('a','a') lru.set('b','b')
lru.set('c','c')

这时候我们看下lru的data数据结果是:

{'a' => 'a''b' => 'b''c' => 'c'}

现在我们再增加第四个:

lru.set('d','d')

这时候再看lru的data数据结果已经变为:

{'b' => 'b', 'c' => 'c', 'd' => 'd'}

也就是说,在超出限制长度后,lru会删除掉最先存入的数据

而如果我们在增加d之前先访问a,即lru.get('a'),那么在增加d后结果就会变为

{'c' => 'c''a' => 'a''d' => 'd'}

这时a就会在data中会被重新放到较“新”的位置

这样就简单实现了lru的基本功能了。

好好学习,天天向上~