go语言实现LRU缓存

go语言实现LRU Cache

题目描述

设计和构建一个“最近最少使用”缓存,该缓存会删除最近最少使用的项目。缓存应该从键映射到值(允许你插入和检索特定键对应的值),并在初始化时指定最大容量。当缓存被填满时,它应该删除最近最少使用的项目。

它应该支持以下操作: 获取数据 get 和 写入数据 put 。

获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。

详细代码

type LRUCache struct {
	capacity   int
	m          map[int]*Node
	head, tail *Node
}

type Node struct {
	Key       int
	Value     int
	Pre, Next *Node
}

func Constructor(capacity int) LRUCache {
	head, tail := &Node{}, &Node{}
	head.Next = tail
	tail.Pre = head
	return LRUCache{
		capacity: capacity,
		m:        map[int]*Node{},
		head:     head,
		tail:     tail,
	}
}

func (this *LRUCache) Get(key int) int {
	// 存在,放到头
	if v, ok := this.m[key]; ok {
		this.moveToHead(v)
		return v.Value
	}
	// 不存在,返回-1
	return -1
}

func (this *LRUCache) Put(key int, value int) {
	// 已经存在了
	if v, ok := this.m[key];ok{
		v.Value = value
		this.moveToHead(v)
		return 
	}
	if this.capacity==len(this.m){
		rmKey := this.removeTail()
		delete(this.m ,rmKey)
	}
	newNode := &Node{Key: key, Value: value}
	this.m[key] = newNode
	this.addToHead(newNode)
}

func (this *LRUCache) moveToHead(node *Node) {
	this.deleteNode(node)
	this.addToHead(node)
}

func (this *LRUCache) deleteNode(node *Node) {
	node.Pre.Next = node.Next
	node.Next.Pre = node.Pre
}

func (this *LRUCache) addToHead(node *Node) {
	// 先让node位于现存第一位元素之前
	this.head.Next.Pre = node
	// 通过node的next指针让原始第一位元素放到第二位
	node.Next = this.head.Next
	// 捆绑node和head的关系
	this.head.Next = node
	node.Pre = this.head
}

func (this *LRUCache)removeTail()int{
	node := this.tail.Pre
    this.deleteNode(node)
    return node.Key
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * obj := Constructor(capacity);
 * param_1 := obj.Get(key);
 * obj.Put(key,value);
 */

好的,我可以回答这个问题。以下是 Go 语言实现 LRU 缓存的代码示例: ``` package main import ( "container/list" "fmt" ) type LRUCache struct { capacity int cache map[int]*list.Element list *list.List } type entry struct { key int value int } func Constructor(capacity int) LRUCache { return LRUCache{ capacity: capacity, cache: make(map[int]*list.Element), list: list.New(), } } func (this *LRUCache) Get(key int) int { if elem, ok := this.cache[key]; ok { this.list.MoveToFront(elem) return elem.Value.(*entry).value } return -1 } func (this *LRUCache) Put(key int, value int) { if elem, ok := this.cache[key]; ok { this.list.MoveToFront(elem) elem.Value.(*entry).value = value } else { if len(this.cache) == this.capacity { last := this.list.Back() delete(this.cache, last.Value.(*entry).key) this.list.Remove(last) } elem := this.list.PushFront(&entry{key, value}) this.cache[key] = elem } } func main() { cache := Constructor(2) cache.Put(1, 1) cache.Put(2, 2) fmt.Println(cache.Get(1)) // 1 cache.Put(3, 3) fmt.Println(cache.Get(2)) // -1 cache.Put(4, 4) fmt.Println(cache.Get(1)) // -1 fmt.Println(cache.Get(3)) // 3 fmt.Println(cache.Get(4)) // 4 } ``` 这个 LRU 缓存使用了双向链表和哈希表来实现。其中,双向链表用来维护缓存中的元素顺序,哈希表用来快速查找元素。在 `Get` 方法中,如果缓存中存在指定的 key,则将对应的元素移动到链表头部,并返回其值;否则返回 -1。在 `Put` 方法中,如果缓存中已经存在指定的 key,则更新对应的值,并将元素移动到链表头部;否则,如果缓存已满,则删除链表尾部的元素,并从哈希表中删除对应的 key;然后将新元素插入到链表头部,并在哈希表中添加对应的 key。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值