go实现lru

LRU : 最近最少使用

操作系统的页面置换算法

基本都是用hashmap + 双端链表去实现(头插尾删)

hashmap为了快速找到是那个node, 双端链表有前后指针为了能快速删除该节点

package problem0146

// 双向链表结构
type LinkNode struct {
    key, value int
    pre, next  *LinkNode
}

// LRU结构
type LRUCache struct {
    m          map[int]*LinkNode
    cap        int
    head, tail *LinkNode
}

func Constructor(capacity int) LRUCache {
    head := &LinkNode{0, 0, nil, nil}
    tail := &LinkNode{0, 0, nil, nil}
    head.next = tail
    tail.pre = head
    return LRUCache{make(map[int]*LinkNode, capacity), capacity, head, tail}
}

func (this *LRUCache) moveToHead(node *LinkNode) {
    this.removeNode(node)
    this.addNode(node)
}

// 双向链表的好处在于,找到该节点后,能立马删除(因为前置也找到了pre) func (
this *LRUCache) removeNode(node *LinkNode) { node.pre.next = node.next node.next.pre = node.pre }
// 双向链表节点插入操作 func (
this *LRUCache) addNode(node *LinkNode) { head := this.head node.next = head.next node.next.pre = node node.pre = head head.next = node } // 如果有,将这个元素移动到首位置,返回值 // 如果没有,返回-1 func (this *LRUCache) Get(key int) int { if v, exist := this.m[key]; exist { this.moveToHead(v) return v.value } else { return -1 } } // 如果元素存在,将其移动到最前面,并更新值 // 如果元素不存在,插入到元素首,放入map(判断容量) func (this *LRUCache) Put(key int, value int) { tail := this.tail cache := this.m if v, exist := cache[key]; exist { v.value = value this.moveToHead(v) } else { v := &LinkNode{key, value, nil, nil} if len(this.m) == this.cap { delete(cache, tail.pre.key) this.removeNode(tail.pre) } this.addNode(v) cache[key] = v } }

 

posted @ 2020-11-28 11:14  天之草  阅读(203)  评论(0编辑  收藏  举报