//链表结点
type Node struct {
key, val int
prev, next *Node
}
func initNode(key, val int) *Node {
return &Node{key: key, val: val}
}
type DoubleListNode struct {
head, tail *Node //虚头结点,尾节点
size int //链表元素数
}
func initDoubleListNode() *DoubleListNode {
dll := &DoubleListNode{
head: initNode(0, 0),
tail: initNode(0, 0),
size: 0,
}
dll.head.next = dll.tail
dll.tail.prev = dll.head
return dll
}
//在尾部添加结点
func (dll *DoubleListNode) AddNode(x *Node) {
x.next = dll.tail
x.prev = dll.tail.prev
dll.tail.prev.next = x
dll.tail.prev = x
dll.size++
}
//删除结点
func (dll *DoubleListNode) DelNode(x *Node) {
x.prev.next = x.next
x.next.prev = x.prev
x.prev, x.next = nil, nil
dll.size--
}
//删除第一个结点并返回
func (dll *DoubleListNode) DelFirst() *Node {
if dll.head.next == dll.tail {
return nil
}
first := dll.head.next
dll.DelNode(first)
return first
}
type LRUCache struct {
capacity int // 容量
Map map[int]*Node // key -> Node(key, val)
cache *DoubleListNode // Node(k1, v1) <-> Node(k2, v2)...
}
//初始化
func Constructor(capacity int) LRUCache {
lrucache := &LRUCache{
capacity: capacity,
Map: map[int]*Node{},
cache: initDoubleListNode(),
}
return *lrucache
}
//封装一些api
// 将某个 key 调整为最近使用的元素
func (lru *LRUCache) makeRecently(key int) {
//找到结点
node := lru.Map[key]
//删除结点
lru.cache.DelNode(node)
//调整到链表末尾(对头)
lru.cache.AddNode(node)
}
//添加新的元素
func (lru *LRUCache) AddNewNode(key, val int) {
//组装结点
node := initNode(key, val)
//添加到队头
lru.cache.AddNode(node)
//添加到map
lru.Map[key] = node
}
// 删除某一个 key 及对应元素
func (this *LRUCache) deleteKey(key int) {
node := this.Map[key]
// 删除节点
this.cache.DelNode(node)
// 删除映射
delete(this.Map, key)
}
// 删除最近最少使用的元素
func (this *LRUCache) deleteLRU() {
// 链表的第一个就是最近最少使用的元素
Node := this.cache.DelFirst()
// 删除映射
delete(this.Map, Node.key)
}
func (this *LRUCache) Get(key int) int {
node, ok := this.Map[key]
if !ok {
return -1
}
this.makeRecently(node.key)
return node.val
}
func (this *LRUCache) Put(key int, value int) {
_, exist := this.Map[key]
// 如果存在
if exist {
// 删除旧元素
this.deleteKey(key)
// 添加新数据为最近使用
this.AddNewNode(key, value)
} else {
// 不存在
// 容量满
if this.cache.size == this.capacity {
// 删除最近最少使用的元素
this.deleteLRU()
}
// 添加元素为最近使用
this.AddNewNode(key, value)
}
}
LRU缓存
最新推荐文章于 2024-08-23 06:00:53 发布