LRU(Least Recently Used)算法是一种缓存淘汰算法,常用于缓存系统中,通过保留最近使用的数据而淘汰最久未使用的数据,以提高缓存的命中率。LRU算法的核心思想是基于时间局部性原理:最近访问的数据在未来会被再次访问。
LRU算法的基本原理如下:
LRU算法通常使用两个数据结构来实现:
LRU算法主要包含以下几个操作:
LRU算法的时间复杂度和空间复杂度主要取决于哈希表和双向链表的操作。
下面是一个简单的LRU算法的示例实现,使用Golang语言:
package main
import "fmt"
type LRUCache struct {
capacity int
cache map[int]*DoublyListNode
head *DoublyListNode
tail *DoublyListNode
}
type DoublyListNode struct {
key int
value int
prev *DoublyListNode
next *DoublyListNode
}
func Constructor(capacity int) LRUCache {
head := &DoublyListNode{}
tail := &DoublyListNode{}
head.next = tail
tail.prev = head
return LRUCache{
capacity: capacity,
cache: make(map[int]*DoublyListNode),
head: head,
tail: tail,
}
}
func (lru *LRUCache) moveToHead(node *DoublyListNode) {
lru.removeNode(node)
lru.addToHead(node)
}
func (lru *LRUCache) removeNode(node *DoublyListNode) {
node.prev.next = node.next
node.next.prev = node.prev
}
func (lru *LRUCache) addToHead(node *DoublyListNode) {
node.next = lru.head.next
node.prev = lru.head
lru.head.next.prev = node
lru.head.next = node
}
func (lru *LRUCache) removeTail() {
tail := lru.tail.prev
lru.removeNode(tail)
delete(lru.cache, tail.key)
}
func (lru *LRUCache) Get(key int) int {
if node, ok := lru.cache[key]; ok {
lru.moveToHead(node)
return node.value
}
return -1
}
func (lru *LRUCache) Put(key int, value int) {
if node, ok := lru.cache[key]; ok {
node.value = value
lru.moveToHead(node)
} else {
newNode := &DoublyListNode{key: key, value: value}
lru.cache[key] = newNode
lru.addToHead(newNode)
if len(lru.cache) > lru.capacity {
lru.removeTail()
}
}
}
func main() {
lruCache := Constructor(2)
lruCache.Put(1, 1)
lruCache.Put(2, 2)
fmt.Println(lruCache.Get(1)) // 输出 1
lruCache.Put(3, 3) // 该操作会使得密钥 2 作废
fmt.Println(lruCache.Get(2)) // 输出 -1(未找到)
lruCache.Put(4, 4) // 该操作会使得密钥 1 作废
fmt.Println(lruCache.Get(1)) // 输出 -1(未找到)
fmt.Println(lruCache.Get(3)) // 输出 3
fmt.Println(lruCache.Get(4)) // 输出 4
}
在这个示例中,LRUCache
结构体包含了哈希表和双向链表。DoublyListNode
结构体表示双向链表的节点。通过moveToHead
、removeNode
、addToHead
、removeTail
等方法实现了对双向链表的操作。Get
方法用于获取缓存中的值,Put
方法用于插入新值或更新已有值,并在需要时淘汰最久未使用的数据。
我正在参与2024腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!
声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意
腾讯云开发者社区:孟斯特
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。