JS实现一个LRU缓存


class LRUCache:
    def __init__(self, capacity):
        self.capacity = capacity
        self.cache = {}

    def get(self, key):
        if key in self.cache:
            value = self.cache.pop(key)
            self.cache[key] = value
            return value
        return -1

    def put(self, key, value):
        if key in self.cache:
            del self.cache[key]
        elif len(self.cache) >= self.capacity:
            delete_key = next(iter(self.cache))  # 拿到最久未使用的 key
            del self.cache[delete_key]
        self.cache[key] = value

    def to_string(self):
        print(self.capacity)
        print(self.cache)


cache = LRUCache(3)
cache.put(1, 1)   # 1
cache.to_string()
cache.put(2, 2)   # 1-2
cache.to_string()
cache.put(3, 3)   # 1-2-3
cache.to_string()
cache.put(4, 4)   # 2-3-4
cache.to_string()
cache.put(3, 3)   # 2-4-3
cache.to_string()
cache.get(2)      # 4-3-2
cache.to_string()

 

class LRUCache {
  capacity = null
  cache = null

  constructor(max) {
    this.capacity = max
    this.cache = new Map()
  }
  get(key) {
    if(this.cache.has(key)) {
      let value = this.cache.get(key)
      this.cache.delete(key)
      this.cache.set(key, value)
      return value
    }
    return -1
  }
  put(key, value) {
    if(this.cache.has(key)) {
      this.cache.delete(key)
    } else if (this.cache.size >= this.capacity) {
      let deleteKey = this.cache.keys().next().value // keys返回的是一个map的迭代器,.next拿到第一项
      this.cache.delete(deleteKey)
    }
    this.cache.set(key, value)
  }
  toString() {
    console.log(this.capacity)
    console.log(this.cache)
  }
}

let cache = new LRUCache(3)
cache.put(1,1) // 1
cache.toString()
cache.put(2,2) // 1-2
cache.toString()
cache.put(3,3) // 1-2-3
cache.toString()
cache.put(4,4) // 2-3-4
cache.toString()
cache.put(3,3) // 2-4-3
cache.toString()
cache.get(2) // 4-3-2
cache.toString()

 

class LRUCache {
  max = null
  data = null // 元素节点集合
  dataLength = 0 // 链表的长度
  listHead = null // 头节点
  listTail = null // 尾节点

  constructor(max) {
    if (max < 1) throw new Error('invalid Max')
    this.max = max
    this.data = {}
  }
  moveToTail(curNode) { // 节点移动后末位
    const tail = this.listTail
    if (tail === curNode) return // 本身就是末尾节点
    // 1、让prevNode 和 nextNode 断绝和curNode的关系
    const prevNode = curNode.prev
    const nextNode = curNode.next
    if (prevNode) {
      if (nextNode) {
        prevNode.next = nextNode
      } else {
        delete prevNode.next
      }
    }
    if (nextNode) {
      if (prevNode) {
        nextNode.prev = prevNode
      } else {
        delete nextNode.prev
      }
      if(this.listHead === curNode) this.listHead = nextNode
    }
    // 2、让curNode 断绝于prevNode 、nextNode 的关系
    delete curNode.prev
    delete curNode.next

    // 3、在末位重新建立curNode的新关系
    if (tail) {
      tail.next = curNode
      curNode.prev = tail
    }
    this.listTail = curNode
  }
  get(key) {
    const data = this.data
    const curNode = data[key]
    if (curNode == null) return null
    if (curNode === this.listTail) return curNode.value // 最后一个节点直接返回
    // 访问中间节点要返回到末位
    this.moveToTail(curNode)
    return curNode.value
  }

  tryClean() {
    while (this.dataLength > this.max) {
      const head = this.listHead
      if (head == null) throw new Error('head is null')
      const headNext = head.next
      if (headNext == null) throw new Error('headNext is Null')
      // 1、断绝head和next的关系
      delete head.next
      delete headNext.prev
      // 2、重新复制listHead
      this.listHead = headNext
      // 3、清理data数据集中的数据, 修改链表长度
      delete this.data[head.key]
      this.dataLength = this.dataLength - 1
    }
  }
  set(key, value) {
    const data = this.data
    const curNode = data[key]
    if (curNode == null) {
      // 新增数据
      const newNode = { key, value }
      this.moveToTail(newNode)

      data[key] = newNode
      this.dataLength++
      if(this.dataLength === 1) this.listHead = newNode // 第一个节点
    } else {
      // 修改现有数据
      curNode.value = value
      this.moveToTail(curNode)
    }
    // 长度超出后要清理
    this.tryClean()
  }

}
let cache = new LRUCache(3)
cache.set('1', 1) // 1
// cache.toString()
cache.set('2',2) // 1-2
// cache.toString()
cache.set('3', 3) // 1-2-3
console.log(cache.get(2))
// cache.toString()
cache.set('4',4) // 2-3-4
// cache.toString()
cache.set('3',3) // 2-4-3
// cache.toString()
console.log(cache.get(2)) // 4-3-2
// cache.toString()

 

posted @ 2026-07-03 00:49  .李宁宁  阅读(4)  评论(0)    收藏  举报