LRU缓存


//链表结点
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)
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值