什么是LRU
LRU是Least Recently Used的缩写,即最近最少使用。实际生活中应用非常广,例如所有手机的后台应用。
在打开后台应用时,
最前显示的一定是最近使用的,包括最新打开的,或者打开之前的;超过后台限制时则将最老的程序关掉。
即设置一个队列,有两个操作,新建和使用。
新建时,将新输入的元素放入队列头部,
使用时,将使用的队列里的元素,从队列中取出,并放到队列头部
当队列元素达到上限时,删除队尾元素。
package main
func main() {
}
type LRUCache struct {
size int //双向链表的长度
capacity int //双向链表容量
chche map[int]*DLinkedNode //查询key对应的节点
head *DLinkedNode //伪头节点
tail *DLinkedNode //伪尾节点
}
type DLinkedNode struct {
//节点保存的信息
key int //key
val int //value
prev *DLinkedNode //节点的上一个节点
next *DLinkedNode //节点的下一个节点
}
func initDLinkedNode(key, value int) *DLinkedNode {
//初始化一个新节点
return &DLinkedNode{
key: key,
val: value,
}
}
func Constructor(capacity int) LRUCache {
l := LRUCache{
size: 0,
capacity: capacity,
chche: map[int]*DLinkedNode{},
head: initDLinkedNode(0, 0),
tail: initDLinkedNode(0, 0),
}
l.head.next = l.tail
l.tail.prev = l.head
return l
}
func (LRU *LRUCache) Get(key int) int {
if k, ok := LRU.chche[key]; ok {
LRU.moveToHead(k)
return k.val
}
return -1
}
func (LRU *LRUCache) Put(key int, value int) {
if k, ok := LRU.chche[key]; ok {
LRU.moveToHead(k)
k.val = value
} else {
newNode := initDLinkedNode(key, value)
LRU.chche[key] = newNode
LRU.size++
LRU.addToHead(newNode)
}
if LRU.size > LRU.capacity {
LRU.removeTail()
LRU.size--
}
}
func (LRU *LRUCache) addToHead(node *DLinkedNode) {
node.next = LRU.head.next
node.prev = LRU.head
LRU.head.next.prev = node
LRU.head.next = node
}
func (LRU *LRUCache) removeNode(node *DLinkedNode) {
node.next.prev = node.prev
node.prev.next = node.next
}
func (LRU *LRUCache) moveToHead(node *DLinkedNode) {
LRU.removeNode(node)
LRU.addToHead(node)
}
func (LRU *LRUCache) removeTail() {
delete(LRU.chche, LRU.tail.prev.key)
LRU.tail.prev = LRU.tail.prev.prev
LRU.tail.prev.next = LRU.tail
}