话说手撕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的基本功能了。
好好学习,天天向上~