本文共 2071 字,大约阅读时间需要 6 分钟。
面云账户时候问了LRU,具体实现的方式是map+双链表。Set和Get的时间复杂度都是O(1)。完整写一遍复习一下, 仅作记录
/** * @Author: lzw5399 * @Date: 2021/5/20 22:28 * @Desc: 基于map和双链表实现的LRU算法 */package mainimport "sync"func main() { lru := NewLRUCache(3) lru.Set(1, 233) lru.Set(2, 666) lru.Set(3, 777) lru.Set(5, 888) lru.Get(2)}// LRUCachetype LRUCache struct { capacity int cache map[int]*LinkedNode head *LinkedNode tail *LinkedNode sync.RWMutex}type LinkedNode struct { key, value int prev, next *LinkedNode}func NewLRUCache(capacity int) *LRUCache { return &LRUCache{ capacity: capacity, cache: make(map[int]*LinkedNode, capacity), head: nil, tail: nil, RWMutex: sync.RWMutex{}, }}// - key是否已存在// - 已存在, 将该节点移动到链表头部// - 未存在, 判断cap是否已满// - 满// - 移除链表尾的节点// - 新的node放入链表头// - 新的node放入cache的map中// - 未满// - 新的node放入链表头// - 新的node放入cache的map中func (l *LRUCache) Set(key int, value int) { l.RLock() node, exist := l.cache[key] l.RUnlock() if exist { l.moveToHead(node) return } node = &LinkedNode{ key: key, value: value, } l.Lock() defer l.Unlock() if l.capacity == len(l.cache) { removedNode := l.removeTail() delete(l.cache, removedNode.key) } l.addToHead(node) l.cache[key] = node}// - 从map中获取是否存在// - 不存在// - 返回-1// - 存在// - 移到链表头部// - 并返回具体的值func (l *LRUCache) Get(key int) int { l.RLock() node, exist := l.cache[key] l.RUnlock() if !exist { return -1 } l.moveToHead(node) return node.value}func (l *LRUCache) moveToHead(node *LinkedNode) { l.removeNode(node) l.addToHead(node)}func (l *LRUCache) removeTail() *LinkedNode { return l.removeNode(l.tail)}func (l *LRUCache) removeNode(node *LinkedNode) *LinkedNode { // 头节点 if node.prev == nil { l.head = node.next node.next.prev = nil return node } // 尾节点 if node.next == nil { l.tail = node.prev node.prev.next = nil return node } // 中间节点 node.prev.next = node.next node.next.prev = node.prev return node}func (l *LRUCache) addToHead(node *LinkedNode) { if l.head == nil { l.tail = node } else { l.head.prev = node } node.prev = nil node.next = l.head l.head = node}
转载地址:http://qnkwk.baihongyu.com/