package main
import "fmt"
type Node struct {
Key int
Value int
freq int
pre *Node
next *Node
}
type LFUCache struct {
limit int
HashMap map[int]*Node
head *Node
end *Node
}
func LFUConstructor(capacity int) LFUCache{
lfuCache := LFUCache{}
lfuCache.limit = capacity
lfuCache.HashMap = make(map[int]*Node, capacity)
return lfuCache
}
func(l *LFUCache) Get(key int) int {
if value ,ok := l.HashMap[key] ;ok {
value.freq ++
l.refreshNode(value)
return value.Value
} else {
return -1
}
}
func (l *LFUCache)Put(key ,value int) {
if v ,ok := l.HashMap[key] ;!ok {
if len(l.HashMap) >= l.limit{
oldKey := l.removeNode(l.head)
delete(l.HashMap, oldKey)
}
node := Node{Key:key, Value:value,freq: 1}
l.addNode(&node)
l.HashMap[key] = &node
} else {
v.Value = value
v.freq ++
l.refreshNode(v)
}
}
func (l *LFUCache) refreshNode(node *Node){
if node == l.end {
return
}
l.removeNode(node)
l.addNode(node)
}
func (l *LFUCache) removeNode(node *Node) int {
if node == l.end {
l.end = l.end.pre
l.end.next = nil
}else if node == l.head {
l.head = l.head.next
l.head.pre = nil
}else {
node.pre.next = node.next
node.next.pre = node.pre
}
return node.Key
}
func (l *LFUCache) addNode(node *Node) {
if l.head == nil && l.end == nil{
l.head = node
l.end = node
return
}
head := l.head
for head != nil && node.freq >= head.freq{
head = head.next
}
if head == nil{
l.end.next = node
node.pre = l.end
l.end = node
}
if head != nil{
head.pre.next = node
node.pre = head.pre
head.pre = node
node.next = head
}
l.head.pre = nil
l.end.next = nil
return
}
func main ()(){
lfuCache := LFUConstructor(3)
lfuCache.Put(1,3)
lfuCache.Put(2,4)
lfuCache.Put(3,5)
fmt.Println(lfuCache) // 此时的链表顺序应该是 1 : 3 2 : 4 3 : 5 l.head 为1 : 3 l.end 为3 : 5
lfuCache.Get(1)
fmt.Println(lfuCache) // 此时的链表顺序应该是 2 : 4 3 : 5 1 : 3 l.head 为2 : 4 l.end 为1 : 3
lfuCache.Put(4,6)
fmt.Println(lfuCache) // 此时的链表顺序应该是 3 : 5 4 : 6 1 : 3 l.head 为3 : 5 l.end 为1 : 3
}
LFU (Least Frequently Used ,最不常用)基于LRU,对双向链表根据使用次数进行了排序即可