• 基于Golang实现LRU


    LRU Least Recently Used的缩写

    即最近最少使用,在页面置换和缓存过期key的淘汰中有用到

    维持了一个map存储每个节点,另外维持了一个双端列表,来实现删除和插入操作

    基本结构:

    type LinkNode struct {
        key, val  int
        pre, next *LinkNode
    }
    
    type LRUCache struct {
        m          map[int]*LinkNode // 指向哈希表的指针
        cap        int               // 长度
        head, tail *LinkNode         // 两个哨兵
    }
    
    func Constructor(capacity int) LRUCache {
        //采用虚拟头尾节点,这两个节点始终处于首位,但不计入map中
        head := &LinkNode{-1, 0, nil, nil}
        tail := &LinkNode{-1, 0, nil, nil}
        head.next = tail
        tail.pre = head
        return LRUCache{make(map[int]*LinkNode), capacity, head, tail}
    }

    关键点:首尾节点是虚拟节点,无论怎么插入删除它们都存在,在cap中不会计算这两个节点,删除也是删除tail节点的前一个节点

    Get方法:

    func (this *LRUCache) Get(key int) int {
        m := this.m
        if node, ok := m[key]; ok {
            this.moveToHead(node)
            return node.val
        }
        return -1
    }
    
    func (this *LRUCache) moveToHead(node *LinkNode) {
        if node.pre != nil && node.next != nil{
            node.pre.next = node.next
            node.next.pre = node.pre
        }
        node.pre = this.head
        node.next = this.head.next
        this.head.next.pre = node
        this.head.next = node
    }

    Put方法:

    func (this *LRUCache) Put(key int, value int) {
        m := this.m
        cap := this.cap
        tail := this.tail
        if node, ok := m[key]; ok {
            //插入新的值
            node.val = value
            this.moveToHead(node)
        } else {
            newNode := &LinkNode{key, value, nil, nil}
            if len(m) == cap {
                rmTail := tail.pre
                rmTail.pre.next = tail
                tail.pre =rmTail.pre
                rmTail.next = nil
                delete(m, rmTail.key)
            }
            this.moveToHead(newNode)
            m[key] = newNode
        }
    }

    关键点:由于双向链表的缘故,在插入或者删除时会一定注意检查前后节点的双向指针的指向问题

    源码地址

    leetcode地址

  • 相关阅读:
    ie下如果已经有缓存,load方法的效果就无法执行.的解决方法
    css公共样式
    pageX、pageY全兼容
    js滚动加载插件
    getComputedStyle()与currentStyle
    excel15个技巧
    XMLHttpRequest函数
    继承模式
    cookie函数
    jQuery添加删除元素
  • 原文地址:https://www.cnblogs.com/peterleee/p/14886339.html
Copyright © 2020-2023  润新知